Decompiled source of UnifiedTargetPortal v1.0.4

plugins/UnifiedTargetPortal/UnifiedTargetPortal.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Splatform;
using TMPro;
using UnifiedTargetPortal.Features;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace UnifiedTargetPortal
{
	[BepInPlugin("com.xman0922.unifiedtargetportal", "Unified Target Portal", "1.0.4")]
	[BepInIncompatibility("org.bepinex.plugins.targetportal")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.xman0922.unifiedtargetportal";

		public const string PluginName = "Unified Target Portal";

		public const string PluginVersion = "1.0.4";

		internal static ManualLogSource Log;

		private Harmony? harmony;

		private PortalFeature? feature;

		private void Awake()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			harmony = new Harmony("com.xman0922.unifiedtargetportal");
			feature = new PortalFeature(((BaseUnityPlugin)this).Config);
			feature.Initialize(harmony);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Unified Target Portal 1.0.4 loaded.");
		}

		private void Update()
		{
			feature?.Update();
		}

		private void OnDestroy()
		{
			feature?.Shutdown();
			Harmony? obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}
	}
}
namespace UnifiedTargetPortal.Features
{
	internal interface IFeatureModule
	{
		void Initialize(Harmony harmony);

		void DrawGui();

		void Shutdown();
	}
	internal interface IUpdatableFeature
	{
		void Update();
	}
	internal static class Loc
	{
		internal static bool IsKorean
		{
			get
			{
				Localization instance = Localization.instance;
				if (instance != null)
				{
					return string.Equals(instance.GetSelectedLanguage(), "Korean", StringComparison.OrdinalIgnoreCase);
				}
				return false;
			}
		}

		internal static string Text(string korean, string english)
		{
			if (!IsKorean)
			{
				return english;
			}
			return korean;
		}
	}
	internal sealed class PortalFeature : IFeatureModule, IUpdatableFeature
	{
		private enum PortalMode
		{
			Public,
			Private
		}

		private enum ItemRestrictionMode
		{
			Never,
			Default,
			Always
		}

		private sealed class PortalEntry
		{
			internal ZDOID Id;

			internal string Tag = string.Empty;

			internal Vector3 Position;

			internal Quaternion Rotation;

			internal PortalMode Mode;

			internal string OwnerId = string.Empty;

			internal string OwnerName = string.Empty;
		}

		private sealed class FavoritePortalClick : MonoBehaviour, IPointerClickHandler, IEventSystemHandler
		{
			internal PortalFeature Owner;

			internal PortalEntry Portal;

			public void OnPointerClick(PointerEventData eventData)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Invalid comparison between Unknown and I4
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				if ((int)eventData.button == 1)
				{
					Owner.ToggleFavorite(Portal);
				}
				else if ((int)eventData.button == 0)
				{
					Owner.Travel(Portal);
				}
			}
		}

		private const string ListRpc = "VU_PortalList";

		private const string RequestRpc = "VU_PortalRequest";

		private const string ChangeModeRpc = "VU_PortalMode";

		private const string ModeKey = "TargetPortal PortalMode";

		private const string OwnerIdKey = "TargetPortal PortalOwnerId";

		private const string OwnerNameKey = "TargetPortal PortalOwnerName";

		private const string FavoritesKey = "TargetPortal Favorites";

		private static PortalFeature? current;

		private static readonly MethodInfo? ScreenToWorldMethod = AccessTools.Method(typeof(Minimap), "ScreenToWorldPoint", (Type[])null, (Type[])null);

		private static readonly MethodInfo? InteractRadiusGetter = AccessTools.PropertyGetter(typeof(Minimap), "PinInteractRadius");

		private static int portalPinType = -1;

		private static Sprite? portalIcon;

		private readonly ConfigEntry<bool> enabled;

		private readonly ConfigEntry<float> broadcastInterval;

		private readonly ConfigEntry<bool> showUntagged;

		private readonly ConfigEntry<bool> allowPrivatePortals;

		private readonly ConfigEntry<KeyboardShortcut> modeToggleShortcut;

		private readonly ConfigEntry<int> portalNameLength;

		private readonly ConfigEntry<int> maximumNumberOfPortals;

		private readonly ConfigEntry<ItemRestrictionMode> itemRestrictionMode;

		private readonly ConfigEntry<PortalMode> defaultPortalMode;

		private readonly List<PortalEntry> portals = new List<PortalEntry>();

		private readonly List<PinData> pickerPins = new List<PinData>();

		private readonly Dictionary<PinData, PortalEntry> pinToPortal = new Dictionary<PinData, PortalEntry>();

		private TeleportWorld? pickerSource;

		private bool pickerFromTrigger;

		private const float LeavePortalDistance = 4f;

		private ConfigEntry<bool> openMapOnEnter;

		private ConfigEntry<bool> portalAnimation;

		private bool[]? savedIconTypes;

		private static readonly FieldInfo? VisibleIconTypesField = AccessTools.Field(typeof(Minimap), "m_visibleIconTypes");

		private static readonly FieldInfo? PinUpdateRequiredField = AccessTools.Field(typeof(Minimap), "m_pinUpdateRequired");

		private static readonly FieldInfo? DragViewField = AccessTools.Field(typeof(Minimap), "m_dragView");

		private static readonly FieldInfo? PlacementGhostField = AccessTools.Field(typeof(Player), "m_placementGhost");

		private GameObject? favoriteList;

		private ZRoutedRpc? registeredWith;

		private bool listReceived;

		private float nextListRequest;

		private float sessionStarted;

		private float nextBroadcast;

		private int lastBroadcastHash;

		private static readonly FieldInfo? TriggerPortalField = AccessTools.Field(typeof(TeleportWorldTrigger), "m_teleportWorld");

		private bool rpcRegistered
		{
			get
			{
				if (registeredWith != null)
				{
					return registeredWith == ZRoutedRpc.instance;
				}
				return false;
			}
		}

		private static bool Active => current?.enabled.Value ?? false;

		internal PortalFeature(ConfigFile config)
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Expected O, but got Unknown
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Expected O, but got Unknown
			enabled = config.Bind<bool>("Portals", "Enabled", true, "Choose a destination on the map when using a portal. Hold Use to rename instead.");
			broadcastInterval = config.Bind<float>("Portals", "BroadcastInterval", 5f, "Seconds between server checks for portal changes.");
			showUntagged = config.Bind<bool>("Portals", "ShowUntagged", true, "List portals that have no tag.");
			allowPrivatePortals = config.Bind<bool>("Portals", "AllowPrivatePortals", true, "Allow portal owners to switch between Public and Private with Shift + Use.");
			modeToggleShortcut = config.Bind<KeyboardShortcut>("Portals", "ModeToggleShortcut", new KeyboardShortcut((KeyCode)304, Array.Empty<KeyCode>()), "Modifier held while using a portal to switch its visibility mode.");
			openMapOnEnter = config.Bind<bool>("Portals", "OpenMapOnEnter", true, "Walk into a portal to open the destination map, like TargetPortal. Off: press Use to open it instead.");
			portalAnimation = config.Bind<bool>("Portals", "PortalAnimation", true, "Show the active portal swirl on every portal, since any portal can now reach any other.");
			portalNameLength = config.Bind<int>("Portals", "PortalNameLength", 10, new ConfigDescription("Maximum portal-name length.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 100), Array.Empty<object>()));
			maximumNumberOfPortals = config.Bind<int>("Portals", "MaximumNumberOfPortals", 0, new ConfigDescription("Maximum portals allowed in the world. 0 means unlimited.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10000), Array.Empty<object>()));
			itemRestrictionMode = config.Bind<ItemRestrictionMode>("Portals", "IgnoreItemTeleportRestrictions", ItemRestrictionMode.Default, "Never: enforce restrictions for every portal. Default: use the portal's vanilla rule. Always: ignore restrictions.");
			defaultPortalMode = config.Bind<PortalMode>("Portals", "DefaultPortalMode", PortalMode.Private, "Visibility mode assigned to newly built portals.");
		}

		private static void Patch(Harmony harmony, MethodBase? original, HarmonyMethod? prefix = null, HarmonyMethod? postfix = null)
		{
			if (original == null)
			{
				Plugin.Log.LogWarning((object)"TargetPortal: a game method was not found; that part of the feature stays inactive.");
				return;
			}
			try
			{
				harmony.Patch(original, prefix, postfix, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("TargetPortal: could not patch " + original.DeclaringType?.Name + "." + original.Name + ": " + ex.Message));
			}
		}

		public void Initialize(Harmony harmony)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Expected O, but got Unknown
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Expected O, but got Unknown
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Expected O, but got Unknown
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Expected O, but got Unknown
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Expected O, but got Unknown
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Expected O, but got Unknown
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Expected O, but got Unknown
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Expected O, but got Unknown
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Expected O, but got Unknown
			current = this;
			Patch(harmony, AccessTools.Method(typeof(TeleportWorld), "Interact", (Type[])null, (Type[])null), new HarmonyMethod(typeof(PortalFeature), "InteractPrefix", (Type[])null));
			Patch(harmony, AccessTools.Method(typeof(TeleportWorld), "GetHoverText", (Type[])null, (Type[])null), null, new HarmonyMethod(typeof(PortalFeature), "HoverTextPostfix", (Type[])null));
			Patch(harmony, AccessTools.Method(typeof(ZDOMan), "AddPeer", (Type[])null, (Type[])null), null, new HarmonyMethod(typeof(PortalFeature), "ZdoAddPeerPostfix", (Type[])null));
			Patch(harmony, AccessTools.Method(typeof(Piece), "SetCreator", (Type[])null, (Type[])null), null, new HarmonyMethod(typeof(PortalFeature), "PieceSetCreatorPostfix", (Type[])null));
			Patch(harmony, AccessTools.Method(typeof(Minimap), "OnMapLeftClick", (Type[])null, (Type[])null), new HarmonyMethod(typeof(PortalFeature), "MapLeftClickPrefix", (Type[])null));
			Patch(harmony, AccessTools.Method(typeof(Minimap), "RemovePinUnderPointer", (Type[])null, (Type[])null), new HarmonyMethod(typeof(PortalFeature), "RemovePinUnderPointerPrefix", (Type[])null));
			Patch(harmony, AccessTools.Method(typeof(Minimap), "SetMapMode", (Type[])null, (Type[])null), null, new HarmonyMethod(typeof(PortalFeature), "SetMapModePostfix", (Type[])null));
			Patch(harmony, AccessTools.Method(typeof(Minimap), "Start", (Type[])null, (Type[])null), null, new HarmonyMethod(typeof(PortalFeature), "MinimapStartPostfix", (Type[])null));
			Patch(harmony, AccessTools.Method(typeof(Game), "Start", (Type[])null, (Type[])null), null, new HarmonyMethod(typeof(PortalFeature), "GameStartPostfix", (Type[])null));
			Patch(harmony, AccessTools.Method(typeof(TeleportWorldTrigger), "OnTriggerEnter", (Type[])null, (Type[])null), new HarmonyMethod(typeof(PortalFeature), "TriggerEnterPrefix", (Type[])null));
			Patch(harmony, AccessTools.Method(typeof(Player), "PlacePiece", (Type[])null, (Type[])null), new HarmonyMethod(typeof(PortalFeature), "PlacePiecePrefix", (Type[])null));
			Patch(harmony, AccessTools.Method(typeof(TeleportWorld), "HaveTarget", (Type[])null, (Type[])null), new HarmonyMethod(typeof(PortalFeature), "HaveTargetPrefix", (Type[])null));
			Patch(harmony, AccessTools.Method(typeof(TeleportWorld), "TargetFound", (Type[])null, (Type[])null), new HarmonyMethod(typeof(PortalFeature), "TargetFoundPrefix", (Type[])null));
			string[] array = new string[2] { "OnMapDblClick", "OnMapMiddleClick" };
			foreach (string text in array)
			{
				MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(Minimap), text, (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(PortalFeature), "BlockWhilePickingPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
			Plugin.Log.LogInfo((object)("PortalFeature: " + (enabled.Value ? ("enabled, open on " + (openMapOnEnter.Value ? "enter" : "use")) : "disabled") + "."));
		}

		private static void GameStartPostfix()
		{
			current?.RegisterRpcs();
		}

		private static void MinimapStartPostfix(Minimap __instance)
		{
			//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)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			if (!(VisibleIconTypesField?.GetValue(__instance) is bool[] array))
			{
				Plugin.Log.LogError((object)"TargetPortal: could not register the dedicated portal map icon.");
				return;
			}
			portalPinType = array.Length;
			bool[] array2 = new bool[portalPinType + 1];
			Array.Copy(array, array2, array.Length);
			array2[portalPinType] = true;
			VisibleIconTypesField.SetValue(__instance, array2);
			if (portalIcon == null)
			{
				portalIcon = CreatePortalIcon();
			}
			__instance.m_icons.Add(new SpriteData
			{
				m_name = (PinType)portalPinType,
				m_icon = portalIcon
			});
			Plugin.Log.LogInfo((object)$"TargetPortal: registered dedicated map icon as pin type {portalPinType}.");
		}

		private static Sprite CreatePortalIcon()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0025: Expected O, but got Unknown
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false)
			{
				name = "TargetPortalIcon",
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			Type type = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule");
			if (((type == null) ? null : AccessTools.Method(type, "LoadImage", new Type[3]
			{
				typeof(Texture2D),
				typeof(byte[]),
				typeof(bool)
			}, (Type[])null))?.Invoke(null, new object[3]
			{
				val,
				Convert.FromBase64String("iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAJn1JREFUeNo8u0mzZMl1pKl6zOze6+Ob4sWUGchAYiDmKhRIFilV3dItvehl/4T+qd1CqaoFm6SQIEggASITQEbG8CLe6O53MrOjtfBgb33hIteGc9T008P/kyfpJ5Bf21lcel9cA760TXxqqRVtkzSfRqipCCeZzVYMlhmNEIJnF1icoQjIhCqAElDnwugAa4QrKasgCCAi3IyiQGYmIxSSStrbqqGETlNwxuSWzGghUCFArREnkG8HZ4D8PqLeZ9m+Ydm71wzwEFAfihclL6BKAyIBGB1hEMwJuNMYvQ73yv25xin8oPlL7upr69I5Bg2YmNIK3LTwywCcElg57Gm29kQMCVAEKADFaZlkDioFtFmgJ5UqwpOyGhW2PoWAmhI8LjGmBcfYwFODGlqUQDiTKhrNdFpIKm1lWM+IbfQ5mmoSaKLVCPgSdWXk5YywbuChIqRI0FSSpEgAgaikQ7CFyRciAwAmVRhqzLSw8TLvU4e4rb9lThutfLADckdu1xH51InGoQUQnmRrgmDZVChgJjETnB1WiVoCvCZNkATCI6WUlAOJAJAUQ2JhhFsAQBQYBIJOqBolWPCsKY+WfHCvMCyCcucKq9kiUq2Z9N5pecmybYmLB49PTTVWBEaTUGcAooMlwgqgncNOKG2NEikIlgMYsnE9LR7v+X9zHYgmERYttBtB5wSigJUQnogRzpBN/vGYewU0V1gxuMJxVQOklvBgtGAASSIRNCAmkpGKLRUS3RxGQIAcDkqADF5cLADmGaGOirZH0w1oTgbr1ksfAmhBjDkayxZzF+iPbrwJVP0A6YbwG3meAH+gsGs05SwsDHUN0AA9CKEXQq4AWu/3keEcgw9xyWYr4JSQCdyK8XFBKgFeouoIaIrK1cFqqhBkghpCiYAZzcWERDKQKZANga5lbRPQRKJp6NFAMzopiIQ7UEkUd2ZQ2YHcqOQl67xUmXrMH3aepyyezwxnGcHamg872tQRH55wPL9GelzBIJC0dAPPcAIzmgeoTAIi4BshnAACUKdGpUy2XMYbYzxjs4LrxOQm2kaIl444Nig5os5VnA3KlDOiRskbgZE0GEM1msNiE8CFESsAK0Aroy8JLozeRXgTgGSQmWQCHEA1ajZobAwDoKkKcwEGyceGZVoqD0uW/hZtocNlfGqeL2eGPFuzg/z2kU3nH9A+qqIclFlzDZ83AAst7OUaDEyQL512YvIHApMBczxV3YRaTmEhuGwlhKekTUl5alFnQcUgh2pbhQAgOgxmVp0tYGwErgHbgr4lsE2s6xa+aOGLRF+29K5F7QKRAmUAJKASKABLhUoRcxEHgx5aaidoKMLB6PugqQ/04Q56D1GZ9vnM5mlSWfSwW3PbXdpo77B4ZKrVyRIs3srnjYseiaHKpoDSmLwDqNlaBZ+nGKVTxS6azwkMjwlmUx0DPSeffQINQnIggKAQCi1BFjuCawInIM8a+LZlXSf5GvKtgJMKbVvUkwZ125k3xxoggqwFnLKYCzBFYWjMhwDNs2Menb2A24a6ruDOgIct8kOE+gDd3KtlRUmQn1N1faBdGXB4YsPpW3aXAV5EK85Uk4YVLVR6LRJmAA2ANeVZDDlCYvA5Anwi0CL8YPASPXMGG8lVYQApoxVYE9yajcDTAL9I8NMGdW2oW696NACPGmK9MV89D9P60zCdPg7erkzeGVgBVbAWwGewjGLe1zDfuM231WYR8yr4XsJZ73hO4E1reDeJqxXLddSwN+CW0m+L+KOg+jQzpb3zTQMdHtt08t6bS8LnZDZJSa5aDNiLNguYCUYCW4B9+LmtHxF4JIbTCD9EFScqsxQqTIJVMbhZqrTUuDVngj1N8KcL1POkelZVn2fnZyIfb80XL+LUfS/1j36cpvMfWW23QdwEWAdYhpkDsYrRgUCwXZgvzkNdXVpdNFC7V2xH2GJJBQKbyW3dGmYBKVK1QVWFHao4Z9omwLcA1jPCtGKZnGGVYQA0k5z+//YNOSQDEAy+cFoNv7DNpwI/BTEFuDvAKhjIAqDQzBU6wNLSLTwi8KyDP14hb1z1YnZ+XmDPO0N8FEq+DLmemjedaZnAxQ7JPnCBGy7wmms92BKjtRyYNDL4iFB6WO3drHe2LbV+FuuiIeymxgZkXJnHUTxJxORijKYS4dVphyLK5I+SymVhDDPscG7ZeqUOwkxgcnIyVRI+iyChBJKCxQjiCUGavLpkogrILLDQKLfWaHEt8BGAJwvW01Z5NVU8zuBLo3UrU78xL0YLt7buPsQOHheVlrJZAkNrFjogJJiEqEmdBqzQM9QhQj4X+Wx1rosypcYnW7Ne/LDJq69LbHYeFiehNg/VUgr47ezAyqpXn/eVfHeQnQE4CyqPi5LGiqszm5obNecA9oF2EIMDmKDqHzc3GqkIcGFQAZyACqVJZCYZ3BZGC1sBjwA83bCcBNVlX/mJA5+ZmXfB7o3EXVh1fdwsD83JYoybdkqrQCYki2xCgxhapLCmxyUiKho/EN6bMKvRIRqLZ/epHe/m54ev7WK6wULT4mUcmxu3u1clppNQ072HHyXDb2anb5g1Wdg54qvR7SKgft/Ez3aI+UL5IVHbDJ5BPIihGLwF2EsohAoFRfOaAURABcAEYHZGkzWkhTWAc4BPt8wnQWVxqPaJoJcITUZs5kNsuymu05hWmuImT2kd57RunKnQ0r5VRoHLqDaYOhgaiycwuwSNyGnBfrnGrBy6+W4Zx6v89d2X+fPbX5WXwzeEuz1ivvgk1LtvarSzUPy6hO8uzOfemU8x10LuJzbfUP6t5POnY1j0Bw/zxma/VnMC2B0t7r2URCEeu7AcVI0CRHhx2hSgQTCTtYSFhWBngB5vWTYBtd17eE7qs5o2XtMq1NCuh+Yk9+35ODWrKIYQvdy1Pn4jDQVSsjqvg0+tQUu3ZjnH1bo0686bbYPF42jxnHX1CaazEzzUiubmbVqHFX/rmKbi059Nr7paaU9COStwXHt4dBqdtyV81lBzofdLr3ej6Wby8NaB86D6bKL1S+arBKyrtCbQVQszvQZKhZBc0sedVzX4WJAULIRIdoJOHLhc0E8Satp5uCT0MqdNO7enPjUb7BdP5qE5yYT6pgw3je92SZld3q225WG1KbvQ+DyaigRTtlSm0M1TXKchbdqH7nJ9n7+9mKloyx8hffIE3hBD6SPngV/Ph4nzof5I13ZVwUexbu8U5EBemL/I4p5C31Fjog0jwpU7Pg/EZwWaR4X7JQvulbaAls60J2oIUHYEGaQIYgQsA5ZDsNatDYRtBZy35qdr5HRf4zmgl3OzWXno6m75RA+rT3P08r6t4+uA+nA6v9ej/tXyLF+fbjRsg3xThE0FtwKWBBqSJEiS5paYDwu/7n+fvxnf8qoOAfVnaJ6cgRdPUYd9mIbb7vpwVb/ajfqBdnxfQvgsltUXOWJjeXbXtw24K/CHQN7D2rtaeN8oryv5eBTPNqxXRm1dWBmRjEqOUKjqhBQhDbJQDTQhBgNWFdySON9gTnsPHaDnYDgjWB+Wz/KYTu8W8+6Vh3S9zXfj08NXfDS+Pj/R8JjE+ew4d+iiozYRaA1GwoTjExAmGGox+WCP6w4v8rX+OH/Q78qBefoxFo9fwLczbP/W+vVbvxlv9OVc8blm3Lu1z0P2Dx63gaUU4XHLet3R+xpWc0W6h/KBqluV+bGo2wTvJtjKgESYASUAEOUeQRuFYCI7MKSKsCFxumVui2BZvIjwC0C27y53BN60efcKsdlfHv44Ph1edZty/2yL6WkBH7nj2cZ0arCFKwaIiBQaAolEIBAJRABZRF8rmuEa5/4PeOZ7/EMZMXrF+eIx+sVz+OK1PSzeaVUGXcl4VjPOoxKhbUOMBXoK8ZtI3ea0Ug6LPfJ+MNVNKuOjLLxqWfMELgF2lXFPz0Z5BYlIa7LB17AYnLYksEnUukXVnceFwc8I+Jg2b9ty+AYW3nbKD+fj+3yZr7frsvtsy/nZoPCspT5ZB6xnT8FApI8fW2EgiY7CyoAzEzoKRcAg4EMVbqceL+5/hxMK/x2CPf0pzpeXuF08sWn13HfDB5xMd3geAFeIZyG3vXPdUKeD69Tg7yzEeY6rKcin6CONOKnCZkHfEVhK6EgG0IzyArmHn9v6CSysYM1CDKdOXp4xd6PTCvA0ql6U0O0p/yMsfrPQeHNZ3k9P8vvTddm/3IbyYoK9PA/61hltLSU7MaAq4r1HvXXjHQN6BIiGhsLSiAsrWAHoQJyagyRuC7CsA55zwp+wwvL0E5QSMZYdOF5jNe/Y+YwTE06s2rUTDes8iw/Z4vV1+zQf0ukKqi9gtm7nB8nr0FC3GSE7eW/ye6gUQiJZo6yJoAXBWgjr1rQgvEwKW6qunHGml9cM9npRdtdnIevED+dLTc+64J8U2YsL82drhlYKeGLA70qLrz1gJJAtgkxoLOA6NPhTjHjuO3xe9/i2TWjhgAyfWIWs4IssnOz+hJeLr/FH/z6a7TOU+QWH+y99OLzBQzFeeMVZIFf0bhIagzYmdUb1JS0UfFWbeXYxzkDe+tGHiAATiQggQCoiESFFt9CQXBJcrTlzrPQKLgNISB9g9i76/OE85HlTx80S+cKoT6rsydJweWohZI88N+Ef5wZXCrhjo31oobjCMi5gaY3b5WO4F9yO73A1XeGq3OJ7NuJFyPhQEh6Z0HPEl/Maj8sd/jDt4BefIwyfYFxc8BAajQUcBUDElgivZcnoS0EtoVAtsIYG0XMhlAEsXWgjFefjUzgAkEij5FG0CFpLYBGILsnzHrGhvCN8Fux9UvmwstpvMLYd6pmDzxvqguCTrdHuPKVLE/5pbvEg4sZa3aczzatnZusX6Bbn2K+fYoqE+hv0uxXudxG/n5a4zXe41Q4/iCNelQ6X5riSUOcDntYB33QtwvIJprTFYJ0GEHsZqhwRYBEjgQZgA8AEM4eZyUskpgpscDwdEVACYARIiQAsRiJkoXHaao0SZnE8KieZgAdCHyJ0f8YRUb4lcZ6o8yJ7dBJM9x6XT0343dxhlPDOlrpbPsfto/9gPP8pluc/wHx2htg5znbvcPLuDzid71H4EsPwGl/3DcYRGIvhh2HAa1/h2zbjTwAuIbxuW8Smg4UGxRJGBuwhDHKAgIMWAZPUQAgio8gmalbLWg6k/fvpwNE3NDCQKKwMipUxGNA52EaqDgqqYDKoEHYXibsVp2LQMlErB84FnCZyAXG1IviqtBhkeMsGt+tP8eHyF0yP/wpnn/4Y22+9wHZxj2X/Fk9zj4tViyZ8D3b9K/wyvsS9vsYbAHF8jxfJ8Sw4LDpyjLjp1misQTYieSblNsPUg8wiHIYqlwGsNGaLCdKCqovosydVP75+0QAg5Ue7Wk4AMAgRQnKzNlKJUqkiP96TLOA+qh6WoSrCFw5sEnQm4HxFUMeFwwdPOMBwu3is67MfcvH0r/HoR3+NtIl4dvWv+OzuHc7GKzy9/S2+9/B71Ej889P/A4/efIXd8gkOJYMkFjbiZeixiw02TYuyOsUyZmC8RxjvYF4gAIBj1tHfdUAQlC1hCosO0CaorBqfdgsWf0AgjoUPBhASBKNAxKMQYkOgaeBWwakgtICb08Ygf+hY5wbeBnIp6CxQG9LMoNXWKl6XFjsY3rdnutl8C5uLn+Hy27/AQff41q++wIv9a9jwHi92X2CZ9ximGyxwwPd2A778/P/C6utfIS1e4gf1d/i238Nqizue4dBcIKKgnW9w/uHXuBqvUT0zQohwRAgPggipwnwKCx/jYi3aeeNTt/D5YYWSDIE8LhQJuB/rp0SigIpOCwRipFTFUmGLglAJP0TOh45eDeoILQitq7jamqc1tYQCrpzYWdLt6pnHk++Gl89+gZt6i+df/AovH36J8d1X+Nn8DSYLuLAD1naN+2r4ez/H9PAKw2f/G/z9G/zb7h2+N2zxJEQkB1oR3fAe822DZrzH6fgeB89YsWBDR6Swd3qCl5FpHuKaY1ickHieyti0rGpRkiGZES5AoKrJ3eUAoMqA6LBAWiLcZwavDCg0jz7vEzQvWI1QI6kzYkGii8d6wJtqnEHdLC7LtP4kvHjyn1GXRPzqH/Dzh7/FN+/+gJ/nKww+4tJ6bJsJD77Ee57i35rH+Nezn2H4zv8ChH8Ghy/wb/YSKTpyeo5V6fHW19h/eIV9vsWzmrHQjAsWbD7e34PgZ/R6bYthn06abM1ZZHze+Kgt59jJGwIWoFIAAcwGuR9vjQus/y4OAojiMgfgwcsAcAj0OaJ+FBFoISwiFSOQAoA7BTzEbd0vH6s5+6Gtnnwfb+++wH/qf4f+/a/xJB9w5jdwB2Lo8d/7U3Rtwq/TM9x0n2NYPser7hRnm8e4Pf0cXwYhYsTn6PGbxbcwv/5nTFVIh7eYfcJjm/EMBQsR9xIMmis478K6v2suToD0PFjcbsr+/ikOZ5VIhMZAVADFpAzJCYGAE/TIY18MH92gCqCK7KPq0MA9QPGjimoItSQYqWAEb9nUD4uLPG5eNOfP/yNu1wl+NeLF7ld4P4743K8QHTiJA/55OsFXSHjtF7D0CJ4StvMHnHz1T0g0tCFgYINv4gJ/ik+wv/5XHNCgG95jO97iCR7wkzBg58c3xlfFvOM83Npq3KcT7JrTpym2n170b/lM981Pm7H9+2lZArQPxOxCjvSpSIJUAbpbVBRgAFBl1WFyMAteI+rQ0KsAcyAa1BgRAVpDhQlRu7ie+uWTOp99r9Wnz/G+H/Cif4Vw+ADO9zhvCjoBpDAV4Com3MUl1hax3Z7gsz/9v1ikLU49YJp7XM0PeOczlnVALgXr8R0e5wc81x4/Cz3cK0yGdy4U8JDI+SacPbxffnqWXM83tM1l/zX+S7hdvLTC/6bIlt47QiFwADQZ3CtZIRQJIYokATlNgrngJSrLoBxVRDgEUlQ4eupkA2kP0z5tNKyfmz/61KaTJfbXb7Ad32KeD+g0Y6WKzo796gDA5VD7COvNJf6sDni0/x3+w/wK1/EEr+s5vqo9Jq8Y84CzfIetRrzkDt8JGRGOGxIFwptqeWN5eh820/XiGfp48rxZXVxc9DfhU9ziL/HAPQzFgZba9+Bk0AFQLjiS3crohQGREp0BgtzgJapMElxkMUhHWfDRyjhCbURCDqLGzhWXQecX2C/WGPOEdrpBnQ9oVRDckQLQO5DhmMICSwCrsMDTvMd3/AoHn/CT/Gv8Us+Qh4q5zNig4JlN+Cz0OIFjdsNMonfiq2JYW5knS/66+eTwZvPdp2zPnl+k83Q6/Qv+d7xBmxxv5oQKDMnUS+gjta/yDK9FtFwsuYOIOH6gRMIRquhzsYClcrXj9osGGeAk/KiSxASho9cINFg3mCCUuQB5j6qCgOMTVwIKgSohhwQjkbzAU4fcPUVXMwpO8Ml0jQABNmOJivXHkzMeWSqu3fBVASJLUaB+33zr8Pr0Byelu3z6aP1Z2r7/J/y5vsbPeIdqxDe1QYQ/gHGI0n0BhiL9e42rzuiAWTwGFIgKAoA7zIlqhKp/xCgEXODHDJBcADpWbTT4ptxrmh31tkede4x1BFRQBYwgtqj49//PNBxihy4ssV5dQP59qH2Cb3/4W8wEKkZEHDMkgyqMwijgbTVcOTHTZSnpH5vPhz+e/Hh9WL04O129iOf3f8JP/Nf4c/8absK1B7ypsQTTbXXuAnXrwlClGcQssFQEUH5cAIJyEHakIx5V4DAnxeOioBiQBc4ASiV8yZy2Zc/H89s63LzHwZ/A5gMeXAoofPCIHYBH5nBPoBFWZxxsidfLM2B1jpvnf43v/9vf44tHfwW/+kdkPiBwQtAMU8Hkws6BSQAj0Tcb/P3y+/XV9oerafnJYttd8tH9K/xk+Fv85/l3YJ3gjfCnvsUeus2yPaDrCO2KfAQ4VdFhoZiqzdaGiI9BhXoMIiFoyjMbNBgkoAjMx2gMRkGTEfMgmy8sdyd+sDq9Lv3VV8jh24hl0K3HDHg8CLZ34D0DWjgMjsYBzg/I84S3i0v0y3P0Pz7H9379N3Anyv1X8PE9rPagylGukJjiAn9YfIJ/3fwQH7bfb7V6wq45x+bDb/Dj/r/hh/NvtZt7fC/M/GOJeFXiJOh2hF031HWW76s4S8pGZoehMlpQDdHBSsGraCKtWKqSszqrk15pmdREaKzgQGjauU3LBL+sfQjzhzp9+BXuNz9HX2fecZXv2LqjpLfFQgPDKTM2lrHIe5ztXmHuzpGuz3HfXWBsX+LD90+xfvV3aLtLdP1bdNMNTBmDJbxL53i7/ATv1t9Cf/Zt+vYCtIjNq1/iF/f/D749/t4fpoN+wiHcGfRvhxa98HaQ7SLwpgA3RRoCNQAsDst+zG5FgU38+KNXIZgqnMGbOoKEj4jequQITJUcAO4BH3ohz+D0iFOb/TA+2X+hb3bvuKNhimu9spPxRbzSH0rqnpr4DQJONKNRj9PDFfb4J8gdNZ3j9vy7CLbC7fP/gnj2Z2h2b7A4vEJx4SGdYrd6gnGxgZ9cQJsNqgtPvvoX/Oz2f2A5fl3ejH39ed23j9rZ/0e/wIPb+17a9QqvAvQOwINJ+ypOBuTRFnVGMkdoADSR8uK06kCUYEFFIDMAz65SzbJQs2g9gPtZ6CM53rpN51a7nU9R5a1OhivedFvcprV9bY+m79pbuwLwpvrimRluveICEx48IB6ucMdfYx9alFxhmyegRQQs0cUnKIsNFCJqWoEpQV1ARUXYHfDo+hW297/B9e5tXhxu8bN803yvG/R3Y+e3NR5G+Iedxw8N9crF6yrsRR5KVZ7ZjgVJDosGtQ5rw0/T45cgV6A1kciQHypYCsxblLq0GhzWfEx6dRm27YiOwMnLlNvRj2V7H57ifvsd9tMdcu6vl+MH+5S78PvSxm+FavKESQUzgcGFWEbU6Q7j+B55HqAygdMeNt6CeYDnAzwPmOoEjHdI918jXH+tcv8HLD78sz+9+Vf+bPwm/lW756/mpnwzN0XmX98UGwL5RRG/KdINgJu92+C04WCLPNgigFwYuAGti4AXwiaXFgVIx/iIxqPukc+uqSGHDAxGHgTsHLi7qWE4yJrHLOvGe2wOv9Tp9AvsqXRYnPPL/vnV4+nu063Nw9/luPpfm8KpJIwqEAN29YB0yNjM99g9/Anj4hFqu8UcWlQeLXQ3g5MCHA7XIu+w7V/jZf9H/lV+ZT9p9vqHufXXOZbW6qurEiaQv6nCW0A3AO6y0BdyfNAiF4UQ6I3DOieXACxSNTvCJGJ2KNrRYGRQrj07NyifaxoL0QfwIUDXs3hB4PYPOW7/vJkr6hQ+nb7E2w//n65PP8Owx2m/ePLHf/QB/3X+zWdXWI5/M8fuvzYTN94iVGEDIWPANPWo8z3m/StMoUW2iN4a6KMAiUeMr4jCtWZ+rgf8pV1jGbP+ZuwwOKfW6purbCOJfwHwhtTV7HZH+W7ncThwMU5srMICgc6ApQMdQISfxsdPA7VwhhY8eoGARkI5I3pDry2mYGCTyCBYykfaknq3y0exxEvzkDzz65z9fvkD633Qjg2TyheHeY7f4e1mYKhflWjP42yfR0f3MY66ZcUpMk5V8KhOaGrGadnhYr7FJ/MNLssOF/WB3/U7/oXd4MfhXu+c+rupBYF7Q72+LrY32j879M7B11m8CcTdQ2U/Iw17JDpo1ZqG4EoMawFLgTn8ND6+BNQ5rD3KDRigUbQssDbIOcKNAAOVEmUCG4FLQc3kuHiZiq28cqgj383E3fmPbJj38xy6ORC/GcchPud+25j8q5qQJfs0ZT5LjlUgAg20gPgRn21YcWoZF2HGizjhu2nAp2HAHq5fzq2/r2HaWrkZ3Id7tw+R/JUL7yv5GtI9wOuD2zAgjQ/olBGDMwSRCzJsXViATKZyF/6jnVyA1jitIdSAlj4KoCmizJA8oYBHWZICaSRChi06c97VsAG1fBGLJS+8nvflXXwW5uWlj3XsQfZGfDnO09z5uDwPOfWg3rnx4GSwym2sOIkF25BxEiZsQsY2ZCxCUaHjrdN/X1K5cxtb+oGoh7vKPsu+TNQXRfjgsNcgbit4fXCOD+j6A1sf2CbBAs3aYHFbwZXI1uTZ4Lfhz8PZJsMag5JoCWQ8JqiUAcygZUP14BmEeFSMQX6MvHURKm9LPE2s6TvMdi8fb4aH3dvlp2dNbMuBoXdLU6R+77XelDyXwNouWBJY0APlzlluneWDs946/dZRb53ltnI6CJOgMdKHIp92FQ+T7A+B+LWLryv4BsC7KtwW2M29N9O9unFEjAPa4AzmIbWN2XZGWDvQHtF4vUsoN+Ev0sVSQKi0RLIBkEQ2Bi+CZgE1gyWoukjMYmg/uqoTLBrJSSxvalql4H7KHO9cb4f+4XC7enbZCfUQ2t1oixLhb0h+sDpfj47DLKjCTagkaiVrBWsx1EzU7PAySNPBsT+4XRXwy0D8zoE3Rbwy6o2D11W8zeDuQc10x0V5wCJkxmREIENoQ9zMtLVLDchonu8E3kWfDuGH3C5NJCxESY0zJgJJoB1VIosz1KgsU0WGQZKR5gI1ypqGKA8e8cqb1KCUzvOYvX7QcNffrj55GsR2tnS7b85QGG+KtfdJ+X1QeVfBq1m4naWHybGbHfejeD2K7zL42sU/AvjKiK9deFfBK4BvQXyYnXczwm2vONxgUe6wYJbFSkuzdTHSQpvSekJYF/nR1lN5MOg+au7FcBN+znXrDGyRg9PMGVoCJiDxqAVqRKkEHKh+dFWPIQ/SagY1I6REjQ/VwpW3aKjcoPTm8z6Ot4f7xZNLt3QuhMOuvQizteMhbnYF4cFUrk31PYF3At8BeCvgnYC3Dr4VcFXE9wCvBF4BuM6y+wHhfkLoH9T4DRd4QBczYiswGU0hNrELcTWKq+KeALZU2QX4HZX3AXwY4nIffmrnTYMgt4jMkI6ReUYAQWQC4JSq07xaKoBqUPYCmBAqYDmDXmmhNT8c3MIHb5YOqvOco099O970fXO6Hdrzb7Wl1xDXNsZ1GKwbDmF1mNjuJL+TdF2F6wq+r+CHCrv+eMSvM+xugu0GxcM92vkWHW6xCA/suiLrnCFO1qbOpJRWTRPjZiglVXlTENqgfA/ojioPEXUv+f3CH/rwC3vWBj9Yb5saUEJQ5ZGiMnykRuE4HxTg/26YqIhArVIwsxngXBBQaezofRZ872E7IsQgr9HnaTHd9ALiw/L5t6PnbaiTF8TGRatey6SQM2wqsCGDQ5YNM2yYYOOgMO8U64PaeIuuuediMSl2M2NXEDsCKRm8i0ltbFqR3VgyBbX1KPbuKH8w1bvoc2/wO7ntu/Iwh1+0F22vXKWJER5As4QanCEKCKAFRwiEi5IfXdVYJcJQBdUA2iRyzgiqCNZSPaBxFroRtpIQoufczvdjO93PfXd+Wa153uVdiqVPVGlZ57a4x7Eyjm7NoJgOHpu9QtsrLgak9YS4GtmuKsMKRBegVK21JgTvYlI0S8WrlVoDgEURBfgNj5T7PiiPsrBz147wHAwK/0mL9t53ZQ3Kjlw0gBCgSFogdETOIAwOyilCIGuAuyS5PACcSJsKWAsCEjUFYgcoF6EtQktVNmU/rcYPh1QOqNZcgOG8nR+WwXNjXpaUrwWsBa0AbQSuHLYSbUVgBWNXrGnCEVSMXeDUGqrgrLWaC40DTREmot4A3FH1nvKhYb2v7gfKerEW8/0c/gJd7FWs+/jsiBAckBiMONrgx1ABI+FGiALNj6NzlXCHvELVBGTQDqJNs4KMLA2xj9S9A6OOCdUQy6gm7+fFdNs3ZZ+j5gWljWAGaklg5bRGYGvwpTOYI5hRRtqUoH0yHlr6HCg/Dp55qkA7yST4vaQ7QDuqPlSwF21vqqNh6q1OnkUPcosZiFs2aOjeo9Ss2DeomhkCIIuq5FE5tA5rC42mSn1MVhPKUXLBSc8twArGDAvDqHA+M5w1VodW/uBQW6VFFdbmeUGVLtQpEoqEwxEGQoXHDaiCZZAzwSFSI2hjgzqDmnTMHdLkzQwLWVaLsAsoe0CHinAIXiZD3Zew3CfPufFxBuEzB+8lW1gbo6PGFgEVhhbMQi0GTKZZgoFAMIASQTCJMQrWURUCObPpZSjB8xRQK3zujEWO9pq0XuDDKDsZETYNtEhW9wm6lRAKkByKDgbIzI7OXIFUomoR7ZizouaPvqRIeGANDnBCwEGhurAD/GBSX2G9oY5UnRv4rsr7rva5Ouqh9vOpcoYt+SnVzEATI2NymIjqSR56lDxyOZyVBwuhOfTs6EfT1P04iZkERAMWBOggZluMkWGWTyUpD1JpQ62hWrs3YJTFHRhWI2wzypYB6BKVAhQTRcqJj/wF8ALSj0NVro8sQg5YOY5ccpSVIuYKDgYfA9TX450fWuQZqkNgHFxekk9WvCiElGcfymwL0NZp8H5J5RgzDY1qoApmNjTN9qje53trp5aJI/w+iAJVTDoF1UrsQBmEFiAgwWEEQ3HVatAAeTQfW4fNgs9g2oHhjmAnYDGAnRBak5IRHyGtjMCR3RIC6BLcwVrBImg2YIZ8JjQZw6wj9pqjSnZgctohUiNqT5MzArVXGWsZ8sraUJEi6q451lD0cV2HsbBpxJAc1Y0JzsDJhzlny4t2vYLrUCWZKgxh47Aqsa0IAbQI+cKOnWCUpZmq7mA+ts4a5TLQi8H2sjgCdm+wppIN4dFl4TizAAIMRxBHHFUnHfAKsBzDpSqmWgzKplwqQjGVuSL0Bs8hxMlz31qdAXIaaP3SoqqXSFgMYCsqHWl4nGJByQ067QhP7qGCacdQh7T00m29G+Zdserw6p3mMoWumsraEWqAOkeIPAonVlgUbQA4gyxRuVLFk2p0IDicXr3QAihmMvQCQoCsMDGimo6kynR8gLvDEFHdZfmoSosAVKmq0rLBB5cV8xGiAvPcCgRh04Fplo+IQgpokqkGsKi3thd8vKu7KRa7GKtulh26aReX4bLucG0tje6fDG8ZK+vC07QH3KF+pTr1DIOpbgRrRUuUJ9EMYJacldEi3CTLkUYDakK1SUZS5u4g6IZyHMGlKSBLJASDQaoMJOQmgaQnVR/ZeJTX4/zyMR9FLwqqOLZrwWvJ4nIoKjUoWoJ1TjCAqTL47OqhOd+EZvzt5sf1fw4AqKTpP/QALc8AAAAASUVORK5CYII="),
				true
			}) as bool? != true)
			{
				Plugin.Log.LogError((object)"TargetPortal: failed to decode the original portal map icon.");
			}
			return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 64f);
		}

		private void RegisterRpcs()
		{
			if (ZRoutedRpc.instance != null && registeredWith != ZRoutedRpc.instance)
			{
				ZRoutedRpc.instance.Register<ZPackage>("VU_PortalList", (Action<long, ZPackage>)OnPortalList);
				ZRoutedRpc.instance.Register("VU_PortalRequest", (Action<long>)OnPortalRequest);
				ZRoutedRpc.instance.Register<ZDOID, int, string, string>("VU_PortalMode", (Method<ZDOID, int, string, string>)OnPortalModeChange);
				registeredWith = ZRoutedRpc.instance;
				lastBroadcastHash = 0;
				nextBroadcast = 0f;
				portals.Clear();
				listReceived = false;
				nextListRequest = 0f;
				sessionStarted = Time.time;
				Plugin.Log.LogInfo((object)"TargetPortal: portal list handlers registered for this session.");
			}
		}

		private void UpdateClientList()
		{
			if ((Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsServer() || listReceived || Time.time < nextListRequest)
			{
				return;
			}
			if (ZNet.instance.GetServerPeer() == null)
			{
				nextListRequest = Time.time + 1f;
				return;
			}
			ZRoutedRpc.instance.InvokeRoutedRPC("VU_PortalRequest", Array.Empty<object>());
			float num = Time.time - sessionStarted;
			nextListRequest = Time.time + ((num < 20f) ? 2f : 10f);
			if (num > 10f && portals.Count == 0)
			{
				UseLocalPortalList();
			}
		}

		private void UseLocalPortalList()
		{
			if (ZDOMan.instance != null)
			{
				int hash;
				ZPackage val = BuildPackage(out hash);
				val.SetPos(0);
				ReadPortalList(val);
			}
		}

		private static void ZdoAddPeerPostfix()
		{
			if (current != null && (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
			{
				current.lastBroadcastHash = 0;
				current.nextBroadcast = Mathf.Min(current.nextBroadcast, Time.time + 2f);
			}
		}

		public void Update()
		{
			if (Active && ZRoutedRpc.instance != null && !rpcRegistered)
			{
				RegisterRpcs();
			}
			if (Active && rpcRegistered)
			{
				UpdateClientList();
			}
			if (Active && rpcRegistered && (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && ZDOMan.instance != null && Time.time >= nextBroadcast)
			{
				nextBroadcast = Time.time + Mathf.Max(1f, broadcastInterval.Value);
				int hash;
				ZPackage package = BuildPackage(out hash);
				if (hash != lastBroadcastHash)
				{
					lastBroadcastHash = hash;
					Broadcast(package, 0L);
				}
			}
			UpdateMapControls();
			UpdateLeftPortal();
		}

		private void OnPortalRequest(long sender)
		{
			if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer())
			{
				Broadcast(BuildPackage(out var _), sender);
			}
		}

		private void Broadcast(ZPackage package, long target)
		{
			ZRoutedRpc.instance.InvokeRoutedRPC(target, "VU_PortalList", new object[1] { package });
			if (target == 0L)
			{
				package.SetPos(0);
				OnPortalList(ZNet.GetUID(), package);
			}
		}

		private static ZPackage BuildPackage(out int hash)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_004c: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			List<ZDO> portalList = ZDOMan.instance.GetPortalList();
			ZPackage val = new ZPackage();
			val.Write(portalList.Count);
			hash = portalList.Count;
			foreach (ZDO item in portalList)
			{
				string text = item.GetString(ZDOVars.s_tag, "");
				Vector3 position = item.GetPosition();
				val.Write(item.m_uid);
				val.Write(text);
				val.Write(position);
				val.Write(item.GetRotation());
				PortalMode portalMode = SquashMode(item.GetInt("TargetPortal PortalMode", 0));
				string text2 = item.GetString("TargetPortal PortalOwnerId", string.Empty);
				string text3 = item.GetString("TargetPortal PortalOwnerName", string.Empty);
				val.Write((int)portalMode);
				val.Write(text2);
				val.Write(text3);
				hash = hash * 31 + ((object)Unsafe.As<ZDOID, ZDOID>(ref item.m_uid)/*cast due to .constrained prefix*/).GetHashCode();
				hash = hash * 31 + text.GetHashCode();
				hash = hash * 31 + Mathf.RoundToInt(position.x) + Mathf.RoundToInt(position.z) * 977;
				hash = (int)(hash * 31 + portalMode);
				hash = hash * 31 + text2.GetHashCode();
			}
			return val;
		}

		private void OnPortalList(long sender, ZPackage package)
		{
			listReceived = true;
			ReadPortalList(package);
		}

		private void ReadPortalList(ZPackage package)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			portals.Clear();
			int num = package.ReadInt();
			for (int i = 0; i < num; i++)
			{
				portals.Add(new PortalEntry
				{
					Id = package.ReadZDOID(),
					Tag = package.ReadString(),
					Position = package.ReadVector3(),
					Rotation = package.ReadQuaternion(),
					Mode = SquashMode(package.ReadInt()),
					OwnerId = package.ReadString(),
					OwnerName = package.ReadString()
				});
			}
		}

		private static bool InteractPrefix(TeleportWorld __instance, Humanoid human, bool hold, ref bool __result)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Expected O, but got Unknown
			if (!Active || current == null || (Object)(object)human != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			if (!PrivateArea.CheckAccess(((Component)__instance).transform.position, 0f, true, false))
			{
				((Character)human).Message((MessageType)2, "$piece_noaccess", 0, (Sprite)null, false);
				__result = true;
				return false;
			}
			if (!hold && current.allowPrivatePortals.Value)
			{
				KeyboardShortcut value = current.modeToggleShortcut.Value;
				if (((KeyboardShortcut)(ref value)).IsPressed())
				{
					current.TogglePortalMode(__instance, human);
					__result = true;
					return false;
				}
			}
			if (current.openMapOnEnter.Value)
			{
				if (hold)
				{
					__result = false;
					return false;
				}
				if (!CanModifyPortal(__instance, showMessage: true))
				{
					__result = true;
					return false;
				}
				if (!TextInput.IsVisible() && (Object)(object)TextInput.instance != (Object)null)
				{
					TextInput.instance.RequestText((TextReceiver)(object)__instance, "$piece_portal_tag", Mathf.Clamp(current.portalNameLength.Value, 5, 100));
				}
				__result = true;
				return false;
			}
			if (hold)
			{
				if (!CanModifyPortal(__instance, showMessage: true))
				{
					__result = true;
					return false;
				}
				if (!TextInput.IsVisible() && (Object)(object)TextInput.instance != (Object)null)
				{
					TextInput.instance.RequestText((TextReceiver)(object)__instance, "$piece_portal_tag", Mathf.Clamp(current.portalNameLength.Value, 5, 100));
				}
				__result = true;
				return false;
			}
			current.OpenPicker(__instance, (Player)human, fromTrigger: false);
			__result = true;
			return false;
		}

		private static bool TriggerEnterPrefix(TeleportWorldTrigger __instance, Collider colliderIn)
		{
			if (!Active || current == null || !current.openMapOnEnter.Value)
			{
				return true;
			}
			Player component = ((Component)colliderIn).GetComponent<Player>();
			if ((Object)(object)component == (Object)null || (Object)(object)component != (Object)(object)Player.m_localPlayer)
			{
				return false;
			}
			if (((Character)component).IsTeleporting() || (Object)(object)current.pickerSource != (Object)null)
			{
				return false;
			}
			object? obj = TriggerPortalField?.GetValue(__instance);
			TeleportWorld val = (TeleportWorld)((obj is TeleportWorld) ? obj : null);
			if (val != null)
			{
				current.OpenPicker(val, component, fromTrigger: true);
			}
			return false;
		}

		private void UpdateLeftPortal()
		{
			//IL_002e: 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)pickerSource == (Object)null) && pickerFromTrigger && !((Object)(object)Player.m_localPlayer == (Object)null) && !(Vector3.Distance(((Component)Player.m_localPlayer).transform.position, ((Component)pickerSource).transform.position) <= 4f))
			{
				if ((Object)(object)Minimap.instance != (Object)null)
				{
					DragViewField?.SetValue(Minimap.instance, false);
				}
				ClosePicker();
			}
		}

		private static bool PlacePiecePrefix(Player __instance)
		{
			if (Active && current != null && current.maximumNumberOfPortals.Value > 0)
			{
				object? obj = PlacementGhostField?.GetValue(__instance);
				GameObject val = (GameObject)((obj is GameObject) ? obj : null);
				if (val != null && !((Object)(object)val.GetComponent<TeleportWorld>() == (Object)null) && current.portals.Count >= current.maximumNumberOfPortals.Value)
				{
					((Character)__instance).Message((MessageType)2, Loc.Text($"이 월드에는 포털을 {current.maximumNumberOfPortals.Value}개보다 더 설치할 수 없습니다.", $"You cannot place more than {current.maximumNumberOfPortals.Value} portals in this world."), 0, (Sprite)null, false);
					return false;
				}
			}
			return true;
		}

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

		private static bool TargetFoundPrefix(ref bool __result)
		{
			if (!Active || current == null)
			{
				return true;
			}
			__result = current.portalAnimation.Value;
			return false;
		}

		private static bool BlockWhilePickingPrefix()
		{
			if (current != null)
			{
				return (Object)(object)current.pickerSource == (Object)null;
			}
			return true;
		}

		private static void HoverTextPostfix(TeleportWorld __instance, ref string __result)
		{
			if (!Active)
			{
				return;
			}
			int num = __result.LastIndexOf('\n');
			string text = ((num >= 0) ? __result.Substring(0, num) : __result);
			string text2 = Localization.instance.Localize("$KEY_Use");
			PortalFeature? portalFeature = current;
			if (portalFeature != null && portalFeature.openMapOnEnter.Value)
			{
				__result = text + "\n" + Loc.Text("포털에 들어가면 목적지를 선택합니다", "Walk in to choose a destination") + "\n" + Loc.Text("[<color=yellow><b>" + text2 + "</b></color>] 이름 변경", "[<color=yellow><b>" + text2 + "</b></color>] Rename");
			}
			else
			{
				__result = text + "\n" + Loc.Text("[<color=yellow><b>" + text2 + "</b></color>] 목적지 선택", "[<color=yellow><b>" + text2 + "</b></color>] Choose destination") + "\n" + Loc.Text("[<color=yellow><b>" + text2 + "</b></color> 길게] 이름 변경", "[Hold <color=yellow><b>" + text2 + "</b></color>] Rename");
			}
			PortalFeature? portalFeature2 = current;
			if (portalFeature2 != null && portalFeature2.allowPrivatePortals.Value)
			{
				ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
				ZDO obj = ((component != null) ? component.GetZDO() : null);
				PortalMode portalMode = SquashMode((obj != null) ? obj.GetInt("TargetPortal PortalMode", 0) : 0);
				string text3 = ((obj != null) ? obj.GetString("TargetPortal PortalOwnerName", string.Empty) : null) ?? string.Empty;
				string text4 = ModeText(portalMode);
				if (portalMode == PortalMode.Private && !string.IsNullOrEmpty(text3))
				{
					text4 += Loc.Text(" (소유자: " + StringExtensionMethods.RemoveRichTextTags(text3) + ")", " (Owner: " + StringExtensionMethods.RemoveRichTextTags(text3) + ")");
				}
				__result = __result + "\n" + Loc.Text("공개 범위: " + text4, "Visibility: " + text4) + "\n" + Loc.Text("[<color=yellow><b>Shift + " + text2 + "</b></color>] 공개/비공개 전환", "[<color=yellow><b>Shift + " + text2 + "</b></color>] Toggle public/private");
			}
		}

		private static void PieceSetCreatorPostfix(Piece __instance)
		{
			if (!Active)
			{
				return;
			}
			PortalFeature? portalFeature = current;
			if (portalFeature == null || !portalFeature.allowPrivatePortals.Value || (Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)((Component)__instance).GetComponent<TeleportWorld>() == (Object)null)
			{
				return;
			}
			ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
			ZDO val = ((component != null) ? component.GetZDO() : null);
			if (val != null && val.GetInt("TargetPortal PortalMode", -1) == -1 && __instance.GetCreator() == Player.m_localPlayer.GetPlayerID())
			{
				SetMode(val, current.defaultPortalMode.Value, LocalOwnerId(), Player.m_localPlayer.GetPlayerName());
				if (current != null)
				{
					current.nextBroadcast = 0f;
				}
			}
		}

		private void TogglePortalMode(TeleportWorld portal, Humanoid human)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			if (CanModifyPortal(portal, showMessage: true))
			{
				ZNetView component = ((Component)portal).GetComponent<ZNetView>();
				ZDO val = ((component != null) ? component.GetZDO() : null);
				if (val != null && ZRoutedRpc.instance != null)
				{
					PortalMode portalMode = ((SquashMode(val.GetInt("TargetPortal PortalMode", 0)) == PortalMode.Public) ? PortalMode.Private : PortalMode.Public);
					Player localPlayer = Player.m_localPlayer;
					string text = ((localPlayer != null) ? localPlayer.GetPlayerName() : null) ?? ((Character)human).GetHoverName();
					ZRoutedRpc.instance.InvokeRoutedRPC(0L, "VU_PortalMode", new object[4]
					{
						val.m_uid,
						(int)portalMode,
						LocalOwnerId(),
						text
					});
					SetMode(val, portalMode, LocalOwnerId(), text);
					((Character)human).Message((MessageType)2, Loc.Text("포털을 " + ModeText(portalMode) + " 모드로 변경했습니다.", "Portal changed to " + ModeText(portalMode) + " mode."), 0, (Sprite)null, false);
					nextBroadcast = 0f;
				}
			}
		}

		private void OnPortalModeChange(long sender, ZDOID portalId, int rawMode, string ownerId, string ownerName)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			ZDOMan instance = ZDOMan.instance;
			ZDO val = ((instance != null) ? instance.GetZDO(portalId) : null);
			if (val != null)
			{
				SetMode(val, SquashMode(rawMode), ownerId, ownerName);
				nextBroadcast = 0f;
			}
		}

		private static void SetMode(ZDO zdo, PortalMode mode, string ownerId, string ownerName)
		{
			zdo.Set("TargetPortal PortalMode", (int)mode);
			zdo.Set("TargetPortal PortalOwnerId", ownerId);
			zdo.Set("TargetPortal PortalOwnerName", ownerName);
		}

		private static bool CanModifyPortal(TeleportWorld portal, bool showMessage)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if (PrivateArea.CheckAccess(((Component)portal).transform.position, 0f, true, false))
			{
				return true;
			}
			if (showMessage)
			{
				Player localPlayer = Player.m_localPlayer;
				if (localPlayer != null)
				{
					((Character)localPlayer).Message((MessageType)2, "$piece_noaccess", 0, (Sprite)null, false);
				}
			}
			return false;
		}

		private static PortalMode SquashMode(int rawMode)
		{
			if (rawMode != 0)
			{
				return PortalMode.Private;
			}
			return PortalMode.Public;
		}

		private static string LocalOwnerId()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			return ((object)((IUser)PlatformManager.DistributionPlatform.LocalUser).PlatformUserID/*cast due to .constrained prefix*/).ToString().Replace("Steam_", string.Empty);
		}

		private static string ModeText(PortalMode mode)
		{
			if (mode != PortalMode.Public)
			{
				return Loc.Text("비공개", "Private");
			}
			return Loc.Text("공개", "Public");
		}

		private void OpenPicker(TeleportWorld source, Player player, bool fromTrigger)
		{
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: 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_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			if (ZoneSystem.instance.GetGlobalKey((GlobalKeys)32))
			{
				((Character)player).Message((MessageType)2, "$msg_blocked", 0, (Sprite)null, false);
				return;
			}
			if (!CanTeleport(player, source))
			{
				((Character)player).Message((MessageType)2, "$msg_noteleport", 0, (Sprite)null, false);
				return;
			}
			Minimap instance = Minimap.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			ClearPickerPins();
			if (portals.Count == 0 && (Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer())
			{
				nextListRequest = 0f;
				UpdateClientList();
				UseLocalPortalList();
			}
			ZNetView component = ((Component)source).GetComponent<ZNetView>();
			ZDOID val = (ZDOID)(((??)((component == null) ? ((ZDOID?)null) : component.GetZDO()?.m_uid)) ?? ZDOID.None);
			int num = 0;
			int num2 = 0;
			foreach (PortalEntry portal in portals)
			{
				if (portal.Id == val || (string.IsNullOrEmpty(portal.Tag) && !showUntagged.Value))
				{
					continue;
				}
				if (allowPrivatePortals.Value && portal.Mode == PortalMode.Private && !string.Equals(portal.OwnerId, LocalOwnerId(), StringComparison.Ordinal))
				{
					num2++;
					continue;
				}
				string text = (string.IsNullOrEmpty(portal.Tag) ? Loc.Text("(이름 없음)", "(untagged)") : StringExtensionMethods.RemoveRichTextTags(portal.Tag));
				if (portalPinType < 0)
				{
					Plugin.Log.LogError((object)"TargetPortal picker cannot open because its map icon was not registered.");
					((Character)player).Message((MessageType)2, Loc.Text("포털 지도 아이콘을 준비하지 못했습니다.", "The portal map icon is not ready."), 0, (Sprite)null, false);
					ClearPickerPins();
					return;
				}
				PinData val2 = instance.AddPin(portal.Position, (PinType)portalPinType, text, false, false, 0L, default(PlatformUserID));
				pickerPins.Add(val2);
				pinToPortal[val2] = portal;
				num++;
			}
			if (num == 0)
			{
				string text2 = ((portals.Count == 0 && !listReceived && (Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer()) ? Loc.Text("서버에서 포털 목록을 받는 중입니다. 잠시 후 다시 들어가 보세요.", "Waiting for the portal list from the server. Try again in a moment.") : ((num2 <= 0) ? Loc.Text("이동할 수 있는 다른 포털이 없습니다.", "No other portal to travel to.") : Loc.Text($"이동할 수 있는 공개 포털이 없습니다. (다른 사람의 비공개 포털 {num2}개 제외)", $"No public portal to travel to ({num2} private portal(s) of other players hidden).")));
				ManualLogSource log = Plugin.Log;
				string text3 = $"TargetPortal picker empty: list={portals.Count}, received={listReceived}, ";
				ZNet instance2 = ZNet.instance;
				log.LogInfo((object)(text3 + $"server={((instance2 != null) ? new bool?(instance2.IsServer()) : ((bool?)null))}, hiddenPrivate={num2}, untaggedShown={showUntagged.Value}."));
				((Character)player).Message((MessageType)2, text2, 0, (Sprite)null, false);
				ClearPickerPins();
				return;
			}
			pickerSource = source;
			pickerFromTrigger = fromTrigger;
			if (InventoryGui.IsVisible())
			{
				InventoryGui.instance.Hide();
			}
			bool noMap = Game.m_noMap;
			Game.m_noMap = false;
			if (fromTrigger)
			{
				instance.ShowPointOnMap(((Component)source).transform.position);
			}
			else
			{
				instance.SetMapMode((MapMode)2);
			}
			Game.m_noMap = noMap;
			HideOtherPins(instance);
			BuildFavoriteList();
			((Character)player).Message((MessageType)2, Loc.Text("포털 클릭: 이동 · 우클릭: 즐겨찾기", "Click: travel · Right-click: favourite"), 0, (Sprite)null, false);
		}

		private static bool MapLeftClickPrefix(Minimap __instance)
		{
			if (current == null || (Object)(object)current.pickerSource == (Object)null || current.pickerPins.Count == 0)
			{
				return true;
			}
			if (!current.TryGetClosestPickerPortal(__instance, out PinData _, out PortalEntry portal))
			{
				return true;
			}
			current.Travel(portal);
			return false;
		}

		private static bool RemovePinUnderPointerPrefix(Minimap __instance)
		{
			if (current == null || (Object)(object)current.pickerSource == (Object)null)
			{
				return true;
			}
			if (!current.TryGetClosestPickerPortal(__instance, out PinData _, out PortalEntry portal))
			{
				return true;
			}
			current.ToggleFavorite(portal);
			return false;
		}

		private bool TryGetClosestPickerPortal(Minimap map, out PinData pin, out PortalEntry portal)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			pin = null;
			portal = null;
			if (ScreenToWorldMethod == null || InteractRadiusGetter == null)
			{
				return false;
			}
			Vector3 val = (Vector3)ScreenToWorldMethod.Invoke(map, new object[1] { ZInput.pointerPosition });
			float num = (float)InteractRadiusGetter.Invoke(map, null);
			float num2 = float.MaxValue;
			foreach (PinData pickerPin in pickerPins)
			{
				float num3 = Utils.DistanceXZ(val, pickerPin.m_pos);
				if (num3 < num && num3 < num2)
				{
					pin = pickerPin;
					num2 = num3;
				}
			}
			if (pin != null)
			{
				return pinToPortal.TryGetValue(pin, out portal);
			}
			return false;
		}

		private HashSet<string> FavoriteIds()
		{
			HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || !localPlayer.m_customData.TryGetValue("TargetPortal Favorites", out var value))
			{
				return hashSet;
			}
			string[] array = value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string item in array)
			{
				hashSet.Add(item);
			}
			return hashSet;
		}

		private void ToggleFavorite(PortalEntry portal)
		{
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null))
			{
				HashSet<string> hashSet = FavoriteIds();
				string item = ((object)Unsafe.As<ZDOID, ZDOID>(ref portal.Id)/*cast due to .constrained prefix*/).ToString();
				bool flag = hashSet.Add(item);
				if (!flag)
				{
					hashSet.Remove(item);
				}
				localPlayer.m_customData["TargetPortal Favorites"] = string.Join(",", hashSet);
				BuildFavoriteList();
				((Character)localPlayer).Message((MessageType)2, flag ? Loc.Text("포털을 즐겨찾기에 추가했습니다.", "Portal added to favourites.") : Loc.Text("포털을 즐겨찾기에서 제거했습니다.", "Portal removed from favourites."), 0, (Sprite)null, false);
			}
		}

		private unsafe void BuildFavoriteList()
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			//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_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			DestroyFavoriteList();
			Minimap instance = Minimap.instance;
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)instance == (Object)null || (Object)(object)localPlayer == (Object)null || (Object)(object)pickerSource == (Object)null)
			{
				return;
			}
			Transform obj = instance.m_largeRoot.transform.Find("KeyHints/keyboard_hints/AddPin");
			GameObject val = ((obj != null) ? ((Component)obj).gameObject : null);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)"Portal favourites: native AddPin key-hint template was not found.");
				return;
			}
			favoriteList = new GameObject("UnifiedTargetPortal Favorites", new Type[2]
			{
				typeof(RectTransform),
				typeof(VerticalLayoutGroup)
			});
			favoriteList.transform.SetParent(instance.m_largeRoot.transform, false);
			RectTransform val2 = (RectTransform)favoriteList.transform;
			val2.anchorMin = new Vector2(0f, 0.5f);
			val2.anchorMax = new Vector2(0f, 0.5f);
			val2.pivot = new Vector2(0f, 0.5f);
			val2.anchoredPosition = new Vector2(15f, 0f);
			val2.sizeDelta = new Vector2(240f, 500f);
			VerticalLayoutGroup component = favoriteList.GetComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)component).spacing = 3f;
			HashSet<string> hashSet = FavoriteIds();
			foreach (KeyValuePair<PinData, PortalEntry> item in pinToPortal)
			{
				PortalEntry value = item.Value;
				if (hashSet.Contains(((object)Unsafe.As<ZDOID, ZDOID>(ref value.Id)/*cast due to .constrained prefix*/).ToString()))
				{
					GameObject obj2 = Object.Instantiate<GameObject>(val, favoriteList.transform, false);
					ZDOID id = value.Id;
					((Object)obj2).name = "FavoritePortal_" + ((object)(*(ZDOID*)(&id))/*cast due to .constrained prefix*/).ToString();
					obj2.SetActive(true);
					HorizontalLayoutGroup component2 = obj2.GetComponent<HorizontalLayoutGroup>();
					if ((Object)(object)component2 != (Object)null)
					{
						((LayoutGroup)component2).childAlignment = (TextAnchor)3;
					}
					Transform obj3 = obj2.transform.Find("Label");
					TMP_Text val3 = ((obj3 != null) ? ((Component)obj3).GetComponent<TMP_Text>() : null);
					if ((Object)(object)val3 != (Object)null)
					{
						val3.text = (string.IsNullOrEmpty(value.Tag) ? Loc.Text("(이름 없음)", "(untagged)") : StringExtensionMethods.RemoveRichTextTags(value.Tag));
						val3.transform.SetAsLastSibling();
					}
					Transform obj4 = obj2.transform.Find("keyboard_hint");
					Image val4 = ((obj4 != null) ? ((Component)obj4).GetComponent<Image>() : null);
					if ((Object)(object)val4 != (Object)null)
					{
						val4.sprite = item.Key.m_icon;
					}
					FavoritePortalClick favoritePortalClick = obj2.AddComponent<FavoritePortalClick>();
					favoritePortalClick.Owner = this;
					favoritePortalClick.Portal = value;
				}
			}
		}

		private void UpdateMapControls()
		{
			Minimap instance = Minimap.instance;
			if (Active)
			{
				_ = (Object)(object)instance == (Object)null;
			}
		}

		private void Travel(PortalEntry destination)
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: 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_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: 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)
			Player localPlayer = Player.m_localPlayer;
			TeleportWorld val = pickerSource;
			ClosePicker();
			if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)val == (Object)null))
			{
				if (ZoneSystem.instance.GetGlobalKey((GlobalKeys)32))
				{
					((Character)localPlayer).Message((MessageType)2, "$msg_blocked", 0, (Sprite)null, false);
					return;
				}
				float num = default(float);
				if (ZoneSystem.instance.GetGlobalKey((GlobalKeys)33) && (RandEventSystem.instance.GetBossEvent() != null || (ZoneSystem.instance.GetGlobalKey((GlobalKeys)47, ref num) && num > 0f)))
				{
					((Character)localPlayer).Message((MessageType)2, "$msg_blockedbyboss", 0, (Sprite)null, false);
					return;
				}
				if (!CanTeleport(localPlayer, val))
				{
					((Character)localPlayer).Message((MessageType)2, "$msg_noteleport", 0, (Sprite)null, false);
					return;
				}
				Vector3 val2 = destination.Rotation * Vector3.forward;
				Vector3 val3 = destination.Position + val2 * val.m_exitDistance + Vector3.up;
				Plugin.Log.LogInfo((object)$"Portal travel to '{destination.Tag}' at {destination.Position}.");
				((Character)localPlayer).TeleportTo(val3, destination.Rotation, true);
				Game.instance.IncrementPlayerStat((PlayerStatType)15, 1f, false);
			}
		}

		private static void SetMapModePostfix(MapMode mode)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			if (current != null && (Object)(object)current.pickerSource != (Object)null && (int)mode != 2)
			{
				current.ClosePicker();
			}
		}

		private void HideOtherPins(Minimap map)
		{
			if (savedIconTypes == null && VisibleIconTypesField?.GetValue(map) is bool[] array)
			{
				savedIconTypes = (bool[])array.Clone();
				HashSet<int> hashSet = new HashSet<int> { portalPinType };
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = hashSet.Contains(i);
				}
				PinUpdateRequiredField?.SetValue(map, true);
			}
		}

		private bool CanTeleport(Player player, TeleportWorld source)
		{
			if (itemRestrictionMode.Value != ItemRestrictionMode.Always)
			{
				return ((Humanoid)player).IsTeleportable(itemRestrictionMode.Value == ItemRestrictionMode.Default && source.m_allowAllItems);
			}
			return true;
		}

		private void RestorePins()
		{
			Minimap instance = Minimap.instance;
			if (savedIconTypes == null || (Object)(object)instance == (Object)null || !(VisibleIconTypesField?.GetValue(instance) is bool[] array))
			{
				savedIconTypes = null;
				return;
			}
			Array.Copy(savedIconTypes, array, Math.Min(savedIconTypes.Length, array.Length));
			savedIconTypes = null;
			PinUpdateRequiredField?.SetValue(instance, true);
		}

		private void ClosePicker()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Invalid comparison between Unknown and I4
			bool num = (Object)(object)pickerSource != (Object)null;
			pickerSource = null;
			RestorePins();
			ClearPickerPins();
			if (num && (Object)(object)Minimap.instance != (Object)null && (int)Minimap.instance.m_mode == 2)
			{
				Minimap.instance.SetMapMode((MapMode)1);
			}
		}

		private void ClearPickerPins()
		{
			Minimap instance = Minimap.instance;
			foreach (PinData pickerPin in pickerPins)
			{
				if ((Object)(object)instance != (Object)null)
				{
					instance.RemovePin(pickerPin);
				}
			}
			pickerPins.Clear();
			pinToPortal.Clear();
			DestroyFavoriteList();
		}

		private void DestroyFavoriteList()
		{
			if ((Object)(object)favoriteList != (Object)null)
			{
				Object.Destroy((Object)(object)favoriteList);
				favoriteList = null;
			}
		}

		public void DrawGui()
		{
		}

		public void Shutdown()
		{
			ClosePicker();
			portals.Clear();
			current = null;
		}
	}
	internal static class PortalIconData
	{
		internal const string PngBase64 = "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";
	}
}