Decompiled source of SettingsSaver v1.0.5

BepInEx/plugins/SettingsSaver.dll

Decompiled 10 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using SimpleJSON;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("SettingsSaver")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SettingsSaver")]
[assembly: AssemblyTitle("SettingsSaver")]
[assembly: AssemblyVersion("1.0.0.0")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
[BepInPlugin("com.peak.settingssaver", "SettingsSaver", "1.0.0")]
public class SettingsSaver : BaseUnityPlugin
{
	[CompilerGenerated]
	private sealed class <FirstTimeSettingsCapture>d__10 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public SettingsSaver <>4__this;

		private int <i>5__1;

		private object <handler>5__2;

		private FieldInfo <settingsField>5__3;

		private IEnumerable <list>5__4;

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

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

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

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<handler>5__2 = null;
			<settingsField>5__3 = null;
			<list>5__4 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)"[SettingsSaver] Waiting for SettingsHandler to become ready for initial capture...");
				<i>5__1 = 0;
				break;
			case 1:
				<>1__state = -1;
				<handler>5__2 = null;
				<i>5__1++;
				break;
			}
			if (<i>5__1 < 30)
			{
				<handler>5__2 = FindSettingsHandler();
				if (<handler>5__2 != null)
				{
					<settingsField>5__3 = <handler>5__2.GetType().GetField("settings", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					object obj = <settingsField>5__3?.GetValue(<handler>5__2);
					<list>5__4 = obj as IEnumerable;
					if (<list>5__4 != null && <list>5__4.GetEnumerator().MoveNext())
					{
						<>4__this.CaptureAndSaveInitialValues(<handler>5__2);
						((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)"[SettingsSaver] Initial values captured from SettingsHandler.");
						return false;
					}
					<settingsField>5__3 = null;
					<list>5__4 = null;
				}
				<>2__current = (object)new WaitForSeconds(1f);
				<>1__state = 1;
				return true;
			}
			((BaseUnityPlugin)<>4__this).Logger.LogWarning((object)"[SettingsSaver] Failed to capture initial settings — handler never became ready.");
			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();
		}
	}

	[CompilerGenerated]
	private sealed class <MainMenuWatcher>d__9 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public SettingsSaver <>4__this;

		private object <handler>5__1;

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

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

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

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

		private bool MoveNext()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				break;
			case 1:
				<>1__state = -1;
				if (<>4__this._appliedOnce)
				{
					return false;
				}
				<handler>5__1 = FindSettingsHandler();
				if (<handler>5__1 != null)
				{
					((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)"[SettingsSaver] Detected SettingsHandler in scene, applying saved settings.");
					ApplySavedSettings(<handler>5__1);
					<>4__this._appliedOnce = true;
					return false;
				}
				<handler>5__1 = null;
				break;
			}
			<>2__current = (object)new WaitForSeconds(7f);
			<>1__state = 1;
			return true;
		}

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

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

	[CompilerGenerated]
	private sealed class <MonitorSettings>d__18 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public SettingsSaver <>4__this;

		private MonoBehaviour[] <>s__1;

		private int <>s__2;

		private MonoBehaviour <mb>5__3;

		private Type <type>5__4;

		private FieldInfo <field>5__5;

		private object <setting>5__6;

		private string <key>5__7;

		private PropertyInfo <valProp>5__8;

		private object <currentValue>5__9;

		private string <saveString>5__10;

		private string <oldVal>5__11;

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

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

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

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>s__1 = null;
			<mb>5__3 = null;
			<type>5__4 = null;
			<field>5__5 = null;
			<setting>5__6 = null;
			<key>5__7 = null;
			<valProp>5__8 = null;
			<currentValue>5__9 = null;
			<saveString>5__10 = null;
			<oldVal>5__11 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				break;
			case 1:
				<>1__state = -1;
				break;
			}
			<>s__1 = Object.FindObjectsByType<MonoBehaviour>((FindObjectsSortMode)0);
			for (<>s__2 = 0; <>s__2 < <>s__1.Length; <>s__2++)
			{
				<mb>5__3 = <>s__1[<>s__2];
				<type>5__4 = ((object)<mb>5__3).GetType();
				if (<type>5__4.Name.Contains("SettingUI"))
				{
					<field>5__5 = <type>5__4.GetField("_listeningSetting", BindingFlags.Instance | BindingFlags.NonPublic);
					if (!(<field>5__5 == null))
					{
						<setting>5__6 = <field>5__5.GetValue(<mb>5__3);
						if (<setting>5__6 != null)
						{
							<key>5__7 = <setting>5__6.GetType().Name;
							<valProp>5__8 = <setting>5__6.GetType().GetProperty("Value", BindingFlags.Instance | BindingFlags.Public);
							if (!(<valProp>5__8 == null) && <valProp>5__8.CanRead)
							{
								<currentValue>5__9 = <valProp>5__8.GetValue(<setting>5__6);
								if (<currentValue>5__9 != null)
								{
									<saveString>5__10 = (<valProp>5__8.PropertyType.IsEnum ? Enum.GetName(<valProp>5__8.PropertyType, <currentValue>5__9) : <currentValue>5__9.ToString());
									if (!<>4__this._lastKnownValues.TryGetValue(<key>5__7, out <oldVal>5__11) || <oldVal>5__11 != <saveString>5__10)
									{
										SavedSettings[<key>5__7] = <saveString>5__10;
										<>4__this._lastKnownValues[<key>5__7] = <saveString>5__10;
										<>4__this.SaveSettingsToDisk();
										((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)("[SettingsSaver] Change saved: " + <key>5__7 + " = " + <saveString>5__10));
									}
									<type>5__4 = null;
									<field>5__5 = null;
									<setting>5__6 = null;
									<key>5__7 = null;
									<valProp>5__8 = null;
									<currentValue>5__9 = null;
									<saveString>5__10 = null;
									<oldVal>5__11 = null;
									<mb>5__3 = null;
								}
							}
						}
					}
				}
			}
			<>s__1 = null;
			<>2__current = (object)new WaitForSeconds(2f);
			<>1__state = 1;
			return true;
		}

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

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

	private const string SaveFileName = "SettingsSaver.json";

	public static Dictionary<string, string> SavedSettings = new Dictionary<string, string>();

	private static SettingsSaver Instance;

	private Coroutine monitor;

	private bool _appliedOnce = false;

	private Dictionary<string, string> _lastKnownValues = new Dictionary<string, string>();

	public static string SaveFilePath => Path.Combine(Paths.ConfigPath, "SettingsSaver.json");

	private void Awake()
	{
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		((BaseUnityPlugin)this).Logger.LogInfo((object)"[SettingsSaver] Loading saved settings...");
		LoadSettingsFromDisk();
		((BaseUnityPlugin)this).Logger.LogInfo((object)("[SettingsSaver] Loaded saved settings. Ready. " + SavedSettings.Count + " settings loaded."));
		if (SavedSettings.Count == 0)
		{
			((MonoBehaviour)this).StartCoroutine(FirstTimeSettingsCapture());
		}
		((MonoBehaviour)this).StartCoroutine(MainMenuWatcher());
		new Harmony("com.peak.settingssaver").PatchAll();
	}

	[IteratorStateMachine(typeof(<MainMenuWatcher>d__9))]
	private IEnumerator MainMenuWatcher()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <MainMenuWatcher>d__9(0)
		{
			<>4__this = this
		};
	}

	[IteratorStateMachine(typeof(<FirstTimeSettingsCapture>d__10))]
	private IEnumerator FirstTimeSettingsCapture()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <FirstTimeSettingsCapture>d__10(0)
		{
			<>4__this = this
		};
	}

	private void CaptureAndSaveInitialValues(object settingsHandler)
	{
		if (!(settingsHandler.GetType().GetField("settings", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(settingsHandler) is IEnumerable enumerable))
		{
			return;
		}
		foreach (object item in enumerable)
		{
			if (item == null)
			{
				continue;
			}
			string name = item.GetType().Name;
			PropertyInfo property = item.GetType().GetProperty("Value", BindingFlags.Instance | BindingFlags.Public);
			if (property == null || !property.CanRead)
			{
				continue;
			}
			object value = property.GetValue(item);
			if (value != null)
			{
				string value2 = (property.PropertyType.IsEnum ? Enum.GetName(property.PropertyType, value) : value.ToString());
				if (!SavedSettings.ContainsKey(name))
				{
					SavedSettings[name] = value2;
					_lastKnownValues[name] = value2;
				}
			}
		}
		SaveSettingsToDisk();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"[SettingsSaver] Initial settings captured and saved.");
	}

	public static void ApplySavedSettings(object settingsHandler)
	{
		if (!(settingsHandler.GetType().GetField("settings", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(settingsHandler) is IEnumerable enumerable))
		{
			return;
		}
		foreach (object item in enumerable)
		{
			if (item == null)
			{
				continue;
			}
			string name = item.GetType().Name;
			if (!SavedSettings.TryGetValue(name, out var value))
			{
				continue;
			}
			MethodInfo[] methods = item.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			MethodInfo methodInfo = null;
			MethodInfo[] array = methods;
			foreach (MethodInfo methodInfo2 in array)
			{
				ParameterInfo[] parameters = methodInfo2.GetParameters();
				if (methodInfo2.Name == "SetValue" && parameters.Length == 3 && parameters[1].ParameterType.Name.Contains("ISettingHandler"))
				{
					methodInfo = methodInfo2;
					break;
				}
			}
			if (!(methodInfo == null))
			{
				Type parameterType = methodInfo.GetParameters()[0].ParameterType;
				object obj = null;
				try
				{
					obj = ((parameterType == typeof(int)) ? ((object)int.Parse(value)) : ((parameterType == typeof(float)) ? ((object)float.Parse(value)) : ((parameterType == typeof(bool)) ? ((object)bool.Parse(value)) : ((!parameterType.IsEnum) ? Convert.ChangeType(value, parameterType) : Enum.Parse(parameterType, value, ignoreCase: true)))));
					methodInfo.Invoke(item, new object[3] { obj, settingsHandler, false });
					item.GetType().GetMethod("ApplyValue", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(item, null);
				}
				catch
				{
				}
			}
		}
	}

	public static object FindSettingsHandler()
	{
		MonoBehaviour[] array = Object.FindObjectsByType<MonoBehaviour>((FindObjectsSortMode)0);
		foreach (MonoBehaviour val in array)
		{
			Type type = ((object)val).GetType();
			if (type.Name == "GameHandler")
			{
				object obj = type.GetProperty("SettingsHandler", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(val);
				if (obj != null)
				{
					return obj;
				}
				object obj2 = type.GetField("SettingsHandler", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(val);
				if (obj2 != null)
				{
					return obj2;
				}
			}
		}
		MonoBehaviour[] array2 = Object.FindObjectsByType<MonoBehaviour>((FindObjectsSortMode)0);
		foreach (MonoBehaviour val2 in array2)
		{
			if (((object)val2).GetType().Name.Contains("SettingsHandler"))
			{
				return val2;
			}
		}
		return null;
	}

	private void SaveSettingsToDisk()
	{
		try
		{
			JSONObject jSONObject = new JSONObject();
			foreach (KeyValuePair<string, string> savedSetting in SavedSettings)
			{
				jSONObject[savedSetting.Key] = savedSetting.Value;
			}
			File.WriteAllText(SaveFilePath, jSONObject.ToString(2));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[SettingsSaver] Saved settings to disk.");
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("[SettingsSaver] Failed to save: " + ex.Message));
		}
	}

	private void LoadSettingsFromDisk()
	{
		if (!File.Exists(SaveFilePath))
		{
			return;
		}
		try
		{
			string aJSON = File.ReadAllText(SaveFilePath);
			JSONObject asObject = JSON.Parse(aJSON).AsObject;
			SavedSettings.Clear();
			JSONNode.KeyEnumerator enumerator = asObject.Keys.GetEnumerator();
			while (enumerator.MoveNext())
			{
				string current = enumerator.Current;
				SavedSettings[current] = asObject[current];
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[SettingsSaver] Loaded saved settings.");
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("[SettingsSaver] Failed to load: " + ex.Message));
		}
	}

	public static void StartWatching()
	{
		if (Instance.monitor == null)
		{
			((BaseUnityPlugin)Instance).Logger.LogInfo((object)"[SettingsSaver] Settings menu opened. Starting watcher...");
			Instance.monitor = ((MonoBehaviour)Instance).StartCoroutine(Instance.MonitorSettings());
		}
	}

	public static void StopWatching()
	{
		if (Instance.monitor != null)
		{
			((BaseUnityPlugin)Instance).Logger.LogInfo((object)"[SettingsSaver] Settings menu closed. Stopping watcher.");
			((MonoBehaviour)Instance).StopCoroutine(Instance.monitor);
			Instance.monitor = null;
		}
	}

	[IteratorStateMachine(typeof(<MonitorSettings>d__18))]
	private IEnumerator MonitorSettings()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <MonitorSettings>d__18(0)
		{
			<>4__this = this
		};
	}
}
[HarmonyPatch(typeof(SharedSettingsMenu), "OnEnable")]
public static class PatchOnEnable
{
	[HarmonyPostfix]
	public static void OnOpen()
	{
		SettingsSaver.StartWatching();
	}
}
[HarmonyPatch(typeof(SharedSettingsMenu), "OnDisable")]
public static class PatchOnDisable
{
	[HarmonyPostfix]
	public static void OnClose()
	{
		SettingsSaver.StopWatching();
	}
}
namespace SimpleJSON
{
	public enum JSONNodeType
	{
		Array = 1,
		Object = 2,
		String = 3,
		Number = 4,
		NullValue = 5,
		Boolean = 6,
		None = 7,
		Custom = 255
	}
	public enum JSONTextMode
	{
		Compact,
		Indent
	}
	public abstract class JSONNode
	{
		public struct Enumerator
		{
			private enum Type
			{
				None,
				Array,
				Object
			}

			private Type type;

			private Dictionary<string, JSONNode>.Enumerator m_Object;

			private List<JSONNode>.Enumerator m_Array;

			public bool IsValid => type != Type.None;

			public KeyValuePair<string, JSONNode> Current
			{
				get
				{
					if (type == Type.Array)
					{
						return new KeyValuePair<string, JSONNode>(string.Empty, m_Array.Current);
					}
					if (type == Type.Object)
					{
						return m_Object.Current;
					}
					return new KeyValuePair<string, JSONNode>(string.Empty, null);
				}
			}

			public Enumerator(List<JSONNode>.Enumerator aArrayEnum)
			{
				type = Type.Array;
				m_Object = default(Dictionary<string, JSONNode>.Enumerator);
				m_Array = aArrayEnum;
			}

			public Enumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum)
			{
				type = Type.Object;
				m_Object = aDictEnum;
				m_Array = default(List<JSONNode>.Enumerator);
			}

			public bool MoveNext()
			{
				if (type == Type.Array)
				{
					return m_Array.MoveNext();
				}
				if (type == Type.Object)
				{
					return m_Object.MoveNext();
				}
				return false;
			}
		}

		public struct ValueEnumerator
		{
			private Enumerator m_Enumerator;

			public JSONNode Current => m_Enumerator.Current.Value;

			public ValueEnumerator(List<JSONNode>.Enumerator aArrayEnum)
				: this(new Enumerator(aArrayEnum))
			{
			}

			public ValueEnumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum)
				: this(new Enumerator(aDictEnum))
			{
			}

			public ValueEnumerator(Enumerator aEnumerator)
			{
				m_Enumerator = aEnumerator;
			}

			public bool MoveNext()
			{
				return m_Enumerator.MoveNext();
			}

			public ValueEnumerator GetEnumerator()
			{
				return this;
			}
		}

		public struct KeyEnumerator
		{
			private Enumerator m_Enumerator;

			public string Current => m_Enumerator.Current.Key;

			public KeyEnumerator(List<JSONNode>.Enumerator aArrayEnum)
				: this(new Enumerator(aArrayEnum))
			{
			}

			public KeyEnumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum)
				: this(new Enumerator(aDictEnum))
			{
			}

			public KeyEnumerator(Enumerator aEnumerator)
			{
				m_Enumerator = aEnumerator;
			}

			public bool MoveNext()
			{
				return m_Enumerator.MoveNext();
			}

			public KeyEnumerator GetEnumerator()
			{
				return this;
			}
		}

		public class LinqEnumerator : IEnumerator<KeyValuePair<string, JSONNode>>, IDisposable, IEnumerator, IEnumerable<KeyValuePair<string, JSONNode>>, IEnumerable
		{
			private JSONNode m_Node;

			private Enumerator m_Enumerator;

			public KeyValuePair<string, JSONNode> Current => m_Enumerator.Current;

			object IEnumerator.Current => m_Enumerator.Current;

			internal LinqEnumerator(JSONNode aNode)
			{
				m_Node = aNode;
				if (m_Node != null)
				{
					m_Enumerator = m_Node.GetEnumerator();
				}
			}

			public bool MoveNext()
			{
				return m_Enumerator.MoveNext();
			}

			public void Dispose()
			{
				m_Node = null;
				m_Enumerator = default(Enumerator);
			}

			public IEnumerator<KeyValuePair<string, JSONNode>> GetEnumerator()
			{
				return new LinqEnumerator(m_Node);
			}

			public void Reset()
			{
				if (m_Node != null)
				{
					m_Enumerator = m_Node.GetEnumerator();
				}
			}

			IEnumerator IEnumerable.GetEnumerator()
			{
				return new LinqEnumerator(m_Node);
			}
		}

		[CompilerGenerated]
		private sealed class <get_Children>d__43 : IEnumerable<JSONNode>, IEnumerable, IEnumerator<JSONNode>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private JSONNode <>2__current;

			private int <>l__initialThreadId;

			public JSONNode <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				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<JSONNode> IEnumerable<JSONNode>.GetEnumerator()
			{
				<get_Children>d__43 result;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					result = this;
				}
				else
				{
					result = new <get_Children>d__43(0)
					{
						<>4__this = <>4__this
					};
				}
				return result;
			}

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

		[CompilerGenerated]
		private sealed class <get_DeepChildren>d__45 : IEnumerable<JSONNode>, IEnumerable, IEnumerator<JSONNode>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private JSONNode <>2__current;

			private int <>l__initialThreadId;

			public JSONNode <>4__this;

			private IEnumerator<JSONNode> <>s__1;

			private JSONNode <C>5__2;

			private IEnumerator<JSONNode> <>s__3;

			private JSONNode <D>5__4;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if ((uint)(num - -4) <= 1u || num == 1)
				{
					try
					{
						if (num == -4 || num == 1)
						{
							try
							{
							}
							finally
							{
								<>m__Finally2();
							}
						}
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>s__1 = null;
				<C>5__2 = null;
				<>s__3 = null;
				<D>5__4 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					int num = <>1__state;
					if (num != 0)
					{
						if (num != 1)
						{
							return false;
						}
						<>1__state = -4;
						<D>5__4 = null;
						goto IL_00b5;
					}
					<>1__state = -1;
					<>s__1 = <>4__this.Children.GetEnumerator();
					<>1__state = -3;
					goto IL_00d7;
					IL_00b5:
					if (<>s__3.MoveNext())
					{
						<D>5__4 = <>s__3.Current;
						<>2__current = <D>5__4;
						<>1__state = 1;
						return true;
					}
					<>m__Finally2();
					<>s__3 = null;
					<C>5__2 = null;
					goto IL_00d7;
					IL_00d7:
					if (<>s__1.MoveNext())
					{
						<C>5__2 = <>s__1.Current;
						<>s__3 = <C>5__2.DeepChildren.GetEnumerator();
						<>1__state = -4;
						goto IL_00b5;
					}
					<>m__Finally1();
					<>s__1 = null;
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

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

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>s__1 != null)
				{
					<>s__1.Dispose();
				}
			}

			private void <>m__Finally2()
			{
				<>1__state = -3;
				if (<>s__3 != null)
				{
					<>s__3.Dispose();
				}
			}

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

			[DebuggerHidden]
			IEnumerator<JSONNode> IEnumerable<JSONNode>.GetEnumerator()
			{
				<get_DeepChildren>d__45 result;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					result = this;
				}
				else
				{
					result = new <get_DeepChildren>d__45(0)
					{
						<>4__this = <>4__this
					};
				}
				return result;
			}

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

		public static bool forceASCII = false;

		public static bool longAsString = false;

		public static bool allowLineComments = true;

		[ThreadStatic]
		private static StringBuilder m_EscapeBuilder;

		public abstract JSONNodeType Tag { get; }

		public virtual JSONNode this[int aIndex]
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual JSONNode this[string aKey]
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string Value
		{
			get
			{
				return "";
			}
			set
			{
			}
		}

		public virtual int Count => 0;

		public virtual bool IsNumber => false;

		public virtual bool IsString => false;

		public virtual bool IsBoolean => false;

		public virtual bool IsNull => false;

		public virtual bool IsArray => false;

		public virtual bool IsObject => false;

		public virtual bool Inline
		{
			get
			{
				return false;
			}
			set
			{
			}
		}

		public virtual IEnumerable<JSONNode> Children
		{
			[IteratorStateMachine(typeof(<get_Children>d__43))]
			get
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				<get_Children>d__43 <get_Children>d__ = new <get_Children>d__43(-2);
				<get_Children>d__.<>4__this = this;
				return <get_Children>d__;
			}
		}

		public IEnumerable<JSONNode> DeepChildren
		{
			[IteratorStateMachine(typeof(<get_DeepChildren>d__45))]
			get
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				<get_DeepChildren>d__45 <get_DeepChildren>d__ = new <get_DeepChildren>d__45(-2);
				<get_DeepChildren>d__.<>4__this = this;
				return <get_DeepChildren>d__;
			}
		}

		public IEnumerable<KeyValuePair<string, JSONNode>> Linq => new LinqEnumerator(this);

		public KeyEnumerator Keys => new KeyEnumerator(GetEnumerator());

		public ValueEnumerator Values => new ValueEnumerator(GetEnumerator());

		public virtual double AsDouble
		{
			get
			{
				double result = 0.0;
				if (double.TryParse(Value, NumberStyles.Float, CultureInfo.InvariantCulture, out result))
				{
					return result;
				}
				return 0.0;
			}
			set
			{
				Value = value.ToString(CultureInfo.InvariantCulture);
			}
		}

		public virtual int AsInt
		{
			get
			{
				return (int)AsDouble;
			}
			set
			{
				AsDouble = value;
			}
		}

		public virtual float AsFloat
		{
			get
			{
				return (float)AsDouble;
			}
			set
			{
				AsDouble = value;
			}
		}

		public virtual bool AsBool
		{
			get
			{
				bool result = false;
				if (bool.TryParse(Value, out result))
				{
					return result;
				}
				return !string.IsNullOrEmpty(Value);
			}
			set
			{
				Value = (value ? "true" : "false");
			}
		}

		public virtual long AsLong
		{
			get
			{
				long result = 0L;
				if (long.TryParse(Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out result))
				{
					return result;
				}
				return 0L;
			}
			set
			{
				Value = value.ToString(CultureInfo.InvariantCulture);
			}
		}

		public virtual ulong AsULong
		{
			get
			{
				ulong result = 0uL;
				if (ulong.TryParse(Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out result))
				{
					return result;
				}
				return 0uL;
			}
			set
			{
				Value = value.ToString(CultureInfo.InvariantCulture);
			}
		}

		public virtual JSONArray AsArray => this as JSONArray;

		public virtual JSONObject AsObject => this as JSONObject;

		internal static StringBuilder EscapeBuilder
		{
			get
			{
				if (m_EscapeBuilder == null)
				{
					m_EscapeBuilder = new StringBuilder();
				}
				return m_EscapeBuilder;
			}
		}

		public virtual void Add(string aKey, JSONNode aItem)
		{
		}

		public virtual void Add(JSONNode aItem)
		{
			Add("", aItem);
		}

		public virtual JSONNode Remove(string aKey)
		{
			return null;
		}

		public virtual JSONNode Remove(int aIndex)
		{
			return null;
		}

		public virtual JSONNode Remove(JSONNode aNode)
		{
			return aNode;
		}

		public virtual void Clear()
		{
		}

		public virtual JSONNode Clone()
		{
			return null;
		}

		public virtual bool HasKey(string aKey)
		{
			return false;
		}

		public virtual JSONNode GetValueOrDefault(string aKey, JSONNode aDefault)
		{
			return aDefault;
		}

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			WriteToStringBuilder(stringBuilder, 0, 0, JSONTextMode.Compact);
			return stringBuilder.ToString();
		}

		public virtual string ToString(int aIndent)
		{
			StringBuilder stringBuilder = new StringBuilder();
			WriteToStringBuilder(stringBuilder, 0, aIndent, JSONTextMode.Indent);
			return stringBuilder.ToString();
		}

		internal abstract void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode);

		public abstract Enumerator GetEnumerator();

		public static implicit operator JSONNode(string s)
		{
			return (s == null) ? ((JSONNode)JSONNull.CreateOrGet()) : ((JSONNode)new JSONString(s));
		}

		public static implicit operator string(JSONNode d)
		{
			return (d == null) ? null : d.Value;
		}

		public static implicit operator JSONNode(double n)
		{
			return new JSONNumber(n);
		}

		public static implicit operator double(JSONNode d)
		{
			return (d == null) ? 0.0 : d.AsDouble;
		}

		public static implicit operator JSONNode(float n)
		{
			return new JSONNumber(n);
		}

		public static implicit operator float(JSONNode d)
		{
			return (d == null) ? 0f : d.AsFloat;
		}

		public static implicit operator JSONNode(int n)
		{
			return new JSONNumber(n);
		}

		public static implicit operator int(JSONNode d)
		{
			return (!(d == null)) ? d.AsInt : 0;
		}

		public static implicit operator JSONNode(long n)
		{
			if (longAsString)
			{
				return new JSONString(n.ToString(CultureInfo.InvariantCulture));
			}
			return new JSONNumber(n);
		}

		public static implicit operator long(JSONNode d)
		{
			return (d == null) ? 0 : d.AsLong;
		}

		public static implicit operator JSONNode(ulong n)
		{
			if (longAsString)
			{
				return new JSONString(n.ToString(CultureInfo.InvariantCulture));
			}
			return new JSONNumber(n);
		}

		public static implicit operator ulong(JSONNode d)
		{
			return (d == null) ? 0 : d.AsULong;
		}

		public static implicit operator JSONNode(bool b)
		{
			return new JSONBool(b);
		}

		public static implicit operator bool(JSONNode d)
		{
			return !(d == null) && d.AsBool;
		}

		public static implicit operator JSONNode(KeyValuePair<string, JSONNode> aKeyValue)
		{
			return aKeyValue.Value;
		}

		public static bool operator ==(JSONNode a, object b)
		{
			if ((object)a == b)
			{
				return true;
			}
			bool flag = a is JSONNull || (object)a == null || a is JSONLazyCreator;
			bool flag2 = b is JSONNull || b == null || b is JSONLazyCreator;
			if (flag && flag2)
			{
				return true;
			}
			return !flag && a.Equals(b);
		}

		public static bool operator !=(JSONNode a, object b)
		{
			return !(a == b);
		}

		public override bool Equals(object obj)
		{
			return (object)this == obj;
		}

		public override int GetHashCode()
		{
			return base.GetHashCode();
		}

		internal static string Escape(string aText)
		{
			StringBuilder escapeBuilder = EscapeBuilder;
			escapeBuilder.Length = 0;
			if (escapeBuilder.Capacity < aText.Length + aText.Length / 10)
			{
				escapeBuilder.Capacity = aText.Length + aText.Length / 10;
			}
			foreach (char c in aText)
			{
				switch (c)
				{
				case '\\':
					escapeBuilder.Append("\\\\");
					continue;
				case '"':
					escapeBuilder.Append("\\\"");
					continue;
				case '\n':
					escapeBuilder.Append("\\n");
					continue;
				case '\r':
					escapeBuilder.Append("\\r");
					continue;
				case '\t':
					escapeBuilder.Append("\\t");
					continue;
				case '\b':
					escapeBuilder.Append("\\b");
					continue;
				case '\f':
					escapeBuilder.Append("\\f");
					continue;
				}
				if (c < ' ' || (forceASCII && c > '\u007f'))
				{
					ushort num = c;
					escapeBuilder.Append("\\u").Append(num.ToString("X4"));
				}
				else
				{
					escapeBuilder.Append(c);
				}
			}
			string result = escapeBuilder.ToString();
			escapeBuilder.Length = 0;
			return result;
		}

		private static JSONNode ParseElement(string token, bool quoted)
		{
			if (quoted)
			{
				return token;
			}
			if (token.Length <= 5)
			{
				string text = token.ToLower();
				if (text == "false" || text == "true")
				{
					return text == "true";
				}
				if (text == "null")
				{
					return JSONNull.CreateOrGet();
				}
			}
			if (double.TryParse(token, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
			{
				return result;
			}
			return token;
		}

		public static JSONNode Parse(string aJSON)
		{
			Stack<JSONNode> stack = new Stack<JSONNode>();
			JSONNode jSONNode = null;
			int i = 0;
			StringBuilder stringBuilder = new StringBuilder();
			string aKey = "";
			bool flag = false;
			bool flag2 = false;
			bool flag3 = false;
			for (; i < aJSON.Length; i++)
			{
				switch (aJSON[i])
				{
				case '{':
					if (flag)
					{
						stringBuilder.Append(aJSON[i]);
						break;
					}
					stack.Push(new JSONObject());
					if (jSONNode != null)
					{
						jSONNode.Add(aKey, stack.Peek());
					}
					aKey = "";
					stringBuilder.Length = 0;
					jSONNode = stack.Peek();
					flag3 = false;
					break;
				case '[':
					if (flag)
					{
						stringBuilder.Append(aJSON[i]);
						break;
					}
					stack.Push(new JSONArray());
					if (jSONNode != null)
					{
						jSONNode.Add(aKey, stack.Peek());
					}
					aKey = "";
					stringBuilder.Length = 0;
					jSONNode = stack.Peek();
					flag3 = false;
					break;
				case ']':
				case '}':
					if (flag)
					{
						stringBuilder.Append(aJSON[i]);
						break;
					}
					if (stack.Count == 0)
					{
						throw new Exception("JSON Parse: Too many closing brackets");
					}
					stack.Pop();
					if (stringBuilder.Length > 0 || flag2)
					{
						jSONNode.Add(aKey, ParseElement(stringBuilder.ToString(), flag2));
					}
					if (jSONNode != null)
					{
						jSONNode.Inline = !flag3;
					}
					flag2 = false;
					aKey = "";
					stringBuilder.Length = 0;
					if (stack.Count > 0)
					{
						jSONNode = stack.Peek();
					}
					break;
				case ':':
					if (flag)
					{
						stringBuilder.Append(aJSON[i]);
						break;
					}
					aKey = stringBuilder.ToString();
					stringBuilder.Length = 0;
					flag2 = false;
					break;
				case '"':
					flag = !flag;
					flag2 = flag2 || flag;
					break;
				case ',':
					if (flag)
					{
						stringBuilder.Append(aJSON[i]);
						break;
					}
					if (stringBuilder.Length > 0 || flag2)
					{
						jSONNode.Add(aKey, ParseElement(stringBuilder.ToString(), flag2));
					}
					flag2 = false;
					aKey = "";
					stringBuilder.Length = 0;
					flag2 = false;
					break;
				case '\n':
				case '\r':
					flag3 = true;
					break;
				case '\t':
				case ' ':
					if (flag)
					{
						stringBuilder.Append(aJSON[i]);
					}
					break;
				case '\\':
					i++;
					if (flag)
					{
						char c = aJSON[i];
						switch (c)
						{
						case 't':
							stringBuilder.Append('\t');
							break;
						case 'r':
							stringBuilder.Append('\r');
							break;
						case 'n':
							stringBuilder.Append('\n');
							break;
						case 'b':
							stringBuilder.Append('\b');
							break;
						case 'f':
							stringBuilder.Append('\f');
							break;
						case 'u':
						{
							string s = aJSON.Substring(i + 1, 4);
							stringBuilder.Append((char)int.Parse(s, NumberStyles.AllowHexSpecifier));
							i += 4;
							break;
						}
						default:
							stringBuilder.Append(c);
							break;
						}
					}
					break;
				case '/':
					if (allowLineComments && !flag && i + 1 < aJSON.Length && aJSON[i + 1] == '/')
					{
						while (++i < aJSON.Length && aJSON[i] != '\n' && aJSON[i] != '\r')
						{
						}
					}
					else
					{
						stringBuilder.Append(aJSON[i]);
					}
					break;
				default:
					stringBuilder.Append(aJSON[i]);
					break;
				case '\ufeff':
					break;
				}
			}
			if (flag)
			{
				throw new Exception("JSON Parse: Quotation marks seems to be messed up.");
			}
			if (jSONNode == null)
			{
				return ParseElement(stringBuilder.ToString(), flag2);
			}
			return jSONNode;
		}
	}
	public class JSONArray : JSONNode
	{
		[CompilerGenerated]
		private sealed class <get_Children>d__24 : IEnumerable<JSONNode>, IEnumerable, IEnumerator<JSONNode>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private JSONNode <>2__current;

			private int <>l__initialThreadId;

			public JSONArray <>4__this;

			private List<JSONNode>.Enumerator <>s__1;

			private JSONNode <N>5__2;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>s__1 = default(List<JSONNode>.Enumerator);
				<N>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>s__1 = <>4__this.m_List.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						<N>5__2 = null;
						break;
					}
					if (<>s__1.MoveNext())
					{
						<N>5__2 = <>s__1.Current;
						<>2__current = <N>5__2;
						<>1__state = 1;
						return true;
					}
					<>m__Finally1();
					<>s__1 = default(List<JSONNode>.Enumerator);
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

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

			private void <>m__Finally1()
			{
				<>1__state = -1;
				((IDisposable)<>s__1).Dispose();
			}

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

			[DebuggerHidden]
			IEnumerator<JSONNode> IEnumerable<JSONNode>.GetEnumerator()
			{
				<get_Children>d__24 result;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					result = this;
				}
				else
				{
					result = new <get_Children>d__24(0)
					{
						<>4__this = <>4__this
					};
				}
				return result;
			}

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

		private List<JSONNode> m_List = new List<JSONNode>();

		private bool inline = false;

		public override bool Inline
		{
			get
			{
				return inline;
			}
			set
			{
				inline = value;
			}
		}

		public override JSONNodeType Tag => JSONNodeType.Array;

		public override bool IsArray => true;

		public override JSONNode this[int aIndex]
		{
			get
			{
				if (aIndex < 0 || aIndex >= m_List.Count)
				{
					return new JSONLazyCreator(this);
				}
				return m_List[aIndex];
			}
			set
			{
				if (value == null)
				{
					value = JSONNull.CreateOrGet();
				}
				if (aIndex < 0 || aIndex >= m_List.Count)
				{
					m_List.Add(value);
				}
				else
				{
					m_List[aIndex] = value;
				}
			}
		}

		public override JSONNode this[string aKey]
		{
			get
			{
				return new JSONLazyCreator(this);
			}
			set
			{
				if (value == null)
				{
					value = JSONNull.CreateOrGet();
				}
				m_List.Add(value);
			}
		}

		public override int Count => m_List.Count;

		public override IEnumerable<JSONNode> Children
		{
			[IteratorStateMachine(typeof(<get_Children>d__24))]
			get
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				<get_Children>d__24 <get_Children>d__ = new <get_Children>d__24(-2);
				<get_Children>d__.<>4__this = this;
				return <get_Children>d__;
			}
		}

		public override Enumerator GetEnumerator()
		{
			return new Enumerator(m_List.GetEnumerator());
		}

		public override void Add(string aKey, JSONNode aItem)
		{
			if (aItem == null)
			{
				aItem = JSONNull.CreateOrGet();
			}
			m_List.Add(aItem);
		}

		public override JSONNode Remove(int aIndex)
		{
			if (aIndex < 0 || aIndex >= m_List.Count)
			{
				return null;
			}
			JSONNode result = m_List[aIndex];
			m_List.RemoveAt(aIndex);
			return result;
		}

		public override JSONNode Remove(JSONNode aNode)
		{
			m_List.Remove(aNode);
			return aNode;
		}

		public override void Clear()
		{
			m_List.Clear();
		}

		public override JSONNode Clone()
		{
			JSONArray jSONArray = new JSONArray();
			jSONArray.m_List.Capacity = m_List.Capacity;
			foreach (JSONNode item in m_List)
			{
				if (item != null)
				{
					jSONArray.Add(item.Clone());
				}
				else
				{
					jSONArray.Add(null);
				}
			}
			return jSONArray;
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append('[');
			int count = m_List.Count;
			if (inline)
			{
				aMode = JSONTextMode.Compact;
			}
			for (int i = 0; i < count; i++)
			{
				if (i > 0)
				{
					aSB.Append(',');
				}
				if (aMode == JSONTextMode.Indent)
				{
					aSB.AppendLine();
				}
				if (aMode == JSONTextMode.Indent)
				{
					aSB.Append(' ', aIndent + aIndentInc);
				}
				m_List[i].WriteToStringBuilder(aSB, aIndent + aIndentInc, aIndentInc, aMode);
			}
			if (aMode == JSONTextMode.Indent)
			{
				aSB.AppendLine().Append(' ', aIndent);
			}
			aSB.Append(']');
		}
	}
	public class JSONObject : JSONNode
	{
		[CompilerGenerated]
		private sealed class <get_Children>d__27 : IEnumerable<JSONNode>, IEnumerable, IEnumerator<JSONNode>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private JSONNode <>2__current;

			private int <>l__initialThreadId;

			public JSONObject <>4__this;

			private Dictionary<string, JSONNode>.Enumerator <>s__1;

			private KeyValuePair<string, JSONNode> <N>5__2;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>s__1 = default(Dictionary<string, JSONNode>.Enumerator);
				<N>5__2 = default(KeyValuePair<string, JSONNode>);
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>s__1 = <>4__this.m_Dict.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						<N>5__2 = default(KeyValuePair<string, JSONNode>);
						break;
					}
					if (<>s__1.MoveNext())
					{
						<N>5__2 = <>s__1.Current;
						<>2__current = <N>5__2.Value;
						<>1__state = 1;
						return true;
					}
					<>m__Finally1();
					<>s__1 = default(Dictionary<string, JSONNode>.Enumerator);
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

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

			private void <>m__Finally1()
			{
				<>1__state = -1;
				((IDisposable)<>s__1).Dispose();
			}

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

			[DebuggerHidden]
			IEnumerator<JSONNode> IEnumerable<JSONNode>.GetEnumerator()
			{
				<get_Children>d__27 result;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					result = this;
				}
				else
				{
					result = new <get_Children>d__27(0)
					{
						<>4__this = <>4__this
					};
				}
				return result;
			}

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

		private Dictionary<string, JSONNode> m_Dict = new Dictionary<string, JSONNode>();

		private bool inline = false;

		public override bool Inline
		{
			get
			{
				return inline;
			}
			set
			{
				inline = value;
			}
		}

		public override JSONNodeType Tag => JSONNodeType.Object;

		public override bool IsObject => true;

		public override JSONNode this[string aKey]
		{
			get
			{
				if (m_Dict.TryGetValue(aKey, out var value))
				{
					return value;
				}
				return new JSONLazyCreator(this, aKey);
			}
			set
			{
				if (value == null)
				{
					value = JSONNull.CreateOrGet();
				}
				if (m_Dict.ContainsKey(aKey))
				{
					m_Dict[aKey] = value;
				}
				else
				{
					m_Dict.Add(aKey, value);
				}
			}
		}

		public override JSONNode this[int aIndex]
		{
			get
			{
				if (aIndex < 0 || aIndex >= m_Dict.Count)
				{
					return null;
				}
				return m_Dict.ElementAt(aIndex).Value;
			}
			set
			{
				if (value == null)
				{
					value = JSONNull.CreateOrGet();
				}
				if (aIndex >= 0 && aIndex < m_Dict.Count)
				{
					string key = m_Dict.ElementAt(aIndex).Key;
					m_Dict[key] = value;
				}
			}
		}

		public override int Count => m_Dict.Count;

		public override IEnumerable<JSONNode> Children
		{
			[IteratorStateMachine(typeof(<get_Children>d__27))]
			get
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				<get_Children>d__27 <get_Children>d__ = new <get_Children>d__27(-2);
				<get_Children>d__.<>4__this = this;
				return <get_Children>d__;
			}
		}

		public override Enumerator GetEnumerator()
		{
			return new Enumerator(m_Dict.GetEnumerator());
		}

		public override void Add(string aKey, JSONNode aItem)
		{
			if (aItem == null)
			{
				aItem = JSONNull.CreateOrGet();
			}
			if (aKey != null)
			{
				if (m_Dict.ContainsKey(aKey))
				{
					m_Dict[aKey] = aItem;
				}
				else
				{
					m_Dict.Add(aKey, aItem);
				}
			}
			else
			{
				m_Dict.Add(Guid.NewGuid().ToString(), aItem);
			}
		}

		public override JSONNode Remove(string aKey)
		{
			if (!m_Dict.ContainsKey(aKey))
			{
				return null;
			}
			JSONNode result = m_Dict[aKey];
			m_Dict.Remove(aKey);
			return result;
		}

		public override JSONNode Remove(int aIndex)
		{
			if (aIndex < 0 || aIndex >= m_Dict.Count)
			{
				return null;
			}
			KeyValuePair<string, JSONNode> keyValuePair = m_Dict.ElementAt(aIndex);
			m_Dict.Remove(keyValuePair.Key);
			return keyValuePair.Value;
		}

		public override JSONNode Remove(JSONNode aNode)
		{
			try
			{
				KeyValuePair<string, JSONNode> keyValuePair = m_Dict.Where((KeyValuePair<string, JSONNode> k) => k.Value == aNode).First();
				m_Dict.Remove(keyValuePair.Key);
				return aNode;
			}
			catch
			{
				return null;
			}
		}

		public override void Clear()
		{
			m_Dict.Clear();
		}

		public override JSONNode Clone()
		{
			JSONObject jSONObject = new JSONObject();
			foreach (KeyValuePair<string, JSONNode> item in m_Dict)
			{
				jSONObject.Add(item.Key, item.Value.Clone());
			}
			return jSONObject;
		}

		public override bool HasKey(string aKey)
		{
			return m_Dict.ContainsKey(aKey);
		}

		public override JSONNode GetValueOrDefault(string aKey, JSONNode aDefault)
		{
			if (m_Dict.TryGetValue(aKey, out var value))
			{
				return value;
			}
			return aDefault;
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append('{');
			bool flag = true;
			if (inline)
			{
				aMode = JSONTextMode.Compact;
			}
			foreach (KeyValuePair<string, JSONNode> item in m_Dict)
			{
				if (!flag)
				{
					aSB.Append(',');
				}
				flag = false;
				if (aMode == JSONTextMode.Indent)
				{
					aSB.AppendLine();
				}
				if (aMode == JSONTextMode.Indent)
				{
					aSB.Append(' ', aIndent + aIndentInc);
				}
				aSB.Append('"').Append(JSONNode.Escape(item.Key)).Append('"');
				if (aMode == JSONTextMode.Compact)
				{
					aSB.Append(':');
				}
				else
				{
					aSB.Append(" : ");
				}
				item.Value.WriteToStringBuilder(aSB, aIndent + aIndentInc, aIndentInc, aMode);
			}
			if (aMode == JSONTextMode.Indent)
			{
				aSB.AppendLine().Append(' ', aIndent);
			}
			aSB.Append('}');
		}
	}
	public class JSONString : JSONNode
	{
		private string m_Data;

		public override JSONNodeType Tag => JSONNodeType.String;

		public override bool IsString => true;

		public override string Value
		{
			get
			{
				return m_Data;
			}
			set
			{
				m_Data = value;
			}
		}

		public override Enumerator GetEnumerator()
		{
			return default(Enumerator);
		}

		public JSONString(string aData)
		{
			m_Data = aData;
		}

		public override JSONNode Clone()
		{
			return new JSONString(m_Data);
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append('"').Append(JSONNode.Escape(m_Data)).Append('"');
		}

		public override bool Equals(object obj)
		{
			if (base.Equals(obj))
			{
				return true;
			}
			if (obj is string text)
			{
				return m_Data == text;
			}
			JSONString jSONString = obj as JSONString;
			if (jSONString != null)
			{
				return m_Data == jSONString.m_Data;
			}
			return false;
		}

		public override int GetHashCode()
		{
			return m_Data.GetHashCode();
		}

		public override void Clear()
		{
			m_Data = "";
		}
	}
	public class JSONNumber : JSONNode
	{
		private double m_Data;

		public override JSONNodeType Tag => JSONNodeType.Number;

		public override bool IsNumber => true;

		public override string Value
		{
			get
			{
				return m_Data.ToString(CultureInfo.InvariantCulture);
			}
			set
			{
				if (double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
				{
					m_Data = result;
				}
			}
		}

		public override double AsDouble
		{
			get
			{
				return m_Data;
			}
			set
			{
				m_Data = value;
			}
		}

		public override long AsLong
		{
			get
			{
				return (long)m_Data;
			}
			set
			{
				m_Data = value;
			}
		}

		public override ulong AsULong
		{
			get
			{
				return (ulong)m_Data;
			}
			set
			{
				m_Data = value;
			}
		}

		public override Enumerator GetEnumerator()
		{
			return default(Enumerator);
		}

		public JSONNumber(double aData)
		{
			m_Data = aData;
		}

		public JSONNumber(string aData)
		{
			Value = aData;
		}

		public override JSONNode Clone()
		{
			return new JSONNumber(m_Data);
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append(Value.ToString(CultureInfo.InvariantCulture));
		}

		private static bool IsNumeric(object value)
		{
			return value is int || value is uint || value is float || value is double || value is decimal || value is long || value is ulong || value is short || value is ushort || value is sbyte || value is byte;
		}

		public override bool Equals(object obj)
		{
			if (obj == null)
			{
				return false;
			}
			if (base.Equals(obj))
			{
				return true;
			}
			JSONNumber jSONNumber = obj as JSONNumber;
			if (jSONNumber != null)
			{
				return m_Data == jSONNumber.m_Data;
			}
			if (IsNumeric(obj))
			{
				return Convert.ToDouble(obj) == m_Data;
			}
			return false;
		}

		public override int GetHashCode()
		{
			return m_Data.GetHashCode();
		}

		public override void Clear()
		{
			m_Data = 0.0;
		}
	}
	public class JSONBool : JSONNode
	{
		private bool m_Data;

		public override JSONNodeType Tag => JSONNodeType.Boolean;

		public override bool IsBoolean => true;

		public override string Value
		{
			get
			{
				return m_Data.ToString();
			}
			set
			{
				if (bool.TryParse(value, out var result))
				{
					m_Data = result;
				}
			}
		}

		public override bool AsBool
		{
			get
			{
				return m_Data;
			}
			set
			{
				m_Data = value;
			}
		}

		public override Enumerator GetEnumerator()
		{
			return default(Enumerator);
		}

		public JSONBool(bool aData)
		{
			m_Data = aData;
		}

		public JSONBool(string aData)
		{
			Value = aData;
		}

		public override JSONNode Clone()
		{
			return new JSONBool(m_Data);
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append(m_Data ? "true" : "false");
		}

		public override bool Equals(object obj)
		{
			if (obj == null)
			{
				return false;
			}
			if (obj is bool)
			{
				return m_Data == (bool)obj;
			}
			return false;
		}

		public override int GetHashCode()
		{
			return m_Data.GetHashCode();
		}

		public override void Clear()
		{
			m_Data = false;
		}
	}
	public class JSONNull : JSONNode
	{
		private static JSONNull m_StaticInstance = new JSONNull();

		public static bool reuseSameInstance = true;

		public override JSONNodeType Tag => JSONNodeType.NullValue;

		public override bool IsNull => true;

		public override string Value
		{
			get
			{
				return "null";
			}
			set
			{
			}
		}

		public override bool AsBool
		{
			get
			{
				return false;
			}
			set
			{
			}
		}

		public static JSONNull CreateOrGet()
		{
			if (reuseSameInstance)
			{
				return m_StaticInstance;
			}
			return new JSONNull();
		}

		private JSONNull()
		{
		}

		public override Enumerator GetEnumerator()
		{
			return default(Enumerator);
		}

		public override JSONNode Clone()
		{
			return CreateOrGet();
		}

		public override bool Equals(object obj)
		{
			if ((object)this == obj)
			{
				return true;
			}
			return obj is JSONNull;
		}

		public override int GetHashCode()
		{
			return 0;
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append("null");
		}
	}
	internal class JSONLazyCreator : JSONNode
	{
		private JSONNode m_Node = null;

		private string m_Key = null;

		public override JSONNodeType Tag => JSONNodeType.None;

		public override JSONNode this[int aIndex]
		{
			get
			{
				return new JSONLazyCreator(this);
			}
			set
			{
				Set(new JSONArray()).Add(value);
			}
		}

		public override JSONNode this[string aKey]
		{
			get
			{
				return new JSONLazyCreator(this, aKey);
			}
			set
			{
				Set(new JSONObject()).Add(aKey, value);
			}
		}

		public override int AsInt
		{
			get
			{
				Set(new JSONNumber(0.0));
				return 0;
			}
			set
			{
				Set(new JSONNumber(value));
			}
		}

		public override float AsFloat
		{
			get
			{
				Set(new JSONNumber(0.0));
				return 0f;
			}
			set
			{
				Set(new JSONNumber(value));
			}
		}

		public override double AsDouble
		{
			get
			{
				Set(new JSONNumber(0.0));
				return 0.0;
			}
			set
			{
				Set(new JSONNumber(value));
			}
		}

		public override long AsLong
		{
			get
			{
				if (JSONNode.longAsString)
				{
					Set(new JSONString("0"));
				}
				else
				{
					Set(new JSONNumber(0.0));
				}
				return 0L;
			}
			set
			{
				if (JSONNode.longAsString)
				{
					Set(new JSONString(value.ToString(CultureInfo.InvariantCulture)));
				}
				else
				{
					Set(new JSONNumber(value));
				}
			}
		}

		public override ulong AsULong
		{
			get
			{
				if (JSONNode.longAsString)
				{
					Set(new JSONString("0"));
				}
				else
				{
					Set(new JSONNumber(0.0));
				}
				return 0uL;
			}
			set
			{
				if (JSONNode.longAsString)
				{
					Set(new JSONString(value.ToString(CultureInfo.InvariantCulture)));
				}
				else
				{
					Set(new JSONNumber(value));
				}
			}
		}

		public override bool AsBool
		{
			get
			{
				Set(new JSONBool(aData: false));
				return false;
			}
			set
			{
				Set(new JSONBool(value));
			}
		}

		public override JSONArray AsArray => Set(new JSONArray());

		public override JSONObject AsObject => Set(new JSONObject());

		public override Enumerator GetEnumerator()
		{
			return default(Enumerator);
		}

		public JSONLazyCreator(JSONNode aNode)
		{
			m_Node = aNode;
			m_Key = null;
		}

		public JSONLazyCreator(JSONNode aNode, string aKey)
		{
			m_Node = aNode;
			m_Key = aKey;
		}

		private T Set<T>(T aVal) where T : JSONNode
		{
			if (m_Key == null)
			{
				m_Node.Add(aVal);
			}
			else
			{
				m_Node.Add(m_Key, aVal);
			}
			m_Node = null;
			return aVal;
		}

		public override void Add(JSONNode aItem)
		{
			Set(new JSONArray()).Add(aItem);
		}

		public override void Add(string aKey, JSONNode aItem)
		{
			Set(new JSONObject()).Add(aKey, aItem);
		}

		public static bool operator ==(JSONLazyCreator a, object b)
		{
			if (b == null)
			{
				return true;
			}
			return (object)a == b;
		}

		public static bool operator !=(JSONLazyCreator a, object b)
		{
			return !(a == b);
		}

		public override bool Equals(object obj)
		{
			if (obj == null)
			{
				return true;
			}
			return (object)this == obj;
		}

		public override int GetHashCode()
		{
			return 0;
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append("null");
		}
	}
	public static class JSON
	{
		public static JSONNode Parse(string aJSON)
		{
			return JSONNode.Parse(aJSON);
		}
	}
}