Decompiled source of PeakTcnPatch v1.5.9

ue.Peak.TcnPatch.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using TMPro;
using UnityEngine;
using ue.Peak.TcnPatch.API;
using ue.Peak.TcnPatch.Adapters;
using ue.Peak.TcnPatch.Core;
using ue.Peak.TcnPatch.Patches;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ue.Peak.TcnPatch")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.5.7.0")]
[assembly: AssemblyInformationalVersion("1.5.7+f18aa2db01aa6a7fdec69e36501c754efe6d1844")]
[assembly: AssemblyProduct("ue.Peak.TcnPatch")]
[assembly: AssemblyTitle("ue.Peak.TcnPatch")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.5.7.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class ExtensionMarkerAttribute : Attribute
	{
		public ExtensionMarkerAttribute(string name)
		{
		}
	}
}
namespace ue.Peak.TcnPatch
{
	[BepInPlugin("ue.Peak.TcnPatch", "ue.Peak.TcnPatch", "1.5.9")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGuid = "ue.Peak.TcnPatch";

		public const string ModName = "ue.Peak.TcnPatch";

		public const string ModVersion = "1.5.9";

		private static FileSystemWatcher _watcher;

		public const string TcnTranslationFileName = "TcnTranslations.json";

		private static readonly SemaphoreSlim _lock = new SemaphoreSlim(1, 1);

		[CanBeNull]
		private Harmony _harmony;

		internal static Plugin Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		internal static TranslationFile CurrentTranslationFile { get; private set; } = new TranslationFile();


		internal static PluginConfig ModConfig { get; private set; }

		internal static bool HasOfficialTcn { get; private set; }

		internal static Dictionary<string, string> TranslationsLookup { get; } = new Dictionary<string, string>();


		internal static Dictionary<string, string> AdditionalTranslationsLookup { get; } = new Dictionary<string, string>();


		internal static Dictionary<string, string> KeyToUnlocalizedLookup { get; } = new Dictionary<string, string>();


		private void Awake()
		{
			Instance = this;
			ModConfig = new PluginConfig(((BaseUnityPlugin)this).Config);
			ModConfig.EnableAutoDumpLanguage.SettingChanged += delegate
			{
				if (ModConfig.EnableAutoDumpLanguage.Value)
				{
					LocalizedTextPatch.DumpLanguageEntries();
				}
			};
			Logger = ((BaseUnityPlugin)this).Logger;
			Logger.LogInfo((object)"正在載入模組 - ue.Peak.TcnPatch");
			if (Enum.GetValues(typeof(Language)).Cast<int>().Any((int values) => values == 10))
			{
				HasOfficialTcn = true;
			}
			if (ModConfig.DownloadFromRemote.Value)
			{
				DownloadTranslationsAsync();
			}
			_harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "ue.Peak.TcnPatch");
			ue.Peak.TcnPatch.API.TcnPatch internalInstance = ue.Peak.TcnPatch.API.TcnPatch.InternalInstance;
			internalInstance.RegisterLocalizationKey("PeakTcnPatch.Passport.Crabland", "CRABLAND");
			MoreAscentsSupport.RegisterLocalizations();
			Logger.LogInfo((object)"已載入模組 - ue.Peak.TcnPatch");
			Logger.LogInfo((object)"  + 非官方繁體中文翻譯支援模組 -- by悠依");
		}

		private void Start()
		{
			string path = Path.Combine(Paths.ConfigPath, "ue.Peak.TcnPatch");
			Directory.CreateDirectory(path);
			_watcher = new FileSystemWatcher(path, "*.json");
			_watcher.NotifyFilter = NotifyFilters.LastWrite;
			_watcher.Changed += delegate(object _, FileSystemEventArgs args)
			{
				if (args.Name == "TcnTranslations.json")
				{
					Logger.LogInfo((object)"正在更新遊戲內繁體中文翻譯資料...");
					UpdateMainTable();
				}
			};
			UpdateMainTable();
			_watcher.EnableRaisingEvents = true;
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			_lock.Dispose();
		}

		private static async Task SaveTranslationsAsync(string content)
		{
			string dir = Path.Combine(Paths.ConfigPath, "ue.Peak.TcnPatch");
			Directory.CreateDirectory(dir);
			string path = Path.Combine(dir, "TcnTranslations.json");
			await _lock.EnterScopeAsync(async delegate
			{
				FileStream targetStream = File.Open(path, FileMode.Create, FileAccess.Write);
				try
				{
					StreamWriter writer = new StreamWriter(targetStream);
					try
					{
						await writer.WriteAsync(content);
					}
					finally
					{
						if (writer != null)
						{
							await writer.DisposeAsync();
						}
					}
				}
				finally
				{
					if (targetStream != null)
					{
						await targetStream.DisposeAsync();
					}
				}
			});
		}

		private async Task DownloadTranslationsAsync()
		{
			string url = ModConfig.DownloadUrl.Value;
			Logger.LogInfo((object)"正在從遠端下載翻譯資料... (可以在模組設定停用)");
			Logger.LogInfo((object)("網址:" + url));
			using HttpClient client = new HttpClient();
			try
			{
				string content = await client.GetStringAsync(url);
				try
				{
					JObject.Parse(content);
				}
				catch (Exception ex)
				{
					Exception e2 = ex;
					Logger.LogWarning((object)"無效的遠端翻譯資料!將使用本機資料。");
					Logger.LogWarning((object)e2);
					return;
				}
				await SaveTranslationsAsync(content);
				Logger.LogInfo((object)"翻譯資料下載完成!");
			}
			catch (Exception ex)
			{
				Exception e = ex;
				Logger.LogError((object)"翻譯資料下載失敗!將使用本機資料。");
				Logger.LogError((object)e);
			}
		}

		internal static Option<string> GetVanilla(string id)
		{
			return TranslationsLookup.GetOptional(id.ToUpperInvariant());
		}

		internal static Option<string> GetRegistered(string id, Language? language)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Invalid comparison between Unknown and I4
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			Language valueOrDefault = language.GetValueOrDefault();
			if (!language.HasValue)
			{
				valueOrDefault = LocalizedText.CURRENT_LANGUAGE;
				language = valueOrDefault;
			}
			return (((int)language.GetValueOrDefault() == 10) ? AdditionalTranslationsLookup.GetOptional(id) : Option<string>.None).OrGet(() => KeyToUnlocalizedLookup.GetOptional(id));
		}

		private static void UpdateMainTable()
		{
			ControlFlow<Unit, Unit> controlFlow = _lock.EnterScope(() => TryReadFromJson("TcnTranslations.json", (Func<JObject>)(() => new JObject())).SelectMany(TranslationFile.TryDeserialize).Select((Func<TranslationFile, ControlFlow<Unit, Unit>>)delegate(TranslationFile f)
			{
				CurrentTranslationFile = f;
				return ControlFlow.Continue();
			}).SelectError((Func<Exception, ControlFlow<Unit, Unit>>)delegate(Exception ex)
			{
				if (ex is TranslationParseException ex2)
				{
					Logger.LogError((object)ex2.UserMessage);
					Logger.LogError((object)"翻譯資料分析失敗!");
				}
				else
				{
					Logger.LogError((object)"翻譯資料分析失敗!");
					Logger.LogError((object)ex);
				}
				return ControlFlow.Break();
			})
				.Branch());
			if (controlFlow.IsBreak)
			{
				return;
			}
			if (CurrentTranslationFile.Authors.Count > 0)
			{
				Logger.LogInfo((object)("翻譯資料作者:" + string.Join("、", CurrentTranslationFile.Authors)));
			}
			else
			{
				Logger.LogInfo((object)"翻譯資料作者:未知");
			}
			Dictionary<string, List<string>> mainTable = LocalizedText.mainTable;
			HashSet<string> hashSet = mainTable.Keys.ToHashSet();
			TranslationsLookup.Clear();
			AdditionalTranslationsLookup.Clear();
			string key;
			string value;
			foreach (KeyValuePair<string, string> translation in CurrentTranslationFile.Translations)
			{
				translation.Deconstruct(out key, out value);
				string text = key;
				string value2 = value;
				string text2 = text.ToUpperInvariant();
				if (TranslationsLookup.ContainsKey(text2))
				{
					Logger.LogInfo((object)("發現重複的翻譯key:「" + text + "」!已存在大寫的同名key!"));
					continue;
				}
				if (!mainTable.ContainsKey(text2) && ModConfig.WarnUnknownTranslationKeys.Value)
				{
					Logger.LogWarning((object)("正在使用未知的翻譯key:「" + text2 + "」!"));
				}
				TranslationsLookup[text2] = value2;
				hashSet.Remove(text2);
			}
			foreach (KeyValuePair<string, string> additionalTranslation in CurrentTranslationFile.AdditionalTranslations)
			{
				additionalTranslation.Deconstruct(out value, out key);
				string text3 = value;
				string value3 = key;
				AdditionalTranslationsLookup[text3] = value3;
				hashSet.Remove(text3);
			}
			HashSet<string> vanillaLocalizationKeys = LocalizedTextPatch.VanillaLocalizationKeys;
			foreach (string item in hashSet)
			{
				if (vanillaLocalizationKeys.Contains(item))
				{
					Logger.LogWarning((object)("缺少「" + item + "」翻譯key,請更新翻譯資料!"));
				}
				else if (ModConfig.WarnMissingAdditionalKeys.Value)
				{
					Logger.LogWarning((object)("*附加翻譯* 缺少「" + item + "」翻譯key!"));
				}
			}
			LocalizedText.RefreshAllText();
		}

		private static Result<T, Exception> TryReadFromJson<T>(string fileName, Func<T> defaultContent) where T : class
		{
			Result<string, Exception> result = Result.Catch(delegate
			{
				string text = Path.Combine(Paths.ConfigPath, "ue.Peak.TcnPatch");
				Directory.CreateDirectory(text);
				string text2 = Path.Combine(text, fileName);
				if (File.Exists(text2))
				{
					return text2;
				}
				string contents = JsonConvert.SerializeObject((object)defaultContent());
				File.WriteAllText(text2, contents);
				return text2;
			});
			return result.IfError(delegate(Exception e)
			{
				Logger.LogError((object)("無法初始化 JSON 設定:" + fileName));
				Logger.LogError((object)e);
			}).SelectMany<T>(DeserializeFromPath);
			Result<T, Exception> DeserializeFromPath(string path)
			{
				return Result.Catch(delegate
				{
					using FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
					using StreamReader streamReader = new StreamReader(stream);
					return JsonConvert.DeserializeObject<T>(streamReader.ReadToEnd());
				}).IfError(delegate(Exception e)
				{
					Logger.LogError((object)("無法讀取 JSON 設定:" + fileName));
					Logger.LogError((object)e);
				});
			}
		}
	}
	public class PluginConfig
	{
		public ConfigEntry<bool> DownloadFromRemote { get; } = config.Bind<bool>("Update", "DownloadFromRemote", true, "是否每次啟動都要從遠端下載最新的翻譯資料? (true: 是, false: 否)");


		public ConfigEntry<string> DownloadUrl { get; } = config.Bind<string>("Update", "DownloadUrl", "https://raw.githubusercontent.com/Yuieii/ue.Peak.TcnPatch/refs/heads/master/TcnTranslations.json", "翻譯資料的 URL");


		public ConfigEntry<Language> AutoDumpLanguage { get; } = config.Bind<Language>("Debug", "AutoDumpLanguage", (Language)9, "自動輸出官方參考翻譯時選擇的原始語言");


		public ConfigEntry<bool> EnableAutoDumpLanguage { get; } = config.Bind<bool>("Debug", "EnableAutoDumpLanguage", true, string.Join('\n', "是否自動輸出遊戲內的翻譯表以供參考", " (有 ModConfig 的話即時更改可以重新輸出)"));


		public ConfigEntry<bool> WarnUnknownTranslationKeys { get; } = config.Bind<bool>("Debug", "WarnUnknownTranslationKeys", false, "有未知的非附加翻譯key時是否觸發警告");


		public ConfigEntry<bool> WarnMissingAdditionalKeys { get; } = config.Bind<bool>("Debug", "WarnMissingAdditionalKeys", false, "有缺失的附加翻譯key時是否觸發警告");


		public ConfigEntry<LanguagePatchMode> LanguagePatchMode { get; } = config.Bind<LanguagePatchMode>("Patch", "LanguagePatchMode", ue.Peak.TcnPatch.LanguagePatchMode.InsertAfterSimplifiedChinese, "設定如何修正設定中的語言清單");


		public ConfigEntry<bool> ShowPatchCredit { get; } = config.Bind<bool>("Patch", "ShowPatchCredit", true, "在主畫面版本文字下方顯示本模組作者?");


		public ConfigEntry<bool> ShowTranslatorCredit { get; } = config.Bind<bool>("Patch", "ShowTranslatorCredit", true, "在主畫面版本文字下方顯示翻譯資料的作者?");


		public ConfigEntry<bool> ShowModVersionInPatchCredit { get; } = config.Bind<bool>("Patch", "ShowModVersionInPatchCredit", true, "在主畫面版本文字後面顯示這個模組的版本? (v1.5.9)");


		public PluginConfig(ConfigFile config)
		{
		}
	}
	public enum LanguagePatchMode
	{
		InsertAfterSimplifiedChinese,
		ReplaceEnglish,
		ReplaceSimplifiedChinese,
		Append,
		TraditionalChineseOnly
	}
	internal static class ReflectionExtensions
	{
		[SpecialName]
		public sealed class <G>$8048A6C8BE30A622530249B904B537EB<$T0>
		{
			[SpecialName]
			public static class <M>$B99A874B2F9892B4D9EADD5CC9D40768
			{
			}

			[ExtensionMarker("<M>$B99A874B2F9892B4D9EADD5CC9D40768")]
			public TValue GetReflectionFieldValue<TValue>(TypedFieldInfo<$T0, TValue> fieldInfo)
			{
				throw null;
			}

			[ExtensionMarker("<M>$B99A874B2F9892B4D9EADD5CC9D40768")]
			public void SetReflectionFieldValue<TValue>(TypedFieldInfo<$T0, TValue> fieldInfo, TValue value)
			{
				throw null;
			}
		}

		[SpecialName]
		public sealed class <G>$C0F9324A7FB6D595E082877B54F807CC
		{
			[SpecialName]
			public static class <M>$4776623D3010553C7D2AB93E76A250FB
			{
			}

			[ExtensionMarker("<M>$4776623D3010553C7D2AB93E76A250FB")]
			[CanBeNull]
			public TypedFieldInfo<TOwner, TValue> AsTyped<TOwner, TValue>()
			{
				throw null;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static TValue GetReflectionFieldValue<TOwner, TValue>(this TOwner owner, TypedFieldInfo<TOwner, TValue> fieldInfo)
		{
			return (TValue)fieldInfo.FieldInfo.GetValue(owner);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void SetReflectionFieldValue<TOwner, TValue>(this TOwner owner, TypedFieldInfo<TOwner, TValue> fieldInfo, TValue value)
		{
			fieldInfo.FieldInfo.SetValue(owner, value);
		}

		[CanBeNull]
		public static TypedFieldInfo<TOwner, TValue> AsTyped<TOwner, TValue>([CanBeNull] this FieldInfo field)
		{
			return field;
		}
	}
	public static class Refl
	{
		public static class LoadingScreenAnimation
		{
			public static TypedFieldInfo<LoadingScreenAnimation, string> LoadingString { get; } = AccessTools.Field(typeof(LoadingScreenAnimation), "loadingString");


			public static TypedFieldInfo<LoadingScreenAnimation, float> DefaultLoadingStringLength { get; } = AccessTools.Field(typeof(LoadingScreenAnimation), "defaultLoadingStringLength");

		}

		public static class LocalizedText
		{
			public static TypedFieldInfo<LocalizedText, Language> CurrentLanguage { get; } = AccessTools.Field(typeof(LocalizedText), "CURRENT_LANGUAGE");

		}

		public static class VersionString
		{
			public static TypedFieldInfo<VersionString, TextMeshProUGUI> Text { get; } = AccessTools.Field(typeof(VersionString), "m_text");

		}
	}
	public class TypedFieldInfo<TOwner, TValue>
	{
		public FieldInfo FieldInfo { get; }

		public TypedFieldInfo(FieldInfo fieldInfo)
		{
			FieldInfo = fieldInfo;
			base..ctor();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static implicit operator TypedFieldInfo<TOwner, TValue>(FieldInfo fieldInfo)
		{
			return (fieldInfo == null) ? null : new TypedFieldInfo<TOwner, TValue>(fieldInfo);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static implicit operator FieldInfo(TypedFieldInfo<TOwner, TValue> fieldInfo)
		{
			return fieldInfo?.FieldInfo;
		}

		public TValue GetStaticValue()
		{
			return (TValue)FieldInfo.GetValue(null);
		}
	}
	public class TranslationParseException : Exception
	{
		public string UserMessage { get; }

		public TranslationParseException(string message, string userMessage)
			: base(message)
		{
			UserMessage = userMessage;
		}

		public TranslationParseException(string message)
			: base(message)
		{
			UserMessage = message;
		}
	}
	public class TranslationFile
	{
		public const int CurrentFormatVersion = 0;

		public const string FormatVersionKey = "FormatVersion";

		public const string AuthorKey = "Authors";

		public const string TranslationEntriesKey = "Translations";

		public const string AdditionalTranslationEntriesKey = "AdditionalTranslations";

		public List<string> Authors { get; } = new List<string>();


		public Dictionary<string, string> Translations { get; } = new Dictionary<string, string>();


		public Dictionary<string, string> AdditionalTranslations { get; } = new Dictionary<string, string>();


		public static Result<TranslationFile, Exception> TryDeserialize(JObject obj)
		{
			return Result.Catch(() => Deserialize(obj));
		}

		public static TranslationFile Deserialize(JObject obj)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Invalid comparison between Unknown and I4
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			string[] source = new string[2] { "FormatVersion", "Translations" };
			if (!((IEnumerable<string>)source).All((Func<string, bool>)obj.ContainsKey))
			{
				return InternalDeserializeFromLegacy(obj);
			}
			TranslationFile result = new TranslationFile();
			JToken val = obj["FormatVersion"];
			if ((int)val.Type != 6)
			{
				throw new TranslationParseException($"Format version must be an integer value, found {val.Type}", "無效的格式版本!格式版本必須為一個整數!");
			}
			int num = Extensions.Value<int>((IEnumerable<JToken>)val);
			if (num > 0)
			{
				Plugin.Logger.LogWarning((object)"正在讀取過新版本的翻譯資料!可能會無法正確讀取。");
			}
			((IDictionary<string, JToken>)obj).GetOptional("Authors").IfSome(delegate(JToken authorsToken)
			{
				JArray val9 = (JArray)(object)((authorsToken is JArray) ? authorsToken : null);
				if (val9 != null)
				{
					foreach (JToken item in val9)
					{
						result.Authors.Add(Extensions.Value<string>((IEnumerable<JToken>)item));
					}
					return;
				}
				JValue val10 = (JValue)(object)((authorsToken is JValue) ? authorsToken : null);
				if (val10 != null)
				{
					result.Authors.Add(Extensions.Value<string>((IEnumerable<JToken>)val10));
				}
				else
				{
					Plugin.Logger.LogWarning((object)"無效的翻譯者資料! (Authors)");
				}
			});
			JToken val2 = obj["Translations"];
			JObject val3 = (JObject)(object)((val2 is JObject) ? val2 : null);
			if (val3 == null)
			{
				throw new TranslationParseException($"Translation entries must be an object, found {val2.Type}", "無效的翻譯資料! (Translations)");
			}
			foreach (var (key, val5) in val3)
			{
				result.Translations[key] = Extensions.Value<string>((IEnumerable<JToken>)val5);
			}
			((IDictionary<string, JToken>)obj).GetOptional("AdditionalTranslations").IfSome(delegate(JToken entries)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				JObject val6 = (JObject)(object)((entries is JObject) ? entries : null);
				if (val6 == null)
				{
					throw new TranslationParseException($"Additional translation entries must be an object, found {entries.Type}", "無效的附加翻譯資料! (AdditionalTranslations)");
				}
				List<string> list = new List<string>();
				foreach (var (text3, val8) in val6)
				{
					if (list.Contains<string>(text3, StringComparer.InvariantCultureIgnoreCase))
					{
						Plugin.Logger.LogWarning((object)("翻譯資料出現已註冊過的附加翻譯key「" + text3 + "」!新的同名翻譯將會被忽略。"));
					}
					else
					{
						list.Add(text3);
						result.AdditionalTranslations[text3] = Extensions.Value<string>((IEnumerable<JToken>)val8);
					}
				}
			});
			return result;
		}

		private static TranslationFile InternalDeserializeFromLegacy(JObject obj)
		{
			TranslationFile translationFile = new TranslationFile();
			foreach (var (key, val2) in obj)
			{
				translationFile.Translations[key] = Extensions.Value<string>((IEnumerable<JToken>)val2);
			}
			return translationFile;
		}
	}
	public static class Utils
	{
		[CompilerGenerated]
		private sealed class <DelayFramesCoroutine>d__3<T> : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TaskCompletionSource<T> source;

			public int frames;

			public Func<T> resultGetter;

			private int <i>5__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DelayFramesCoroutine>d__3(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<i>5__1 = 0;
					break;
				case 1:
					<>1__state = -1;
					<i>5__1++;
					break;
				}
				if (<i>5__1 < frames)
				{
					<>2__current = (object)new WaitForEndOfFrame();
					<>1__state = 1;
					return true;
				}
				source.SetResult(resultGetter());
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static Option<T> ToOptionUnity<T>(this T obj) where T : Object
		{
			return ((Object)(object)obj == (Object)null) ? ((Option<T>)Option.None) : Option.Some(obj);
		}

		public static Task WaitForFramesAsync(int frames)
		{
			TaskCompletionSource<bool> taskCompletionSource = new TaskCompletionSource<bool>();
			((MonoBehaviour)Plugin.Instance).StartCoroutine(DelayFramesCoroutine(taskCompletionSource, frames, () => true));
			return taskCompletionSource.Task;
		}

		public static async Task WaitForNextFrameAsync()
		{
			await WaitForFramesAsync(1);
		}

		[IteratorStateMachine(typeof(<DelayFramesCoroutine>d__3<>))]
		private static IEnumerator DelayFramesCoroutine<T>(TaskCompletionSource<T> source, int frames, Func<T> resultGetter)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DelayFramesCoroutine>d__3<T>(0)
			{
				source = source,
				frames = frames,
				resultGetter = resultGetter
			};
		}
	}
	public enum ReturnFlow
	{
		Continue,
		Break
	}
}
namespace ue.Peak.TcnPatch.Patches
{
	[HarmonyPatch]
	public class GUIManagerPatch
	{
		[HarmonyPatch(typeof(GUIManager), "Awake")]
		[HarmonyPostfix]
		private static void PatchPrompt(GUIManager __instance)
		{
			__instance.strugglePrompt.ToOptionUnity<CanvasGroup>().SelectMany((CanvasGroup g) => ((Component)g).transform.Find("PromptText").ToOptionUnity<Transform>()).SelectMany((Transform c) => ((Component)c).GetComponent<LocalizedText>().ToOptionUnity<LocalizedText>())
				.IfNone(delegate
				{
					Plugin.Logger.LogDebug((object)"!!: Failed to find the text in the Struggle prompt UI");
				})
				.IfSome(delegate(LocalizedText text)
				{
					text.autoSet = true;
					text.RefreshText();
				});
		}
	}
	[HarmonyPatch]
	public class LanguageSettingPatch
	{
		[HarmonyPatch(typeof(LanguageSetting), "GetCustomLocalizedChoices")]
		[HarmonyPostfix]
		private static void PatchLanguageChoices(LanguageSetting __instance, ref List<string> __result)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.HasOfficialTcn)
			{
				switch (Plugin.ModConfig.LanguagePatchMode.Value)
				{
				case LanguagePatchMode.ReplaceEnglish:
				case LanguagePatchMode.ReplaceSimplifiedChinese:
					break;
				case LanguagePatchMode.InsertAfterSimplifiedChinese:
				case LanguagePatchMode.Append:
				{
					int num = Enum.GetNames(typeof(Language)).Length;
					string text = LocalizedText.GetText("CURRENT_LANGUAGE", __instance.ValueToLanguage(num));
					Plugin.Logger.LogInfo((object)"正在修正設定中的語言清單...");
					__result.Add(text);
					break;
				}
				case LanguagePatchMode.TraditionalChineseOnly:
					__result = __result.Take(1).ToList();
					break;
				}
			}
		}

		[HarmonyPatch(typeof(LanguageSetting), "ValueToLanguage")]
		[HarmonyPostfix]
		private static void PatchValueToLanguage(int val, ref Language __result)
		{
			if (Plugin.HasOfficialTcn)
			{
				return;
			}
			switch (Plugin.ModConfig.LanguagePatchMode.Value)
			{
			case LanguagePatchMode.InsertAfterSimplifiedChinese:
				__result = (Language)val;
				break;
			case LanguagePatchMode.ReplaceEnglish:
				if (val == 0)
				{
					__result = (Language)10;
				}
				break;
			case LanguagePatchMode.ReplaceSimplifiedChinese:
				if (val == 9)
				{
					__result = (Language)10;
				}
				break;
			case LanguagePatchMode.Append:
			{
				int length = Enum.GetValues(typeof(Language)).Length;
				if (val == length)
				{
					__result = (Language)10;
				}
				break;
			}
			case LanguagePatchMode.TraditionalChineseOnly:
				__result = (Language)10;
				break;
			}
		}
	}
	[HarmonyPatch]
	public class LoadingScreenAnimationPatch
	{
		private static bool _loadingScreenAnimationStartTranspiled;

		[HarmonyPatch(typeof(LoadingScreenAnimation), "Start")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> PatchLoadingAnimationSwitch(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Expected O, but got Unknown
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Expected O, but got Unknown
			if (Plugin.HasOfficialTcn)
			{
				_loadingScreenAnimationStartTranspiled = true;
				return instructions;
			}
			Plugin.Logger.LogInfo((object)"正在修補 LoadingScreenAnimation.Start() 的 IL code...");
			List<CodeInstruction> list = instructions.ToList();
			int num = -1;
			int num2 = -1;
			for (int i = 0; i < list.Count; i++)
			{
				CodeInstruction val = list[i];
				if (CodeInstructionExtensions.LoadsField(val, (FieldInfo)Refl.LocalizedText.CurrentLanguage, false))
				{
					CodeInstruction val2 = list[i + 1];
					if (!(val2.opcode != OpCodes.Ldc_I4_S) && val2.operand.Equals((sbyte)9))
					{
						num = i;
						num2 = i + 3;
						break;
					}
				}
			}
			if (num == -1 || num2 == -1)
			{
				Plugin.Logger.LogWarning((object)"沒有在 LoadingScreenAnimation.Start() 找到合適的對應 branch!");
				Plugin.Logger.LogWarning((object)"無法以 IL 方式修補 LoadingScreenAnimation.Start()!將會使用 Postfix 方式修補文字。");
				return list;
			}
			Plugin.Logger.LogInfo((object)"正在插入新的 IL code...");
			CodeInstruction val3 = list[num2];
			Label label = generator.DefineLabel();
			val3.labels.Add(label);
			List<CodeInstruction> list2 = new List<CodeInstruction>();
			list2.Add(CodeInstruction.LoadField(typeof(LocalizedText), "CURRENT_LANGUAGE", false));
			list2.Add(new CodeInstruction(OpCodes.Ldc_I4_S, (object)10));
			list2.Add(new CodeInstruction(OpCodes.Beq_S, (object)label));
			List<CodeInstruction> collection = list2;
			list.InsertRange(num, collection);
			_loadingScreenAnimationStartTranspiled = true;
			return list;
		}

		[HarmonyPatch(typeof(LoadingScreenAnimation), "Start")]
		[HarmonyPostfix]
		private static void PatchLoadingAnimation(LoadingScreenAnimation __instance)
		{
			if (!_loadingScreenAnimationStartTranspiled)
			{
				string text = LocalizedText.GetText("LOADING", true);
				if (Refl.LoadingScreenAnimation.LoadingString == null)
				{
					Plugin.Logger.LogWarning((object)"Patcher 找不到欄位: LoadingScreenAnimation.loadingString");
					return;
				}
				if (Refl.LoadingScreenAnimation.DefaultLoadingStringLength == null)
				{
					Plugin.Logger.LogWarning((object)"Patcher 找不到欄位: LoadingScreenAnimation.defaultLoadingStringLength");
					return;
				}
				Plugin.Logger.LogInfo((object)"正在修正載入中動畫的文字 @ LoadingScreenAnimation.Start()...");
				string text2 = text + "..." + text + "..." + text + "..." + text + "...";
				__instance.SetReflectionFieldValue(Refl.LoadingScreenAnimation.LoadingString, text2);
				__instance.SetReflectionFieldValue(Refl.LoadingScreenAnimation.DefaultLoadingStringLength, text2.Length);
			}
		}
	}
	[HarmonyPatch]
	public class LocalizedTextPatch
	{
		private class AutoDumpRecord
		{
			public int FormatVersion { get; } = 0;


			public List<string> Authors { get; } = new List<string>();


			public Dictionary<string, string> Translations { get; }

			public Dictionary<string, string> AdditionalTranslations { get; }

			public AutoDumpRecord(Dictionary<string, string> translations, Dictionary<string, string> additionalTranslations)
			{
				Translations = translations;
				AdditionalTranslations = additionalTranslations;
				base..ctor();
			}
		}

		private static bool _autoDumpedMainTable;

		private static readonly Lazy<int> _languageCountLazy = new Lazy<int>(() => Enum.GetNames(typeof(Language)).Length);

		public static HashSet<string> VanillaLocalizationKeys { get; } = new HashSet<string>();


		[HarmonyPatch(typeof(LocalizedText), "GetText", new Type[]
		{
			typeof(string),
			typeof(bool)
		})]
		[HarmonyPrefix]
		private static void PatchGetText(string id, ref string __result, ref bool __runOriginal)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			PatchGetText(id, LocalizedText.CURRENT_LANGUAGE, ref __result, ref __runOriginal);
		}

		[HarmonyPatch(typeof(LocalizedText), "GetText", new Type[]
		{
			typeof(string),
			typeof(Language)
		})]
		[HarmonyPrefix]
		private static void PatchGetText(string id, Language language, ref string __result, ref bool __runOriginal)
		{
			//IL_000e: 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)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			(bool, string) tuple = (from result in (from result in (from result in Plugin.GetRegistered(id, language)
						where !string.IsNullOrEmpty(result.Trim())
						select result).OrGet(() => Plugin.GetRegistered(id.ToUpperInvariant(), language))
					where !string.IsNullOrEmpty(result.Trim())
					select result).OrGet(() => ((int)language != 10) ? ((Option<string>)Option.None) : Plugin.GetVanilla(id))
				where !string.IsNullOrEmpty(result.Trim())
				select (false, result)).OrElse((true, null));
			bool item = tuple.Item1;
			string item2 = tuple.Item2;
			__runOriginal = item;
			__result = item2;
			if (__runOriginal && LocalizedText.mainTable.TryGetValue(id.ToUpperInvariant(), out var value))
			{
				while (value.Count < _languageCountLazy.Value)
				{
					value.Add(string.Empty);
				}
			}
		}

		[HarmonyPatch(typeof(LocalizedText), "LoadMainTable")]
		[HarmonyPriority(800)]
		[HarmonyPostfix]
		private static void PatchLoadMainTableFirstChance()
		{
			if (VanillaLocalizationKeys.Count > 0)
			{
				foreach (string item in LocalizedText.mainTable.Keys.Where((string key) => !VanillaLocalizationKeys.Contains(key)))
				{
					LocalizedText.mainTable.Remove(item);
				}
				return;
			}
			foreach (string key in LocalizedText.mainTable.Keys)
			{
				VanillaLocalizationKeys.Add(key);
			}
		}

		[HarmonyPatch(typeof(LocalizedText), "LoadMainTable")]
		[HarmonyPriority(0)]
		[HarmonyPostfix]
		private static void PatchLoadMainTable()
		{
			if (!_autoDumpedMainTable)
			{
				_autoDumpedMainTable = true;
				if (Plugin.ModConfig.EnableAutoDumpLanguage.Value)
				{
					DumpLanguageEntries();
				}
			}
		}

		internal static void DumpLanguageEntries()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Logger.LogInfo((object)"正在自動輸出翻譯表至 _AutoTcnTranslations.json...");
			string text = Path.Combine(Paths.ConfigPath, "ue.Peak.TcnPatch");
			if (!Directory.Exists(text))
			{
				Directory.CreateDirectory(text);
			}
			string path = Path.Combine(text, "_AutoTcnTranslations.json");
			Language language = Plugin.ModConfig.AutoDumpLanguage.Value;
			Dictionary<string, string> translations = LocalizedText.mainTable.Where((KeyValuePair<string, List<string>> p) => VanillaLocalizationKeys.Contains(p.Key)).ToDictionary((KeyValuePair<string, List<string>> p) => p.Key, (KeyValuePair<string, List<string>> p) => p.Value[(int)language]);
			Dictionary<string, string> dictionary = LocalizedText.mainTable.Where((KeyValuePair<string, List<string>> p) => !VanillaLocalizationKeys.Contains(p.Key)).ToDictionary((KeyValuePair<string, List<string>> p) => p.Key, (KeyValuePair<string, List<string>> p) => p.Value[(int)language]);
			foreach (KeyValuePair<string, string> item in Plugin.KeyToUnlocalizedLookup)
			{
				item.Deconstruct(out var key, out var value);
				string key2 = key;
				string value2 = value;
				dictionary[key2] = value2;
			}
			string contents = JsonConvert.SerializeObject((object)new AutoDumpRecord(translations, dictionary), (Formatting)1);
			File.WriteAllText(path, contents);
		}
	}
	[HarmonyPatch]
	public class PassportManagerPatch
	{
		[HarmonyPatch(typeof(PassportManager), "Awake")]
		[HarmonyPostfix]
		private static void PatchCrabland(PassportManager __instance)
		{
			((Component)__instance).transform.Find("PassportUI/Canvas/Panel/Panel/BG/Text/Nationality/Text").ToOptionUnity<Transform>().IfNone(delegate
			{
				Plugin.Logger.LogDebug((object)"!!: Failed to find the Crabland text in passport UI");
			})
				.IfSome(delegate(Transform transform)
				{
					LocalizedText val = ((Component)transform).gameObject.AddComponent<LocalizedText>();
					val.index = "PeakTcnPatch.Passport.Crabland";
					val.RefreshText();
				});
		}
	}
	[HarmonyPatch]
	public class VersionStringPatch
	{
		private static bool _versionTextMissingWarned;

		[HarmonyPatch(typeof(VersionString), "Start")]
		[HarmonyPostfix]
		private static void PatchVersionStringWarnOnStart(VersionString __instance)
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			if (Refl.VersionString.Text == null)
			{
				if (!_versionTextMissingWarned)
				{
					_versionTextMissingWarned = true;
					Plugin.Logger.LogWarning((object)"VersionString: 找不到版本資訊的 m_text 欄位!");
				}
				return;
			}
			string name = ((Object)((Component)((Component)__instance).transform.GetParent()).gameObject).name;
			string name2 = ((Object)((Component)__instance).gameObject).name;
			if (name2 == "Version" && name == "MainPage")
			{
				RectTransform component = ((Component)__instance).GetComponent<RectTransform>();
				Vector2 anchoredPosition = component.anchoredPosition;
				anchoredPosition.y -= 10f;
				component.anchoredPosition = anchoredPosition;
				TypedFieldInfo<VersionString, TextMeshProUGUI> text = Refl.VersionString.Text;
				TextMeshProUGUI reflectionFieldValue = __instance.GetReflectionFieldValue(text);
				((TMP_Text)reflectionFieldValue).verticalAlignment = (VerticalAlignmentOptions)256;
			}
		}

		[HarmonyPatch(typeof(VersionString), "Update")]
		[HarmonyPostfix]
		private static void PatchVersionString(VersionString __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			if ((int)LocalizedText.CURRENT_LANGUAGE != 10 || !Plugin.ModConfig.ShowPatchCredit.Value)
			{
				return;
			}
			TypedFieldInfo<VersionString, TextMeshProUGUI> text = Refl.VersionString.Text;
			if (text == null)
			{
				return;
			}
			TextMeshProUGUI reflectionFieldValue = __instance.GetReflectionFieldValue(text);
			string text2 = "繁中翻譯by: " + string.Join("、", Plugin.CurrentTranslationFile.Authors);
			string text3 = (Plugin.ModConfig.ShowModVersionInPatchCredit.Value ? "繁中支援v1.5.9 by悠依" : "繁中支援by悠依");
			bool flag = Plugin.ModConfig.ShowTranslatorCredit.Value && Plugin.CurrentTranslationFile.Authors.Count > 0;
			string name = ((Object)((Component)((Component)__instance).transform.GetParent()).gameObject).name;
			string name2 = ((Object)((Component)__instance).gameObject).name;
			if (name2 == "Version" && name == "Logo")
			{
				string text4 = ((flag & (Math.Floor(Time.realtimeSinceStartup / 10f) % 2.0 != 0.0)) ? text2 : text3);
				((TMP_Text)reflectionFieldValue).text = ((TMP_Text)reflectionFieldValue).text + "  (" + text4 + ")";
				return;
			}
			if (name != "MainPage")
			{
				((TMP_Text)reflectionFieldValue).text = ((TMP_Text)reflectionFieldValue).text + "<br><size=70%><alpha=#88>ue.Peak.TcnPatch v1.5.9<alpha=#FF></size>";
				return;
			}
			((TMP_Text)reflectionFieldValue).text = ((TMP_Text)reflectionFieldValue).text + "<br><size=70%>" + text3 + "</size>";
			if (flag)
			{
				((TMP_Text)reflectionFieldValue).text = ((TMP_Text)reflectionFieldValue).text + "<br><size=70%>" + text2 + "</size>";
			}
		}
	}
}
namespace ue.Peak.TcnPatch.Core
{
	public static class ControlFlow
	{
		public class PartialWithBreak<T>
		{
			internal T Value { get; }

			public PartialWithBreak(T value)
			{
				Value = value;
				base..ctor();
			}

			public ControlFlow<T, TContinue> FulfillContinueType<TContinue>()
			{
				return ControlFlow<T, TContinue>.Break(Value);
			}
		}

		public class PartialWithContinue<T>
		{
			internal T Value { get; }

			public PartialWithContinue(T value)
			{
				Value = value;
				base..ctor();
			}

			public ControlFlow<TBreak, T> FulfillBreakType<TBreak>()
			{
				return ControlFlow<TBreak, T>.Continue(Value);
			}
		}

		public static PartialWithBreak<T> Break<T>(T value)
		{
			return new PartialWithBreak<T>(value);
		}

		public static PartialWithBreak<Unit> Break()
		{
			return new PartialWithBreak<Unit>(Unit.Instance);
		}

		public static PartialWithContinue<T> Continue<T>(T value)
		{
			return new PartialWithContinue<T>(value);
		}

		public static PartialWithContinue<Unit> Continue()
		{
			return new PartialWithContinue<Unit>(Unit.Instance);
		}
	}
	public abstract class ControlFlow<TBreak, TContinue>
	{
		private class BreakBranch : ControlFlow<TBreak, TContinue>
		{
			private readonly TBreak _value;

			public override bool IsBreak => true;

			public override bool IsContinue => false;

			public BreakBranch(TBreak value)
			{
				_value = value;
			}

			public override Option<TContinue> GetContinueValue()
			{
				return Option.None;
			}

			public override Result<TContinue, TBreak> ToContinueSuccess()
			{
				return Result.Error(_value);
			}

			public override ControlFlow<TBreak, TResult> SelectContinue<TResult>(Func<TContinue, TResult> transform)
			{
				return ControlFlow.Break(_value);
			}

			public override Option<TBreak> GetBreakValue()
			{
				return Option.Some(_value);
			}

			public override Result<TBreak, TContinue> ToBreakSuccess()
			{
				return Result.Success(_value);
			}

			public override ControlFlow<TResult, TContinue> SelectBreak<TResult>(Func<TBreak, TResult> transform)
			{
				return ControlFlow.Break(transform(_value));
			}
		}

		private class ContinueBranch : ControlFlow<TBreak, TContinue>
		{
			private readonly TContinue _value;

			public override bool IsBreak => false;

			public override bool IsContinue => true;

			public ContinueBranch(TContinue value)
			{
				_value = value;
			}

			public override Option<TContinue> GetContinueValue()
			{
				return Option.Some(_value);
			}

			public override Result<TContinue, TBreak> ToContinueSuccess()
			{
				return Result.Success(_value);
			}

			public override ControlFlow<TBreak, TResult> SelectContinue<TResult>(Func<TContinue, TResult> transform)
			{
				return ControlFlow.Continue(transform(_value));
			}

			public override Option<TBreak> GetBreakValue()
			{
				return Option.None;
			}

			public override Result<TBreak, TContinue> ToBreakSuccess()
			{
				return Result.Error(_value);
			}

			public override ControlFlow<TResult, TContinue> SelectBreak<TResult>(Func<TBreak, TResult> transform)
			{
				return ControlFlow.Continue(_value);
			}
		}

		public abstract bool IsBreak { get; }

		public abstract bool IsContinue { get; }

		public static ControlFlow<TBreak, TContinue> Continue(TContinue value)
		{
			return new ContinueBranch(value);
		}

		public static ControlFlow<TBreak, TContinue> Break(TBreak value)
		{
			return new BreakBranch(value);
		}

		public static implicit operator ControlFlow<TBreak, TContinue>(ControlFlow.PartialWithContinue<TContinue> part)
		{
			return new ContinueBranch(part.Value);
		}

		public static implicit operator ControlFlow<TBreak, TContinue>(ControlFlow.PartialWithBreak<TBreak> part)
		{
			return new BreakBranch(part.Value);
		}

		public abstract Option<TContinue> GetContinueValue();

		public abstract Result<TContinue, TBreak> ToContinueSuccess();

		public abstract ControlFlow<TBreak, TResult> SelectContinue<TResult>(Func<TContinue, TResult> transform);

		public abstract Option<TBreak> GetBreakValue();

		public abstract Result<TBreak, TContinue> ToBreakSuccess();

		public abstract ControlFlow<TResult, TContinue> SelectBreak<TResult>(Func<TBreak, TResult> transform);
	}
	public static class NumberExtensions
	{
		[SpecialName]
		public sealed class <G>$BA41CFE2B5EDAEB8C1B9062F59ED4D69
		{
			[SpecialName]
			public static class <M>$5DACCD576B731A5595F442DFA5E8AE24
			{
			}

			[ExtensionMarker("<M>$5DACCD576B731A5595F442DFA5E8AE24")]
			public int BitCount
			{
				[ExtensionMarker("<M>$5DACCD576B731A5595F442DFA5E8AE24")]
				get
				{
					throw null;
				}
			}

			[ExtensionMarker("<M>$5DACCD576B731A5595F442DFA5E8AE24")]
			public int GetBitCount()
			{
				throw null;
			}
		}

		public static int get_BitCount(int self)
		{
			self -= (self >>> 1) & 0x55555555;
			self = (self & 0x33333333) + ((self >>> 2) & 0x33333333);
			self = (self + (self >>> 4)) & 0xF0F0F0F;
			self += self >>> 8;
			self += self >>> 16;
			return self & 0x3F;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int GetBitCount(this int self)
		{
			return get_BitCount(self);
		}
	}
	public interface IOption
	{
		bool IsSome { get; }

		bool IsNone { get; }

		IOption<T> Cast<T>();
	}
	public interface IOption<out T> : IOption
	{
		T Unwrap();

		T Expect(string message);

		T Expect(Exception ex);

		T Expect(Func<Exception> ex);

		IOption<TResult> Select<TResult>(Func<T, TResult> selector);

		IOption<TResult> SelectMany<TResult>(Func<T, IOption<TResult>> selector);

		IOption<T> Where(Func<T, bool> predicate);
	}
	public static class Option
	{
		[StructLayout(LayoutKind.Sequential, Size = 1)]
		public struct NoneValuePlaceholder
		{
			public Option<T> FulfillType<T>()
			{
				return Option<T>.None;
			}

			public IOption FulfillType(Type type)
			{
				Type type2 = typeof(Option<>).MakeGenericType(type);
				return (IOption)Activator.CreateInstance(type2);
			}
		}

		[SpecialName]
		public sealed class <G>$74CAB2AE3CF21190BB3801A1AE8B218F<$T0>
		{
			[SpecialName]
			public static class <M>$BD89945CA7648600A6623ED9B0D34B66
			{
			}

			[ExtensionMarker("<M>$BD89945CA7648600A6623ED9B0D34B66")]
			public $T0 OrElse($T0 other)
			{
				throw null;
			}

			[ExtensionMarker("<M>$BD89945CA7648600A6623ED9B0D34B66")]
			public $T0 OrElseGet(Func<$T0> other)
			{
				throw null;
			}

			[ExtensionMarker("<M>$BD89945CA7648600A6623ED9B0D34B66")]
			public Option<$T0> SafeUnbox()
			{
				throw null;
			}
		}

		[SpecialName]
		public sealed class <G>$89F335C99AD8D0EADD6CEDDA8A8F68D2<$T0, $T1>
		{
			[SpecialName]
			public static class <M>$FB1CE76455089A4956A6AB3011B003C7
			{
			}

			[ExtensionMarker("<M>$FB1CE76455089A4956A6AB3011B003C7")]
			public (Option<$T0> First, Option<$T1> Second) Unzip()
			{
				throw null;
			}
		}

		public static NoneValuePlaceholder None => default(NoneValuePlaceholder);

		public static Option<T> Some<T>(T value)
		{
			return Option<T>.Some(value);
		}

		public static Option<T> ToOption<T>(this T? value) where T : class
		{
			return (value == null) ? Option<T>.None : Option<T>.Some(value);
		}

		public static Option<T> ToOption<T>(this T? value) where T : struct
		{
			return (!value.HasValue) ? Option<T>.None : Option<T>.Some(value.Value);
		}

		public static IOption<T> Cast<T>(this IOption self)
		{
			return (IOption<T>)self;
		}

		public static TOption Or<TOption, TValue>(this TOption self, TOption other) where TOption : IOption<TValue>
		{
			return self.IsSome ? self : other;
		}

		public static Option<T> GetOptional<T>(this IReadOnlyList<T> self, int index)
		{
			if (index < 0 || index >= self.Count)
			{
				return None;
			}
			return Some(self[index]);
		}

		public static T OrElse<T>(this IOption<T> self, T other)
		{
			return self.IsSome ? self.Unwrap() : other;
		}

		public static T OrElseGet<T>(this IOption<T> self, Func<T> other)
		{
			return self.IsSome ? self.Unwrap() : other();
		}

		public static Option<T> SafeUnbox<T>(this IOption<T> self)
		{
			if (self is Option<T> result)
			{
				return result;
			}
			return self.Select<Option<T>>(Option<T>.Some).OrElse(Option<T>.None);
		}

		public static (Option<TFirst> First, Option<TSecond> Second) Unzip<TFirst, TSecond>(this IOption<(TFirst, TSecond)> self)
		{
			return self.Select(((TFirst, TSecond) t) => (Some(t.Item1), Some(t.Item2))).OrElse((None, None));
		}
	}
	public readonly struct Option<T> : IOption<T>, IOption
	{
		[CompilerGenerated]
		private sealed class <AsEnumerable>d__25 : IEnumerable<T>, IEnumerable, IEnumerator<T>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private T <>2__current;

			private int <>l__initialThreadId;

			public Option<T> <>4__this;

			public Option<T> <>3__<>4__this;

			T IEnumerator<T>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <AsEnumerable>d__25(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if (<>4__this.IsSome)
					{
						<>2__current = <>4__this.ValueUnsafe;
						<>1__state = 1;
						return true;
					}
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<T> IEnumerable<T>.GetEnumerator()
			{
				<AsEnumerable>d__25 <AsEnumerable>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<AsEnumerable>d__ = this;
				}
				else
				{
					<AsEnumerable>d__ = new <AsEnumerable>d__25(0);
				}
				<AsEnumerable>d__.<>4__this = <>3__<>4__this;
				return <AsEnumerable>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<T>)this).GetEnumerator();
			}
		}

		public bool IsSome { get; }

		private T ValueUnsafe { get; }

		public static Option<T> None => default(Option<T>);

		public bool IsNone => !IsSome;

		private Option(T value)
		{
			IsSome = true;
			ValueUnsafe = value;
		}

		public static implicit operator Option<T>(Option.NoneValuePlaceholder _)
		{
			return None;
		}

		public static Option<T> Some(T value)
		{
			return new Option<T>(value);
		}

		public T Unwrap()
		{
			return Expect("Cannot unwrap a None value.");
		}

		public T Expect(string message)
		{
			if (!IsSome)
			{
				throw new InvalidOperationException(message);
			}
			return ValueUnsafe;
		}

		public T Expect(Exception ex)
		{
			return IsSome ? ValueUnsafe : ex.Rethrow<T>();
		}

		public T Expect(Func<Exception> ex)
		{
			return IsSome ? ValueUnsafe : ex().Rethrow<T>();
		}

		public Option<TResult> Select<TResult>(Func<T, TResult> selector)
		{
			return IsSome ? Option<TResult>.Some(selector(ValueUnsafe)) : Option<TResult>.None;
		}

		IOption<TResult> IOption<T>.Select<TResult>(Func<T, TResult> selector)
		{
			return Select(selector);
		}

		public Option<TResult> SelectMany<TResult>(Func<T, Option<TResult>> selector)
		{
			return IsSome ? selector(ValueUnsafe) : Option<TResult>.None;
		}

		IOption<TResult> IOption<T>.SelectMany<TResult>(Func<T, IOption<TResult>> selector)
		{
			Func<T, IOption<TResult>> selector2 = selector;
			return SelectMany((T t) => selector2(t).Select(Option.Some).OrElse(Option.None));
		}

		public Option<TResult> SelectMany<TSelectMany, TResult>(Func<T, Option<TSelectMany>> selector, Func<Option<T>, TSelectMany, TResult> resultSelector)
		{
			Func<Option<T>, TSelectMany, TResult> resultSelector2 = resultSelector;
			T valueUnsafe = ValueUnsafe;
			Option<T> self = this;
			return IsSome ? (from v in selector(valueUnsafe)
				select resultSelector2(self, v)) : Option<TResult>.None;
		}

		public Option<T> IfSome(Action<T> action)
		{
			if (IsSome)
			{
				action(ValueUnsafe);
			}
			return this;
		}

		public Option<T> IfNone(Action action)
		{
			if (!IsSome)
			{
				action();
			}
			return this;
		}

		public Option<T> Match(Action? None = null, Action<T>? Some = null)
		{
			if (IsSome)
			{
				Some?.Invoke(ValueUnsafe);
			}
			else
			{
				None?.Invoke();
			}
			return this;
		}

		[IteratorStateMachine(typeof(Option<>.<AsEnumerable>d__25))]
		public IEnumerable<T> AsEnumerable()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <AsEnumerable>d__25(-2)
			{
				<>3__<>4__this = this
			};
		}

		public Result<T, TError> ToSuccessOr<TError>(TError error)
		{
			TError error2 = error;
			return Select((Func<T, Result<T, TError>>)((T x) => Result.Success(x))).OrElseGet(() => Result.Error(error2));
		}

		public Option<T> Or(Option<T> other)
		{
			return IsSome ? this : other;
		}

		public Option<T> Where(Func<T, bool> predicate)
		{
			return (!IsSome) ? this : (predicate(ValueUnsafe) ? this : None);
		}

		IOption<T> IOption<T>.Where(Func<T, bool> predicate)
		{
			return Where(predicate);
		}

		public T OrElse(T other)
		{
			return (T)(IsSome ? ((object)ValueUnsafe) : ((object)other));
		}

		public Option<T> OrGet(Func<Option<T>> other)
		{
			return IsSome ? this : other();
		}

		public T OrElseGet(Func<T> other)
		{
			return IsSome ? ValueUnsafe : other();
		}

		public Option<TOut> CastOrThrow<TOut>()
		{
			return IsSome ? Option.Some((TOut)(object)ValueUnsafe) : Option<TOut>.None;
		}

		public Option<TOut> Cast<TOut>()
		{
			if (!IsSome)
			{
				return Option<TOut>.None;
			}
			T valueUnsafe = ValueUnsafe;
			Option<TOut> result;
			if (valueUnsafe is TOut)
			{
				object obj = valueUnsafe;
				TOut value = (TOut)((obj is TOut) ? obj : null);
				result = Option.Some(value);
			}
			else
			{
				result = Option.None;
			}
			return result;
		}

		IOption<TOut> IOption.Cast<TOut>()
		{
			return Cast<TOut>();
		}

		public Option<T> Xor(Option<T> other)
		{
			if (IsSome == other.IsSome)
			{
				return Option.None;
			}
			return IsSome ? this : other;
		}

		public Option<(T, TOther)> Zip<TOther>(Option<TOther> other)
		{
			if (!IsSome || !other.IsSome)
			{
				return Option.None;
			}
			return Option.Some((ValueUnsafe, other.ValueUnsafe));
		}

		public Option<TZipped> Zip<TOther, TZipped>(Option<TOther> other, Func<T, TOther, TZipped> zip)
		{
			if (!IsSome || !other.IsSome)
			{
				return Option.None;
			}
			return Option.Some(zip(ValueUnsafe, other.ValueUnsafe));
		}
	}
	public interface IResult
	{
		bool IsSuccess { get; }

		bool IsError { get; }
	}
	public interface IResultSuccess<T> : IResult
	{
		Option<T> Value { get; }

		T Unwrap();

		IResultSuccess<TResult> Select<TResult>(Func<T, TResult> transform);
	}
	public interface IResultError<T> : IResult
	{
		Option<T> Error { get; }

		T UnwrapError();

		IResultError<TResult> SelectError<TResult>(Func<T, TResult> transform);
	}
	public interface IResult<T, TError> : IResultSuccess<T>, IResult, IResultError<TError>
	{
		new IResult<TResult, TError> Select<TResult>(Func<T, TResult> transform);

		new IResult<T, TResult> SelectError<TResult>(Func<TError, TResult> transform);

		IResultSuccess<TResult> IResultSuccess<T>.Select<TResult>(Func<T, TResult> transform)
		{
			return Select(transform);
		}

		IResultError<TResult> IResultError<TError>.SelectError<TResult>(Func<TError, TResult> transform)
		{
			return SelectError(transform);
		}
	}
	public static class Result
	{
		public class PartialWithSuccess<T>
		{
			private readonly T _value;

			internal PartialWithSuccess(T value)
			{
				_value = value;
			}

			public Result<T, TError> FulfillErrorType<TError>()
			{
				return Result<T, TError>.Success(_value);
			}
		}

		public class PartialWithError<T>
		{
			private readonly T _error;

			internal PartialWithError(T error)
			{
				_error = error;
			}

			public Result<TSuccess, T> FulfillSuccessType<TSuccess>()
			{
				return Result<TSuccess, T>.Error(_error);
			}
		}

		public static PartialWithSuccess<T> Success<T>(T value)
		{
			return new PartialWithSuccess<T>(value);
		}

		public static PartialWithError<T> Error<T>(T error)
		{
			return new PartialWithError<T>(error);
		}

		public static Result<T, Exception> Catch<T>(Func<T> func)
		{
			try
			{
				return Success(func());
			}
			catch (Exception error)
			{
				return Error(error);
			}
		}

		public static T Branch<T>(this IResult<T, T> self)
		{
			return self.IsSuccess ? self.Unwrap() : self.UnwrapError();
		}

		public static Result<T, TError> SafeUnbox<T, TError, TResult>(this TResult self) where TResult : IResult<T, TError>
		{
			if ((object)self is Result<T, TError> result)
			{
				return result;
			}
			ref TResult reference = ref self;
			TResult val2 = default(TResult);
			if (val2 == null)
			{
				val2 = reference;
				reference = ref val2;
			}
			return reference.Select((T val) => Success(val).FulfillErrorType<TError>()).SelectError((TError val) => Error(val).FulfillSuccessType<T>()).Branch();
		}

		public static T UnwrapOrThrow<T, TError>(this Result<T, TError> result) where TError : Exception
		{
			Option<T> value = result.Value;
			return value.IsSome ? value.Unwrap() : result.UnwrapError().Rethrow<T>();
		}

		public static T Branch<T>(this Result<T, T> result)
		{
			return result.IsSuccess ? result.Unwrap() : result.UnwrapError();
		}

		public static T FastUnwrap<T>(this Result<T, Never> self)
		{
			return self.ValueUnsafe;
		}

		public static T FastUnwrapError<T>(this Result<Never, T> self)
		{
			return self.ErrUnsafe;
		}

		public static Result<T, TError> Flatten<T, TError>(this Result<Result<T, TError>, TError> self)
		{
			return self.SelectMany((Result<T, TError> s) => s);
		}

		public static Result<IEnumerable<TItem>, TError> Process<TItem, TError>(this IEnumerable<Result<TItem, TError>> enumerable)
		{
			IEnumerable<TItem> enumerable2 = Enumerable.Empty<TItem>();
			foreach (Result<TItem, TError> item in enumerable)
			{
				if (item.IsError)
				{
					return Error(item.UnwrapError());
				}
				enumerable2 = enumerable2.Append(item.Unwrap());
			}
			return Success(enumerable2);
		}
	}
	public abstract class Result<T, TError> : IResult<T, TError>, IResultSuccess<T>, IResult, IResultError<TError>, IEquatable<Result<T, TError>>
	{
		private class SuccessBranch : Result<T, TError>
		{
			public new T Value { get; }

			internal SuccessBranch(T value)
			{
				Value = value;
			}

			public override Result<TResult, TError> Select<TResult>(Func<T, TResult> func)
			{
				return Result.Success(func(Value));
			}

			public override Result<TResult, TError> SelectMany<TResult>(Func<T, Result<TResult, TError>> func)
			{
				return func(Value);
			}

			public override Result<T, TErrorResult> SelectError<TErrorResult>(Func<TError, TErrorResult> func)
			{
				return Result.Success(Value);
			}

			public override Result<T, TError> IfSuccess(Action<T> action)
			{
				action(Value);
				return this;
			}

			public override Result<T, TError> IfError(Action<TError> action)
			{
				return this;
			}
		}

		private class ErrorBranch : Result<T, TError>
		{
			public new TError Error { get; }

			internal ErrorBranch(TError error)
			{
				Error = error;
			}

			public override Result<TResult, TError> Select<TResult>(Func<T, TResult> func)
			{
				return Result.Error(Error);
			}

			public override Result<TResult, TError> SelectMany<TResult>(Func<T, Result<TResult, TError>> func)
			{
				return Result.Error(Error);
			}

			public override Result<T, TErrorResult> SelectError<TErrorResult>(Func<TError, TErrorResult> func)
			{
				return Result.Error(func(Error));
			}

			public override Result<T, TError> IfSuccess(Action<T> action)
			{
				return this;
			}

			public override Result<T, TError> IfError(Action<TError> action)
			{
				action(Error);
				return this;
			}
		}

		public bool IsSuccess => this is SuccessBranch;

		public bool IsError => this is ErrorBranch;

		internal T ValueUnsafe => ((SuccessBranch)this).Value;

		internal TError ErrUnsafe => ((ErrorBranch)this).Error;

		public Option<T> Value => (this is SuccessBranch successBranch) ? Option<T>.Some(successBranch.Value) : Option<T>.None;

		public Option<TError> Err => (this is ErrorBranch errorBranch) ? Option<TError>.Some(errorBranch.Error) : Option<TError>.None;

		Option<TError> IResultError<TError>.Error => Err;

		internal Result()
		{
		}

		public static implicit operator Result<T, TError>(Result.PartialWithSuccess<T> partial)
		{
			return partial.FulfillErrorType<TError>();
		}

		public static implicit operator Result<T, TError>(Result.PartialWithError<TError> partial)
		{
			return partial.FulfillSuccessType<T>();
		}

		public T Unwrap()
		{
			return Value.Expect("Cannot unwrap a success value from an Error branch.");
		}

		public TError UnwrapError()
		{
			return Err.Expect("Cannot unwrap an error value from a Success branch.");
		}

		public abstract Result<TResult, TError> Select<TResult>(Func<T, TResult> func);

		IResult<TResult, TError> IResult<T, TError>.Select<TResult>(Func<T, TResult> transform)
		{
			return Select(transform);
		}

		public abstract Result<TResult, TError> SelectMany<TResult>(Func<T, Result<TResult, TError>> func);

		public Result<TResult, TError> SelectMany<TMiddle, TResult>(Func<T, Result<TMiddle, TError>> func, Func<Result<T, TError>, TMiddle, TResult> resultSelector)
		{
			Func<Result<T, TError>, TMiddle, TResult> resultSelector2 = resultSelector;
			return IsError ? ((Result<TResult, TError>)Result.Error(ErrUnsafe)) : (from m in func(ValueUnsafe)
				select resultSelector2(this, m));
		}

		public abstract Result<T, TErrorResult> SelectError<TErrorResult>(Func<TError, TErrorResult> func);

		IResult<T, TResult> IResult<T, TError>.SelectError<TResult>(Func<TError, TResult> transform)
		{
			return SelectError(transform);
		}

		public abstract Result<T, TError> IfSuccess(Action<T> action);

		public abstract Result<T, TError> IfError(Action<TError> action);

		public IEnumerable<T> AsEnumerable()
		{
			return Value.AsEnumerable();
		}

		public bool TryUnwrap([MaybeNullWhen(false)] out T value)
		{
			if (IsSuccess)
			{
				value = ValueUnsafe;
				return true;
			}
			value = default(T);
			return false;
		}

		public bool TryUnwrapError([MaybeNullWhen(false)] out TError error)
		{
			if (IsError)
			{
				error = ErrUnsafe;
				return true;
			}
			error = default(TError);
			return false;
		}

		public static Result<T, TError> Success(T value)
		{
			return new SuccessBranch(value);
		}

		public static Result<T, TError> Error(TError error)
		{
			return new ErrorBranch(error);
		}

		public bool Equals(Result<T, TError>? other)
		{
			if ((object)other == null)
			{
				return false;
			}
			if (IsSuccess != other.IsSuccess)
			{
				return false;
			}
			return IsSuccess ? ValueUnsafe.Equals(other.ValueUnsafe) : ErrUnsafe.Equals(other.ErrUnsafe);
		}

		public override bool Equals(object? obj)
		{
			return this == obj || (obj is Result<T, TError> other && Equals(other));
		}

		public override int GetHashCode()
		{
			return IsSuccess ? HashCode.Combine(value1: true, ValueUnsafe) : HashCode.Combine(value1: false, ErrUnsafe);
		}

		public static bool operator ==(Result<T, TError>? left, Result<T, TError>? right)
		{
			return object.Equals(left, right);
		}

		public static bool operator !=(Result<T, TError>? left, Result<T, TError>? right)
		{
			return !object.Equals(left, right);
		}
	}
	public abstract class ScopeGuard : IDisposable
	{
		protected virtual bool ShouldEndScope => true;

		protected abstract void EndScope();

		public void Dispose()
		{
			if (ShouldEndScope)
			{
				EndScope();
			}
		}
	}
	public class DelegateScopeGuard : ScopeGuard
	{
		private readonly Action _endScope;

		private DelegateScopeGuard(Action endScope)
		{
			_endScope = endScope;
		}

		protected override void EndScope()
		{
			_endScope();
		}
	}
	public class SemaphoreSlimGuard : ScopeGuard
	{
		private readonly SemaphoreSlim _semaphore;

		private SemaphoreSlimGuard(SemaphoreSlim semaphore)
		{
			_semaphore = semaphore;
		}

		public static SemaphoreSlimGuard Create(SemaphoreSlim semaphore)
		{
			semaphore.Wait();
			return new SemaphoreSlimGuard(semaphore);
		}

		public static async Task<SemaphoreSlimGuard> CreateAsync(SemaphoreSlim semaphore)
		{
			await semaphore.WaitAsync();
			return new SemaphoreSlimGuard(semaphore);
		}

		protected override void EndScope()
		{
			_semaphore.Release();
		}
	}
	public enum Never
	{

	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	public struct Unit
	{
		public static Unit Instance => default(Unit);
	}
	public static class Utils
	{
		[SpecialName]
		public sealed class <G>$B121A579F9C62187B81C2CC9A1D05898
		{
			[SpecialName]
			public static class <M>$9A581DD593152A881C02B7BBD540726C
			{
			}

			[ExtensionMarker("<M>$9A581DD593152A881C02B7BBD540726C")]
			public Task<IDisposable> CreateScopeAsync()
			{
				throw null;
			}

			[ExtensionMarker("<M>$9A581DD593152A881C02B7BBD540726C")]
			public IDisposable CreateScope()
			{
				throw null;
			}

			[ExtensionMarker("<M>$9A581DD593152A881C02B7BBD540726C")]
			public void EnterScope(Action action)
			{
				throw null;
			}

			[ExtensionMarker("<M>$9A581DD593152A881C02B7BBD540726C")]
			public T EnterScope<T>(Func<T> func)
			{
				throw null;
			}

			[ExtensionMarker("<M>$9A581DD593152A881C02B7BBD540726C")]
			public Task EnterScopeAsync(Action action)
			{
				throw null;
			}

			[ExtensionMarker("<M>$9A581DD593152A881C02B7BBD540726C")]
			public Task<T> EnterScopeAsync<T>(Func<T> func)
			{
				throw null;
			}

			[ExtensionMarker("<M>$9A581DD593152A881C02B7BBD540726C")]
			public Task EnterScopeAsync(Func<Task> action)
			{
				throw null;
			}

			[ExtensionMarker("<M>$9A581DD593152A881C02B7BBD540726C")]
			public Task<T> EnterScopeAsync<T>(Func<Task<T>> action)
			{
				throw null;
			}
		}

		[SpecialName]
		public sealed class <G>$6A188C7A03CB85FC44DF3FD030EA0664
		{
			[SpecialName]
			public static class <M>$438D5453E0DFEE874C985587A0074FB9
			{
			}

			[ExtensionMarker("<M>$438D5453E0DFEE874C985587A0074FB9")]
			[DoesNotReturn]
			public Never Rethrow()
			{
				throw null;
			}

			[ExtensionMarker("<M>$438D5453E0DFEE874C985587A0074FB9")]
			[DoesNotReturn]
			public T Rethrow<T>()
			{
				throw null;
			}
		}

		public static Option<TValue> GetOptional<TKey, TValue>(this IDictionary<TKey, TValue> dict, TKey key)
		{
			TValue value;
			return dict.TryGetValue(key, out value) ? Option.Some(value) : Option<TValue>.None;
		}

		private static Result<Unit, AggregateException> SafeInvokeInternal<T>(T? self, Action<T> invoke) where T : Delegate
		{
			if ((Delegate?)self == (Delegate?)null)
			{
				return Result.Success(Unit.Instance);
			}
			Lazy<List<Exception>> lazy = new Lazy<List<Exception>>(() => new List<Exception>());
			foreach (T item2 in self.GetInvocationList().Cast<T>())
			{
				try
				{
					invoke(item2);
				}
				catch (Exception item)
				{
					lazy.Value.Add(item);
				}
			}
			if (lazy.IsValueCreated)
			{
				return Result.Error(new AggregateException("One or more exceptions occured while safe-invoking the delegate.", lazy.Value));
			}
			return Result.Success(Unit.Instance);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Result<Unit, AggregateException> SafeInvoke(this Action? self)
		{
			return SafeInvokeInternal(self, delegate(Action a)
			{
				a();
			});
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Result<Unit, AggregateException> SafeInvoke<T>(this Action<T>? self, T arg)
		{
			T arg2 = arg;
			return SafeInvokeInternal(self, delegate(Action<T> a)
			{
				a(arg2);
			});
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Result<Unit, AggregateException> SafeInvoke<T1, T2>(this Action<T1, T2>? self, T1 arg1, T2 arg2)
		{
			T1 arg3 = arg1;
			T2 arg4 = arg2;
			return SafeInvokeInternal(self, delegate(Action<T1, T2> a)
			{
				a(arg3, arg4);
			});
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static async Task<IDisposable> CreateScopeAsync(this SemaphoreSlim semaphore)
		{
			return await SemaphoreSlimGuard.CreateAsync(semaphore);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static IDisposable CreateScope(this SemaphoreSlim semaphore)
		{
			return SemaphoreSlimGuard.Create(semaphore);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void EnterScope(this SemaphoreSlim semaphore, Action action)
		{
			using (semaphore.CreateScope())
			{
				action();
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static T EnterScope<T>(this SemaphoreSlim semaphore, Func<T> func)
		{
			using (semaphore.CreateScope())
			{
				return func();
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static async Task EnterScopeAsync(this SemaphoreSlim semaphore, Action action)
		{
			using (await semaphore.CreateScopeAsync())
			{
				action();
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static async Task<T> EnterScopeAsync<T>(this SemaphoreSlim semaphore, Func<T> func) where T : notnull
		{
			using (await semaphore.CreateScopeAsync())
			{
				return func();
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static async Task EnterScopeAsync(this SemaphoreSlim semaphore, Func<Task> action)
		{
			using (await semaphore.CreateScopeAsync())
			{
				await action();
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static async Task<T> EnterScopeAsync<T>(this SemaphoreSlim semaphore, Func<Task<T>> action) where T : notnull
		{
			using (await semaphore.CreateScopeAsync())
			{
				return await action();
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[DoesNotReturn]
		public static Never Rethrow(this Exception ex)
		{
			return ex.Rethrow<Never>();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[DoesNotReturn]
		public static T Rethrow<T>(this Exception ex)
		{
			ExceptionDispatchInfo.Capture(ex).Throw();
			return default(T);
		}
	}
}
namespace ue.Peak.TcnPatch.API
{
	public interface ITcnPatch
	{
		void RegisterLocalizationKey(string key, string unlocalized);
	}
	public class TcnPatch : ITcnPatch
	{
		public static ITcnPatch Instance => InternalInstance;

		internal static TcnPatch InternalInstance { get; } = new TcnPatch();


		public void RegisterLocalizationKey(string key, string unlocalized)
		{
			Plugin.KeyToUnlocalizedLookup[key] = unlocalized;
		}
	}
}
namespace ue.Peak.TcnPatch.Adapters
{
	public static class MoreAscentsSupport
	{
		private class ReflectionFailedError
		{
			[CompilerGenerated]
			[DebuggerBrowsable(DebuggerBrowsableState.Never)]
			private Action <showWarning>P;

			public ReflectionFailedError(Action showWarning)
			{
				<showWarning>P = showWarning;
				base..ctor();
			}

			public void ShowWarning()
			{
				<showWarning>P();
			}
		}

		private static readonly Lazy<Type> _gimmickHandlerType = new Lazy<Type>(() => Type.GetType("MoreAscents.AscentGimmickHandler"));

		private static bool _addedSupport;

		public static bool IsMoreAscentsInstalled => _gimmickHandlerType.Value != null;

		private static Type GimmickHandlerType => _gimmickHandlerType.Value;

		public static void RegisterLocalizations()
		{
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Expected O, but got Unknown
			if (!IsMoreAscentsInstalled)
			{
				return;
			}
			TypedFieldInfo<object, bool> typedFieldInfo = AccessTools.Field(GimmickHandlerType, "HasInitialized").AsTyped<object, bool>();
			if (typedFieldInfo == null)
			{
				return;
			}
			if (!typedFieldInfo.GetStaticValue())
			{
				Plugin.Logger.LogWarning((object)"MoreAscents 還沒初始化!?");
			}
			else
			{
				if (_addedSupport)
				{
					return;
				}
				_addedSupport = true;
				Plugin.Logger.LogInfo((object)"偵測到 MoreAscents!正在為 MoreAscents 提供繁中支援...");
				try
				{
					if (!FindType("MoreAscents.AscentGimmick").IfError(delegate(ReflectionFailedError e)
					{
						e.ShowWarning();
					}).TryUnwrap(out var value) || !FindMethod(value, "GetTitle").IfError(delegate(ReflectionFailedError e)
					{
						e.ShowWarning();
					}).TryUnwrap(out var gimmickGetTitleMethod) || !FindMethod(value, "GetDescription").IfError(delegate(ReflectionFailedError e)
					{
						e.ShowWarning();
					}).TryUnwrap(out var gimmickGetDescriptionMethod) || !FindMethod(value, "GetTitleReward").IfError(delegate(ReflectionFailedError e)
					{
						e.ShowWarning();
					}).TryUnwrap(out var value2) || !FindField(GimmickHandlerType, "gimmicks").IfError(delegate(ReflectionFailedError e)
					{
						e.ShowWarning();
					}).TryUnwrap(out var value3))
					{
						return;
					}
					IReadOnlyList<object> readOnlyList = (IReadOnlyList<object>)value3.GetValue(null);
					MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(AscentData), "Instance");
					AscentData val = (AscentData)methodInfo.Invoke(null, Array.Empty<object>());
					List<AscentInstanceData> ascents = val.ascents;
					foreach (object gimmick in readOnlyList)
					{
						AscentInstanceData val2 = ((IEnumerable<AscentInstanceData>)ascents).FirstOrDefault((Func<AscentInstanceData, bool>)((AscentInstanceData d) => d.title == (string)gimmickGetTitleMethod.Invoke(gimmick, Array.Empty<object>()) && d.description == (string)gimmickGetDescriptionMethod.Invoke(gimmick, Array.Empty<object>())));
						if (val2 != null)
						{
							string text = (val2.title = "MoreAscent." + gimmick.GetType().Name);
							val2.titleReward = text + ".Reward";
							ue.Peak.TcnPatch.API.TcnPatch.Instance.RegisterLocalizationKey(text ?? "", (string)gimmickGetTitleMethod.Invoke(gimmick, Array.Empty<object>()));
							ue.Peak.TcnPatch.API.TcnPatch.Instance.RegisterLocalizationKey(LocalizedText.GetDescriptionIndex(text), (string)gimmickGetDescriptionMethod.Invoke(gimmick, Array.Empty<object>()));
							ue.Peak.TcnPatch.API.TcnPatch.Instance.RegisterLocalizationKey(text + ".Reward", (string)value2.Invoke(gimmick, Array.Empty<object>()));
						}
					}
				}
				catch (Exception ex)
				{
					Plugin.Logger.LogError((object)"無法為 MoreAscents 提供繁中支援... x_x");
					Plugin.Logger.LogError((object)ex);
				}
			}
			static Result<FieldInfo, ReflectionFailedError> FindField(Type type, string fieldName)
			{
				FieldInfo fieldInfo = AccessTools.Field(type, fieldName);
				if (fieldInfo != null)
				{
					return Result.Success(fieldInfo);
				}
				return Result.Error(new ReflectionFailedError(delegate
				{
					Plugin.Logger.LogWarning((object)("無法找到 " + type.Name + "." + fieldName + " 欄位!無法為 MoreAscents 提供繁中支援... x_x"));
				}));
			}
			static Result<MethodInfo, ReflectionFailedError> FindMethod(Type type, string methodName)
			{
				MethodInfo methodInfo2 = AccessTools.Method(type, methodName, (Type[])null, (Type[])null);
				if (methodInfo2 != null)
				{
					return Result.Success(methodInfo2);
				}
				return Result.Error(new ReflectionFailedError(delegate
				{
					Plugin.Logger.LogWarning((object)("無法找到 " + type.Name + "." + methodName + "() 方法!無法為 MoreAscents 提供繁中支援... x_x"));
				}));
			}
			static Result<Type, ReflectionFailedError> FindType(string typeName)
			{
				Type type2 = AccessTools.TypeByName(typeName);
				if (type2 != null)
				{
					return Result.Success(type2);
				}
				return Result.Error(new ReflectionFailedError(delegate
				{
					Plugin.Logger.LogWarning((object)("無法找到 " + typeName + " 類型!無法為 MoreAscents 提供繁中支援... x_x"));
				}));
			}
		}
	}
}