Decompiled source of SullysAutoPinner v1.3.2

BepInEx/plugins/SullysAutoPinner.dll

Decompiled a week 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.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using SimpleJSON;
using Splatform;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("SullysAutoPinner")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SullysAutoPinner")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("53eb7460-cf9b-4412-b6f9-0c7191329f58")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.2.0.0")]
[BepInPlugin("sullys.autopinner", "Sullys Auto Pinner", "1.3.1")]
public class SullysAutoPinner : BaseUnityPlugin
{
	private PinSettings _settings;

	private PinManager _pinManager;

	private ConfigLoader _configLoader;

	private PinScanner _scanner;

	private PrefabTracker _prefabTracker;

	private float _lastScanTime;

	private LocalizationManager _localizationManager;

	private void Awake()
	{
		_configLoader = new ConfigLoader(((BaseUnityPlugin)this).Logger);
		_settings = _configLoader.Load();
		LocalizationManager.EnsureBaseLanguageFiles(((BaseUnityPlugin)this).Logger);
		_localizationManager = new LocalizationManager(((BaseUnityPlugin)this).Logger, _settings.LanguageCode);
		_pinManager = new PinManager(_settings, ((BaseUnityPlugin)this).Logger, _localizationManager);
		_prefabTracker = new PrefabTracker(((BaseUnityPlugin)this).Logger, _settings);
		_scanner = new PinScanner(_settings, _pinManager, _prefabTracker);
		_configLoader.EnableHotReload(delegate
		{
			_settings = _configLoader.Load();
			_localizationManager = new LocalizationManager(((BaseUnityPlugin)this).Logger, _settings.LanguageCode);
			_pinManager = new PinManager(_settings, ((BaseUnityPlugin)this).Logger, _localizationManager);
			_scanner = new PinScanner(_settings, _pinManager, _prefabTracker);
			_lastScanTime = 0f;
			if (_settings.ClearAllMapPinsAndHistory)
			{
				_pinManager.RemoveAllPins();
				_settings.ClearAllMapPinsAndHistory = false;
				_configLoader.SaveDefault(_settings);
				((BaseUnityPlugin)this).Logger.LogWarning((object)"[SullysAutoPinner] All map pins cleared and config flag reset.");
			}
			if (_settings.ClearAllUnwantedPins)
			{
				_pinManager.RemoveUnwantedPins(_settings);
				_settings.ClearAllUnwantedPins = false;
				_configLoader.SaveDefault(_settings);
				((BaseUnityPlugin)this).Logger.LogWarning((object)"[SullysAutoPinner] Unwanted pins cleared and config flag reset.");
			}
			((BaseUnityPlugin)this).Logger.LogWarning((object)"[SullysAutoPinner] Config hot-reloaded — scanner and localization reloaded.");
		});
		((BaseUnityPlugin)this).Logger.LogWarning((object)"SullysAutoPinner Initialized");
	}

	private void Update()
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)Player.m_localPlayer == (Object)null))
		{
			if (Time.time - _lastScanTime > _settings.ScanInterval)
			{
				_lastScanTime = Time.time;
				_scanner.RunScan(((Component)Player.m_localPlayer).transform.position);
			}
			_pinManager.TryPeriodicSave();
			_prefabTracker.TryPeriodicSave();
		}
	}

	private void OnApplicationQuit()
	{
		_pinManager.SaveImmediate();
		_prefabTracker.SaveImmediate();
	}
}
public class ConfigLoader
{
	private static readonly string SaveFolder = Path.Combine(Paths.ConfigPath, "SullysAutoPinnerFiles");

	private static readonly string ConfigFilePath = Path.Combine(SaveFolder, "SullysAutoPinner.cfg");

	private readonly ManualLogSource _logger;

	private FileSystemWatcher _watcher;

	private Timer _debounceTimer;

	private Action _onReload;

	public ConfigLoader(ManualLogSource logger)
	{
		_logger = logger;
		Directory.CreateDirectory(SaveFolder);
	}

	public void EnableHotReload(Action onReload)
	{
		_onReload = onReload;
		_watcher = new FileSystemWatcher(SaveFolder, "SullysAutoPinner.cfg")
		{
			NotifyFilter = (NotifyFilters.Size | NotifyFilters.LastWrite)
		};
		_watcher.Changed += OnConfigChanged;
		_watcher.Renamed += OnConfigChanged;
		_watcher.EnableRaisingEvents = true;
		_logger.LogWarning((object)"[ConfigLoader] Hot config reload enabled.");
	}

	private void OnConfigChanged(object sender, FileSystemEventArgs e)
	{
		_debounceTimer?.Dispose();
		_debounceTimer = new Timer(delegate
		{
			try
			{
				_logger.LogWarning((object)"[ConfigLoader] Config file updated — reloading.");
				_onReload?.Invoke();
			}
			catch (Exception ex)
			{
				_logger.LogWarning((object)("[ConfigLoader] Reload failed: " + ex.Message));
			}
		}, null, 200, -1);
	}

	public PinSettings Load()
	{
		PinSettings pinSettings = new PinSettings();
		Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
		if (File.Exists(ConfigFilePath))
		{
			string[] array = File.ReadAllLines(ConfigFilePath);
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (!text.StartsWith("#") && text.Contains("="))
				{
					string[] array2 = text.Split(new char[1] { '=' }, 2);
					dictionary[array2[0].Trim().ToLowerInvariant()] = array2[1].Trim().ToLowerInvariant();
				}
			}
			foreach (KeyValuePair<string, string> item in dictionary)
			{
				ApplyKeyValue(pinSettings, item.Key, item.Value);
			}
			List<string> list = (from f in typeof(PinSettings).GetFields()
				where f.FieldType == typeof(bool)
				select f.Name.ToLowerInvariant()).ToHashSet().Except(dictionary.Keys).ToList();
			array = new string[2] { "clearallmappinsandhistory", "clearallunwantedpins" };
			foreach (string text2 in array)
			{
				if (!dictionary.ContainsKey(text2) && !list.Contains(text2))
				{
					list.Add(text2);
				}
			}
			if (list.Any())
			{
				AppendMissingDefaults(pinSettings, list);
			}
		}
		else
		{
			SaveDefault(pinSettings);
		}
		return pinSettings;
	}

	private void ApplyKeyValue(PinSettings settings, string key, string value)
	{
		bool flag = value.Equals("true", StringComparison.OrdinalIgnoreCase);
		float result;
		switch (key)
		{
		case "scanradius":
			if (float.TryParse(value, out result))
			{
				settings.ScanRadius = result;
			}
			return;
		case "scaninterval":
			if (float.TryParse(value, out result))
			{
				settings.ScanInterval = result;
			}
			return;
		case "saveinterval":
			if (float.TryParse(value, out result))
			{
				settings.SaveInterval = result;
			}
			return;
		case "pinmergedistance":
			if (float.TryParse(value, out result))
			{
				settings.PinMergeDistance = result;
			}
			return;
		}
		FieldInfo fieldInfo = typeof(PinSettings).GetFields().FirstOrDefault((FieldInfo f) => f.Name.Equals(key, StringComparison.OrdinalIgnoreCase));
		if (fieldInfo != null && fieldInfo.FieldType == typeof(bool))
		{
			fieldInfo.SetValue(settings, flag);
		}
	}

	private void AppendMissingDefaults(PinSettings settings, IEnumerable<string> missingKeys)
	{
		try
		{
			using (StreamWriter streamWriter = File.AppendText(ConfigFilePath))
			{
				foreach (string key in missingKeys)
				{
					bool flag = (bool)typeof(PinSettings).GetFields().First((FieldInfo f) => f.Name.Equals(key, StringComparison.InvariantCultureIgnoreCase)).GetValue(settings);
					streamWriter.WriteLine(key + "=" + flag.ToString().ToLowerInvariant());
				}
			}
			_logger.LogWarning((object)("Appended missing config keys to: " + ConfigFilePath));
		}
		catch (Exception ex)
		{
			_logger.LogWarning((object)("Error appending missing defaults: " + ex.Message));
		}
	}

	public void SaveDefault(PinSettings settings)
	{
		try
		{
			using (StreamWriter streamWriter = new StreamWriter(ConfigFilePath))
			{
				streamWriter.WriteLine("# SullysAutoPinner config");
				streamWriter.WriteLine("scanradius=" + settings.ScanRadius);
				streamWriter.WriteLine("scaninterval=" + settings.ScanInterval);
				streamWriter.WriteLine("saveinterval=" + settings.SaveInterval);
				streamWriter.WriteLine("pinmergedistance=" + settings.PinMergeDistance);
				FieldInfo[] fields = typeof(PinSettings).GetFields();
				foreach (FieldInfo fieldInfo in fields)
				{
					if (fieldInfo.FieldType == typeof(bool))
					{
						string text = fieldInfo.Name.ToLowerInvariant();
						streamWriter.WriteLine(text + "=" + ((bool)fieldInfo.GetValue(settings)).ToString().ToLowerInvariant());
					}
				}
			}
			_logger.LogWarning((object)("Default config created at: " + ConfigFilePath));
		}
		catch (Exception ex)
		{
			_logger.LogWarning((object)("Error saving default config: " + ex.Message));
		}
	}
}
public class PinSettings
{
	public string LanguageCode = "en";

	public bool ClearNearbyFallbackPinsOnNextScan;

	public bool ShowUnmappedPrefabs;

	public float ScanRadius = 300f;

	public float ScanInterval = 12f;

	public float SaveInterval = 120f;

	public float PinMergeDistance = 50f;

	public bool EnablePinSaving = true;

	public bool EnablePrefabLogging;

	public bool Mushrooms;

	public bool RaspBerries;

	public bool BlueBerries;

	public bool Seeds;

	public bool Thistle;

	public bool CloudBerries;

	public bool Copper = true;

	public bool Tin;

	public bool Skeleton;

	public bool DwarfSpawner = true;

	public bool TrollCave = true;

	public bool Crypt = true;

	public bool Totem = true;

	public bool Fire = true;

	public bool DraugrSpawner;

	public bool Treasure;

	public bool Barley;

	public bool Flax;

	public bool Tar = true;

	public bool DragonEgg = true;

	public bool VoltureEgg = true;

	public bool SmokePuffs;

	public bool MageCaps = true;

	public bool YPCones = true;

	public bool JotunPuffs = true;

	public bool Iron = true;

	public bool Mudpile = true;

	public bool Abomination = true;

	public bool Meteorite = true;

	public bool Obsidian = true;

	public bool Silver = true;

	public bool MistlandsGiants = true;

	public bool MistlandsSwords = true;

	public bool DvergerThings = true;

	public bool ClearAllMapPinsAndHistory;

	public bool ClearAllUnwantedPins;
}
public class PrefabTracker
{
	private readonly HashSet<string> _seenPrefabs = new HashSet<string>();

	private readonly ManualLogSource _logger;

	private readonly PinSettings _settings;

	private float _lastPrefabDumpTime;

	private const float DumpInterval = 300f;

	private const int PrefabFlushThreshold = 1000;

	private const string PrefabsFilePath = "BepInEx/config/SullysAutoPinnerFiles/SeenPrefabs.txt";

	private static readonly HashSet<string> IgnoredPrefabs = new HashSet<string> { "tree", "bush", "log", "stone", "branch" };

	public PrefabTracker(ManualLogSource logger, PinSettings settings)
	{
		_logger = logger;
		_settings = settings;
		Directory.CreateDirectory(Path.GetDirectoryName("BepInEx/config/SullysAutoPinnerFiles/SeenPrefabs.txt"));
	}

	public void LogPrefabHierarchy(GameObject rootGO)
	{
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Expected O, but got Unknown
		if (!_settings.EnablePrefabLogging || (Object)(object)rootGO == (Object)null)
		{
			return;
		}
		string text = ((Object)rootGO).name.ToLowerInvariant();
		foreach (string ignoredPrefab in IgnoredPrefabs)
		{
			if (text.Contains(ignoredPrefab))
			{
				return;
			}
		}
		List<string> list = new List<string>();
		foreach (Transform item2 in rootGO.transform)
		{
			Transform val = item2;
			if ((Object)(object)val != (Object)null)
			{
				list.Add(((Object)val).name);
			}
		}
		list.Sort();
		string item = ((Object)rootGO).name + " | " + string.Join(",", list);
		if (_seenPrefabs.Add(item) && _seenPrefabs.Count >= 1000)
		{
			SaveImmediate();
		}
	}

	public void TryPeriodicSave()
	{
		if (_settings.EnablePrefabLogging && Time.time - _lastPrefabDumpTime > 300f)
		{
			SaveImmediate();
		}
	}

	public void SaveImmediate()
	{
		_lastPrefabDumpTime = Time.time;
		try
		{
			HashSet<string> hashSet = new HashSet<string>();
			if (File.Exists("BepInEx/config/SullysAutoPinnerFiles/SeenPrefabs.txt"))
			{
				string[] array = File.ReadAllLines("BepInEx/config/SullysAutoPinnerFiles/SeenPrefabs.txt");
				foreach (string item in array)
				{
					hashSet.Add(item);
				}
			}
			using StreamWriter streamWriter = File.AppendText("BepInEx/config/SullysAutoPinnerFiles/SeenPrefabs.txt");
			foreach (string seenPrefab in _seenPrefabs)
			{
				if (!hashSet.Contains(seenPrefab))
				{
					streamWriter.WriteLine(seenPrefab);
				}
			}
		}
		catch (Exception ex)
		{
			_logger.LogWarning((object)("SullyAutoPinner >>> Error saving prefab list: " + ex.Message));
		}
	}
}
public class PinScanner
{
	public static class PinLabelMap
	{
		public static readonly Dictionary<string, (string SettingKey, PinType Icon)> LabelToSettingInfo = new Dictionary<string, (string, PinType)>(StringComparer.OrdinalIgnoreCase)
		{
			{
				"abomination",
				("Abomination", (PinType)3)
			},
			{
				"crypt2",
				("Crypt", (PinType)3)
			},
			{
				"crypt3",
				("Crypt", (PinType)3)
			},
			{
				"crypt4",
				("Crypt", (PinType)3)
			},
			{
				"trollcave",
				("TrollCave", (PinType)3)
			},
			{
				"rock4_copper",
				("Copper", (PinType)3)
			},
			{
				"iron_deposit",
				("Iron", (PinType)3)
			},
			{
				"mudpile",
				("Mudpile", (PinType)3)
			},
			{
				"obsidian",
				("Obsidian", (PinType)3)
			},
			{
				"silver",
				("Silver", (PinType)3)
			},
			{
				"meteor",
				("Meteorite", (PinType)3)
			},
			{
				"flax",
				("Flax", (PinType)3)
			},
			{
				"barley",
				("Barley", (PinType)3)
			},
			{
				"blueberry",
				("BlueBerries", (PinType)3)
			},
			{
				"berries",
				("RaspBerries", (PinType)3)
			},
			{
				"shrooms",
				("Mushrooms", (PinType)3)
			},
			{
				"cloud",
				("CloudBerries", (PinType)3)
			},
			{
				"thistle",
				("Thistle", (PinType)3)
			},
			{
				"carrot",
				("Seeds", (PinType)3)
			},
			{
				"onion",
				("Seeds", (PinType)3)
			},
			{
				"turnip",
				("Seeds", (PinType)3)
			},
			{
				"magecap",
				("MageCaps", (PinType)3)
			},
			{
				"y-pcone",
				("YPCones", (PinType)3)
			},
			{
				"j-puff",
				("JotunPuffs", (PinType)3)
			},
			{
				"v-egg",
				("VoltureEgg", (PinType)3)
			},
			{
				"dragonegg",
				("DragonEgg", (PinType)3)
			},
			{
				"smokepuff",
				("SmokePuffs", (PinType)3)
			},
			{
				"thing",
				("DvergerThings", (PinType)3)
			},
			{
				"dwarfspawner",
				("DwarfSpawner", (PinType)2)
			},
			{
				"draugrspawner",
				("DraugrSpawner", (PinType)2)
			},
			{
				"totem",
				("Totem", (PinType)2)
			},
			{
				"campfire",
				("Fire", (PinType)0)
			},
			{
				"tar",
				("Tar", (PinType)2)
			},
			{
				"skel",
				("Skeleton", (PinType)3)
			},
			{
				"treasure",
				("Treasure", (PinType)3)
			},
			{
				"swords",
				("MistlandsSwords", (PinType)3)
			},
			{
				"marker",
				("Marker", (PinType)2)
			},
			{
				"giant",
				("MistlandsGiants", (PinType)3)
			}
		};
	}

	private readonly PinSettings _settings;

	private readonly PinManager _pinManager;

	private readonly PrefabTracker _prefabTracker;

	public PinScanner(PinSettings settings, PinManager pinManager, PrefabTracker prefabTracker)
	{
		_settings = settings;
		_pinManager = pinManager;
		_prefabTracker = prefabTracker;
	}

	public void RunScan(Vector3 playerPosition)
	{
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_019e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0251: Unknown result type (might be due to invalid IL or missing references)
		//IL_0256: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0275: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
		if (_settings.ClearNearbyFallbackPinsOnNextScan)
		{
			_pinManager.RemoveNearbyFallbackPins(playerPosition, _settings.ScanRadius);
			_settings.ClearNearbyFallbackPinsOnNextScan = false;
			new ConfigLoader(Logger.CreateLogSource("AutoPinner")).SaveDefault(_settings);
		}
		if (playerPosition.y > 1000f)
		{
			return;
		}
		Collider[] array = Physics.OverlapSphere(playerPosition, _settings.ScanRadius, -1, (QueryTriggerInteraction)2);
		List<Vector3> list = new List<Vector3>();
		List<(Vector3, Transform)> list2 = new List<(Vector3, Transform)>();
		Collider[] array2 = array;
		foreach (Collider obj in array2)
		{
			GameObject gameObject = ((Component)((Component)obj).transform.root).gameObject;
			if ((Object)(object)gameObject == (Object)null)
			{
				continue;
			}
			_prefabTracker.LogPrefabHierarchy(gameObject);
			string text = ((Object)gameObject).name.ToLowerInvariant();
			Vector3 pinPos2 = gameObject.transform.position;
			string matchedLabel;
			PinType icon;
			if (text.Contains("locationproxy"))
			{
				list2.Add((pinPos2, gameObject.transform));
			}
			else if (TryMatchPrefab(text, out matchedLabel, out icon))
			{
				if (matchedLabel == "TROLLCAVE")
				{
					list.Add(pinPos2);
				}
				if (!(matchedLabel == "CRYPT") || !list.Any((Vector3 tc) => Vector3.Distance(tc, pinPos2) < 40f))
				{
					_pinManager.TryAddPin(pinPos2, matchedLabel, icon);
				}
			}
		}
		foreach (var item in list2)
		{
			var (val, _) = item;
			foreach (Transform item2 in item.Item2)
			{
				string text2 = ((Object)item2).name.ToLowerInvariant();
				if (!text2.Contains("runestone") && TryMatchPrefab(text2, out var matchedLabel2, out var icon2))
				{
					if (matchedLabel2 == "TROLLCAVE")
					{
						list.Add(val);
						_pinManager.TryAddPin(val, matchedLabel2, icon2);
					}
					break;
				}
			}
		}
		foreach (var item3 in list2)
		{
			var (pinPos, _) = item3;
			foreach (Transform item4 in item3.Item2)
			{
				string text3 = ((Object)item4).name.ToLowerInvariant();
				if (!text3.Contains("runestone") && TryMatchPrefab(text3, out var matchedLabel3, out var icon3))
				{
					if (!(matchedLabel3 == "TROLLCAVE") && (!(matchedLabel3 == "CRYPT") || !list.Any((Vector3 tc) => Vector3.Distance(tc, pinPos) < 40f)))
					{
						_pinManager.TryAddPin(pinPos, matchedLabel3, icon3);
					}
					break;
				}
			}
		}
	}

	private string CleanLabel(string rawName)
	{
		return Regex.Replace(rawName.Replace("(Clone)", ""), "\\d", "").ToUpperInvariant();
	}

	private bool TryMatchPrefab(string prefabName, out string matchedLabel, out PinType icon)
	{
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Expected I4, but got Unknown
		matchedLabel = null;
		icon = (PinType)3;
		foreach (KeyValuePair<string, (string, PinType)> item2 in PinLabelMap.LabelToSettingInfo)
		{
			if (prefabName.IndexOf(item2.Key, StringComparison.OrdinalIgnoreCase) >= 0)
			{
				string item = item2.Value.Item1;
				FieldInfo field = typeof(PinSettings).GetField(item);
				if (!(field == null) && !(field.FieldType != typeof(bool)) && (bool)field.GetValue(_settings))
				{
					matchedLabel = item.ToUpperInvariant();
					icon = (PinType)(int)item2.Value.Item2;
					return true;
				}
			}
		}
		if (_settings.ShowUnmappedPrefabs)
		{
			string[] array = new string[83]
			{
				"beech", "berry", "birch", "boar", "branch", "bush", "dandelion", "deer", "feathers", "fish",
				"firtree", "fur", "goblin", "goblin_archer", "goblin_banner", "goblin_bed", "goblin_fence", "goblin_pole", "goblin_roof", "goblin_roof_cap",
				"goblin_shaman", "goblin_stepladder", "greyling", "greydwarf", "mushroom", "neck", "oak1", "pickable_dolmentreasure", "pickable_forestcryptremains", "pickable_flint",
				"pickable_stone", "player", "pine", "piece_sharpstakes", "piece_workbench", "berries", "resin", "seagal", "shrub", "stone",
				"stone_wall", "stubbe", "vines", "wood", "zone", "pillar", "carrot", "turnip", "onion", "thistle",
				"minerock_tin", "crow", "odin", "pickable_tar", "tarliquid", "skeleton", "deathsquito", "forestcrypt", "swamptree", "wraith",
				"statue", "leech", "table", "draugr", "blob", "oak", "leather", "log", "meat", "seed",
				"bonefragments", "honey", "forge", "entrails", "bonepile", "castlekit", "trophy", "sunken", "root", "guck",
				"swamp", "grave", "piece"
			};
			foreach (string value in array)
			{
				if (prefabName.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return false;
				}
			}
			matchedLabel = prefabName.Replace("(clone)", "");
			icon = (PinType)2;
			return true;
		}
		return false;
	}
}
public class LocalizationManager
{
	private readonly Dictionary<string, string> _translations = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

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

	private readonly ManualLogSource _logger;

	private readonly string _langCode;

	private readonly string _translationsFolder;

	private const string FallbackLang = "en";

	public LocalizationManager(ManualLogSource logger, string langCode)
	{
		_logger = logger;
		_langCode = (string.IsNullOrWhiteSpace(langCode) ? "en" : langCode.ToLowerInvariant());
		_translationsFolder = Path.Combine(Paths.ConfigPath, "SullysAutoPinnerFiles", "Translations");
		LoadTranslations("en");
		if (_langCode != "en")
		{
			LoadTranslations(_langCode);
		}
	}

	private void LoadTranslations(string lang)
	{
		try
		{
			string text = Path.Combine(_translationsFolder, lang + ".json");
			if (!File.Exists(text))
			{
				_logger.LogWarning((object)("[LocalizationManager] Translation file not found: " + text));
				return;
			}
			JSONNode jSONNode = JSON.Parse(File.ReadAllText(text));
			if (jSONNode == null || !jSONNode.IsObject)
			{
				_logger.LogWarning((object)("[LocalizationManager] Failed to parse " + text));
				return;
			}
			JSONNode.Enumerator enumerator = jSONNode.AsObject.GetEnumerator();
			while (enumerator.MoveNext())
			{
				KeyValuePair<string, JSONNode> current = enumerator.Current;
				_translations[current.Key.ToUpperInvariant()] = current.Value.Value;
			}
			_logger.LogWarning((object)$"[LocalizationManager] Loaded {jSONNode.Count} entries from {lang}.json");
		}
		catch (Exception ex)
		{
			_logger.LogWarning((object)("[LocalizationManager] Error loading " + lang + ".json: " + ex.Message));
		}
	}

	public string GetLabel(string key)
	{
		if (string.IsNullOrWhiteSpace(key))
		{
			return key;
		}
		if (_translations.TryGetValue(key.ToUpperInvariant(), out var value))
		{
			return value;
		}
		if (_missingKeys.Add(key))
		{
			_logger.LogWarning((object)("[LocalizationManager] Missing translation for label: " + key));
		}
		return key;
	}

	public static void EnsureBaseLanguageFiles(ManualLogSource logger)
	{
		string text = Path.Combine(Paths.ConfigPath, "SullysAutoPinnerFiles", "Translations");
		Directory.CreateDirectory(text);
		foreach (KeyValuePair<string, Dictionary<string, string>> defaultTranslation in GetDefaultTranslations())
		{
			string key = defaultTranslation.Key;
			string path = Path.Combine(text, key + ".json");
			if (File.Exists(path))
			{
				continue;
			}
			try
			{
				JSONObject jSONObject = new JSONObject();
				foreach (KeyValuePair<string, string> item in defaultTranslation.Value)
				{
					jSONObject[item.Key] = item.Value;
				}
				File.WriteAllText(path, jSONObject.ToString(2));
				logger.LogWarning((object)("[LocalizationManager] Created default translation file: " + key + ".json"));
			}
			catch (Exception ex)
			{
				logger.LogWarning((object)("[LocalizationManager] Failed to write " + key + ".json: " + ex.Message));
			}
		}
	}

	private static Dictionary<string, Dictionary<string, string>> GetDefaultTranslations()
	{
		return new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase)
		{
			["en"] = new Dictionary<string, string>
			{
				["COPPER"] = "Copper",
				["IRON"] = "Iron",
				["SILVER"] = "Silver",
				["OBSIDIAN"] = "Obsidian",
				["MUDPILE"] = "Mudpile",
				["METEORITE"] = "Meteorite",
				["TROLLCAVE"] = "Troll Cave",
				["CRYPT"] = "Crypt",
				["ABOMINATION"] = "Abomination",
				["FLAX"] = "Flax",
				["BARLEY"] = "Barley",
				["BLUEBERRIES"] = "Blueberries",
				["RASPBERRIES"] = "Raspberries",
				["MUSHROOMS"] = "Mushrooms",
				["CLOUDBERRIES"] = "Cloudberries",
				["THISTLE"] = "Thistle",
				["SEEDS"] = "Seeds",
				["MAGECAPS"] = "Magecaps",
				["YPCONES"] = "Yggdrasil Pine Cones",
				["JOTUNNPUFFS"] = "Jotunn Puffs",
				["VOLTUREEGG"] = "Vulture Egg",
				["DRAGONEGG"] = "Dragon Egg",
				["SMOKEPUFFS"] = "Smoke Puffs",
				["DVERGERTHINGS"] = "Dvergr Remains",
				["DWARFSPAWNER"] = "Greydwarf Nest",
				["DRAUGRSPAWNER"] = "Draugr Spawner",
				["TOTEM"] = "Fuling Totem",
				["FIRE"] = "Campfire",
				["TAR"] = "Tar Pit",
				["SKELETON"] = "Skeleton",
				["TREASURE"] = "Buried Treasure",
				["MISTLANDSSWORDS"] = "Sword in the Stone",
				["MISTLANDSGIANTS"] = "Giant Remains",
				["MARKER"] = "Marker"
			},
			["ru"] = new Dictionary<string, string>
			{
				["COPPER"] = "Медь",
				["IRON"] = "Железо",
				["SILVER"] = "Серебро",
				["OBSIDIAN"] = "Обсидиан",
				["MUDPILE"] = "Грязевая куча",
				["METEORITE"] = "Метеорит",
				["TROLLCAVE"] = "Пещера тролля",
				["CRYPT"] = "Крипта",
				["ABOMINATION"] = "Мерзость",
				["FLAX"] = "Лён",
				["BARLEY"] = "Ячмень",
				["BLUEBERRIES"] = "Черника",
				["RASPBERRIES"] = "Малина",
				["MUSHROOMS"] = "Грибы",
				["CLOUDBERRIES"] = "Морошка",
				["THISTLE"] = "Чертополох",
				["SEEDS"] = "Семена",
				["MAGECAPS"] = "Волшебные шляпки",
				["YPCONES"] = "Шишки Иггдрасиля",
				["JOTUNNPUFFS"] = "Пух Йотуна",
				["VOLTUREEGG"] = "Яйцо стервятника",
				["DRAGONEGG"] = "Яйцо дракона",
				["SMOKEPUFFS"] = "Клубы дыма",
				["DVERGERTHINGS"] = "Останки двергров",
				["DWARFSPAWNER"] = "Гнездо серого карлика",
				["DRAUGRSPAWNER"] = "Портал драугров",
				["TOTEM"] = "Тотем фулингов",
				["FIRE"] = "Костер",
				["TAR"] = "Смоляная яма",
				["SKELETON"] = "Скелет",
				["TREASURE"] = "Сокровище",
				["MISTLANDSSWORDS"] = "Меч в камне",
				["MISTLANDSGIANTS"] = "Останки великанов",
				["MARKER"] = "Маркер"
			},
			["fr"] = new Dictionary<string, string>
			{
				["COPPER"] = "Cuivre",
				["IRON"] = "Fer",
				["SILVER"] = "Argent",
				["OBSIDIAN"] = "Obsidienne",
				["MUDPILE"] = "Tas de boue",
				["METEORITE"] = "Météorite",
				["TROLLCAVE"] = "Grotte du troll",
				["CRYPT"] = "Crypte",
				["ABOMINATION"] = "Abomination",
				["FLAX"] = "Lin",
				["BARLEY"] = "Orge",
				["BLUEBERRIES"] = "Myrtilles",
				["RASPBERRIES"] = "Framboises",
				["MUSHROOMS"] = "Champignons",
				["CLOUDBERRIES"] = "Plaquebières",
				["THISTLE"] = "Chardon",
				["SEEDS"] = "Graines",
				["MAGECAPS"] = "Chapeaux de mage",
				["YPCONES"] = "Cônes d’Yggdrasil",
				["JOTUNNPUFFS"] = "Poussières de Jotunn",
				["VOLTUREEGG"] = "Œuf de vautour",
				["DRAGONEGG"] = "Œuf de dragon",
				["SMOKEPUFFS"] = "Nuages de fumée",
				["DVERGERTHINGS"] = "Restes de Dvergr",
				["DWARFSPAWNER"] = "Nid de nain gris",
				["DRAUGRSPAWNER"] = "Portail Draugr",
				["TOTEM"] = "Totem de Fuling",
				["FIRE"] = "Feu de camp",
				["TAR"] = "Fosse à goudron",
				["SKELETON"] = "Squelette",
				["TREASURE"] = "Trésor",
				["MISTLANDSSWORDS"] = "Épée dans la pierre",
				["MISTLANDSGIANTS"] = "Restes de géants",
				["MARKER"] = "Marqueur"
			},
			["de"] = new Dictionary<string, string>
			{
				["COPPER"] = "Kupfer",
				["IRON"] = "Eisen",
				["SILVER"] = "Silber",
				["OBSIDIAN"] = "Obsidian",
				["MUDPILE"] = "Schlammhaufen",
				["METEORITE"] = "Meteorit",
				["TROLLCAVE"] = "Trollhöhle",
				["CRYPT"] = "Gruft",
				["ABOMINATION"] = "Abscheulichkeit",
				["FLAX"] = "Flachs",
				["BARLEY"] = "Gerste",
				["BLUEBERRIES"] = "Blaubeeren",
				["RASPBERRIES"] = "Himbeeren",
				["MUSHROOMS"] = "Pilze",
				["CLOUDBERRIES"] = "Moltebeeren",
				["THISTLE"] = "Distel",
				["SEEDS"] = "Samen",
				["MAGECAPS"] = "Magierkappen",
				["YPCONES"] = "Yggdrasil-Zapfen",
				["JOTUNNPUFFS"] = "Jotunnflusen",
				["VOLTUREEGG"] = "Geier-Ei",
				["DRAGONEGG"] = "Drachenei",
				["SMOKEPUFFS"] = "Rauchwolken",
				["DVERGERTHINGS"] = "Dvergr-Überreste",
				["DWARFSPAWNER"] = "Grauzwergen-Nest",
				["DRAUGRSPAWNER"] = "Draugr-Portal",
				["TOTEM"] = "Fuling-Totem",
				["FIRE"] = "Lagerfeuer",
				["TAR"] = "Teergrube",
				["SKELETON"] = "Skelett",
				["TREASURE"] = "Schatz",
				["MISTLANDSSWORDS"] = "Schwert im Stein",
				["MISTLANDSGIANTS"] = "Überreste der Riesen",
				["MARKER"] = "Markierung"
			},
			["es"] = new Dictionary<string, string>
			{
				["COPPER"] = "Cobre",
				["IRON"] = "Hierro",
				["SILVER"] = "Plata",
				["OBSIDIAN"] = "Obsidiana",
				["MUDPILE"] = "Montón de barro",
				["METEORITE"] = "Meteorito",
				["TROLLCAVE"] = "Cueva de trolls",
				["CRYPT"] = "Cripta",
				["ABOMINATION"] = "Abominación",
				["FLAX"] = "Lino",
				["BARLEY"] = "Cebada",
				["BLUEBERRIES"] = "Arándanos",
				["RASPBERRIES"] = "Frambuesas",
				["MUSHROOMS"] = "Setas",
				["CLOUDBERRIES"] = "Moras nubes",
				["THISTLE"] = "Cardo",
				["SEEDS"] = "Semillas",
				["MAGECAPS"] = "Sombreros mágicos",
				["YPCONES"] = "Conos de Yggdrasil",
				["JOTUNNPUFFS"] = "Pelusas de Jotunn",
				["VOLTUREEGG"] = "Huevo de buitre",
				["DRAGONEGG"] = "Huevo de dragón",
				["SMOKEPUFFS"] = "Nubes de humo",
				["DVERGERTHINGS"] = "Restos de Dvergr",
				["DWARFSPAWNER"] = "Nido de enano gris",
				["DRAUGRSPAWNER"] = "Portal Draugr",
				["TOTEM"] = "Tótem Fuling",
				["FIRE"] = "Hoguera",
				["TAR"] = "Pozo de alquitrán",
				["SKELETON"] = "Esqueleto",
				["TREASURE"] = "Tesoro",
				["MISTLANDSSWORDS"] = "Espada en la piedra",
				["MISTLANDSGIANTS"] = "Restos de gigantes",
				["MARKER"] = "Marcador"
			},
			["pl"] = new Dictionary<string, string>
			{
				["COPPER"] = "Miedź",
				["IRON"] = "Żelazo",
				["SILVER"] = "Srebro",
				["OBSIDIAN"] = "Obsydian",
				["MUDPILE"] = "Stos błota",
				["METEORITE"] = "Meteoryt",
				["TROLLCAVE"] = "Jaskinia trolla",
				["CRYPT"] = "Krypta",
				["ABOMINATION"] = "Potworność",
				["FLAX"] = "Len",
				["BARLEY"] = "Jęczmień",
				["BLUEBERRIES"] = "Jagody",
				["RASPBERRIES"] = "Maliny",
				["MUSHROOMS"] = "Grzyby",
				["CLOUDBERRIES"] = "Malina moroszka",
				["THISTLE"] = "Oset",
				["SEEDS"] = "Nasiona",
				["MAGECAPS"] = "Kapelusze maga",
				["YPCONES"] = "Szyszki Yggdrasila",
				["JOTUNNPUFFS"] = "Puch Jotunna",
				["VOLTUREEGG"] = "Jajo sępa",
				["DRAGONEGG"] = "Jajo smoka",
				["SMOKEPUFFS"] = "Kłęby dymu",
				["DVERGERTHINGS"] = "Pozostałości Dvergrów",
				["DWARFSPAWNER"] = "Gniazdo krasnoluda",
				["DRAUGRSPAWNER"] = "Pojawiacz Draugrów",
				["TOTEM"] = "Totem Fulingów",
				["FIRE"] = "Ognisko",
				["TAR"] = "Dół ze smołą",
				["SKELETON"] = "Szkielet",
				["TREASURE"] = "Skarb",
				["MISTLANDSSWORDS"] = "Miecz w kamieniu",
				["MISTLANDSGIANTS"] = "Szczątki olbrzyma",
				["MARKER"] = "Znacznik"
			},
			["zh"] = new Dictionary<string, string>
			{
				["COPPER"] = "铜矿",
				["IRON"] = "铁矿",
				["SILVER"] = "银矿",
				["OBSIDIAN"] = "黑曜石",
				["MUDPILE"] = "泥堆",
				["METEORITE"] = "陨石",
				["TROLLCAVE"] = "巨魔洞穴",
				["CRYPT"] = "地穴",
				["ABOMINATION"] = "憎恶",
				["FLAX"] = "亚麻",
				["BARLEY"] = "大麦",
				["BLUEBERRIES"] = "蓝莓",
				["RASPBERRIES"] = "覆盆子",
				["MUSHROOMS"] = "蘑菇",
				["CLOUDBERRIES"] = "云莓",
				["THISTLE"] = "蓟",
				["SEEDS"] = "种子",
				["MAGECAPS"] = "法师帽",
				["YPCONES"] = "世界树松果",
				["JOTUNNPUFFS"] = "尤顿绒毛",
				["VOLTUREEGG"] = "秃鹰蛋",
				["DRAGONEGG"] = "龙蛋",
				["SMOKEPUFFS"] = "烟雾",
				["DVERGERTHINGS"] = "矮人遗物",
				["DWARFSPAWNER"] = "灰矮人巢穴",
				["DRAUGRSPAWNER"] = "尸鬼生成器",
				["TOTEM"] = "愚林图腾",
				["FIRE"] = "营火",
				["TAR"] = "焦油坑",
				["SKELETON"] = "骷髅",
				["TREASURE"] = "宝藏",
				["MISTLANDSSWORDS"] = "石中剑",
				["MISTLANDSGIANTS"] = "巨人遗骸",
				["MARKER"] = "标记"
			},
			["pt"] = new Dictionary<string, string>
			{
				["COPPER"] = "Cobre",
				["IRON"] = "Ferro",
				["SILVER"] = "Prata",
				["OBSIDIAN"] = "Obsidiana",
				["MUDPILE"] = "Monturo de lama",
				["METEORITE"] = "Meteorito",
				["TROLLCAVE"] = "Caverna do troll",
				["CRYPT"] = "Cripta",
				["ABOMINATION"] = "Abominação",
				["FLAX"] = "Linho",
				["BARLEY"] = "Cevada",
				["BLUEBERRIES"] = "Mirtilos",
				["RASPBERRIES"] = "Framboesas",
				["MUSHROOMS"] = "Cogumelos",
				["CLOUDBERRIES"] = "Amoras nubladas",
				["THISTLE"] = "Cardo",
				["SEEDS"] = "Sementes",
				["MAGECAPS"] = "Chapéus mágicos",
				["YPCONES"] = "Pinhas de Yggdrasil",
				["JOTUNNPUFFS"] = "Fofos de Jotunn",
				["VOLTUREEGG"] = "Ovo de abutre",
				["DRAGONEGG"] = "Ovo de dragão",
				["SMOKEPUFFS"] = "Nuvens de fumaça",
				["DVERGERTHINGS"] = "Restos de Dvergr",
				["DWARFSPAWNER"] = "Ninho de anão cinzento",
				["DRAUGRSPAWNER"] = "Portal Draugr",
				["TOTEM"] = "Totem Fuling",
				["FIRE"] = "Fogueira",
				["TAR"] = "Poça de alcatrão",
				["SKELETON"] = "Esqueleto",
				["TREASURE"] = "Tesouro",
				["MISTLANDSSWORDS"] = "Espada na pedra",
				["MISTLANDSGIANTS"] = "Restos de gigantes",
				["MARKER"] = "Marcador"
			}
		};
	}
}
public class PinManager
{
	private const int PinFlushThreshold = 50;

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

	private readonly PinSettings _settings;

	private readonly ManualLogSource _logger;

	private readonly LocalizationManager _localizationManager;

	private readonly List<Tuple<Vector3, string>> _currentPins = new List<Tuple<Vector3, string>>();

	private readonly List<Tuple<Vector3, string>> _newPins = new List<Tuple<Vector3, string>>();

	private float _lastSaveTime;

	private static readonly string SaveFolder = Path.Combine(Paths.ConfigPath, "SullysAutoPinnerFiles");

	private static readonly string PinsFilePath = Path.Combine(SaveFolder, "Pins.txt");

	public PinManager(PinSettings settings, ManualLogSource logger, LocalizationManager localizationManager)
	{
		_settings = settings;
		_logger = logger;
		_localizationManager = localizationManager;
		Directory.CreateDirectory(Path.GetDirectoryName(PinsFilePath));
		LoadPinsFromFile();
	}

	public void TryAddPin(Vector3 pos, string label, PinType icon)
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//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_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Minimap.instance == (Object)null)
		{
			return;
		}
		Vector3 val = RoundTo0_1(pos);
		string text = label.ToUpperInvariant();
		string pinHash = GetPinHash(val, text);
		if (_pinHashes.Contains(pinHash))
		{
			return;
		}
		foreach (Tuple<Vector3, string> currentPin in _currentPins)
		{
			if (Vector3.Distance(currentPin.Item1, val) < _settings.PinMergeDistance && string.Equals(currentPin.Item2, text, StringComparison.OrdinalIgnoreCase))
			{
				return;
			}
		}
		string label2 = _localizationManager.GetLabel(text);
		Minimap.instance.AddPin(val, icon, label2, true, false, 0L, default(PlatformUserID));
		_newPins.Add(new Tuple<Vector3, string>(val, text));
		_currentPins.Add(new Tuple<Vector3, string>(val, text));
		_pinHashes.Add(pinHash);
		if (_settings.EnablePinSaving && _newPins.Count >= 50)
		{
			SavePinsToFile();
		}
	}

	public void TryPeriodicSave()
	{
		if (_settings.EnablePinSaving && _newPins.Count != 0 && (_newPins.Count >= 50 || Time.time - _lastSaveTime > _settings.SaveInterval))
		{
			SavePinsToFile();
		}
	}

	public void SaveImmediate()
	{
		if (_settings.EnablePinSaving)
		{
			SavePinsToFile();
		}
	}

	public void RemoveAllPins()
	{
		if ((Object)(object)Minimap.instance == (Object)null)
		{
			return;
		}
		_pinHashes.Clear();
		try
		{
			File.WriteAllText(PinsFilePath, string.Empty);
			_logger.LogWarning((object)"SullysAutoPinner >>> All Map Pins Removed - Pin history file emptied.");
		}
		catch (Exception ex)
		{
			_logger.LogWarning((object)("SullysAutoPinner >>> Failed to clear Pins.txt: " + ex.Message));
			return;
		}
		if (!(AccessTools.Field(typeof(Minimap), "m_pins").GetValue(Minimap.instance) is List<PinData> list))
		{
			return;
		}
		foreach (PinData item in list.ToList())
		{
			Minimap.instance.RemovePin(item);
		}
		_currentPins.Clear();
		_newPins.Clear();
		_pinHashes.Clear();
		_logger.LogWarning((object)$"SullysAutoPinner >>> All Map Pins Removed: {list.Count} pins removed from the map.");
	}

	public void RemoveUnwantedPins(PinSettings settings)
	{
		if ((Object)(object)Minimap.instance == (Object)null || !(AccessTools.Field(typeof(Minimap), "m_pins").GetValue(Minimap.instance) is List<PinData> list))
		{
			return;
		}
		List<PinData> list2 = new List<PinData>();
		foreach (PinData item in list)
		{
			string label = item.m_name.ToUpperInvariant();
			if (!IsLabelEnabled(label, settings))
			{
				list2.Add(item);
			}
		}
		foreach (PinData item2 in list2)
		{
			Minimap.instance.RemovePin(item2);
		}
		_logger.LogWarning((object)$"Removed {list2.Count} unwanted pins from the map.");
	}

	private bool IsLabelEnabled(string label, PinSettings settings)
	{
		if (!PinScanner.PinLabelMap.LabelToSettingInfo.TryGetValue(label, out (string, PinType) value))
		{
			return true;
		}
		FieldInfo field = typeof(PinSettings).GetField(value.Item1);
		if (field == null || field.FieldType != typeof(bool))
		{
			return true;
		}
		return (bool)field.GetValue(settings);
	}

	private void SavePinsToFile()
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			using StreamWriter streamWriter = File.AppendText(PinsFilePath);
			foreach (Tuple<Vector3, string> newPin in _newPins)
			{
				streamWriter.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0:F1}|{1:F1}|{2:F1}|{3}", newPin.Item1.x, newPin.Item1.y, newPin.Item1.z, newPin.Item2));
			}
		}
		catch (Exception ex)
		{
			_logger.LogWarning((object)("SullyAutoPinner >>> Error saving pins: " + ex.Message));
		}
		_newPins.Clear();
		_lastSaveTime = Time.time;
	}

	private void LoadPinsFromFile()
	{
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (!File.Exists(PinsFilePath))
			{
				return;
			}
			string[] array = File.ReadAllLines(PinsFilePath);
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split(new char[1] { '|' });
				if (array2.Length == 4 && float.TryParse(array2[0], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(array2[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) && float.TryParse(array2[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result3))
				{
					string text = array2[3].Trim().ToUpperInvariant();
					Vector3 val = RoundTo0_1(new Vector3(result, result2, result3));
					string pinHash = GetPinHash(val, text);
					_pinHashes.Add(pinHash);
					_currentPins.Add(new Tuple<Vector3, string>(val, text));
				}
			}
		}
		catch (Exception ex)
		{
			_logger.LogWarning((object)("SullyAutoPinner >>> Error loading pins: " + ex.Message));
		}
	}

	private string GetPinHash(Vector3 pos, string label)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: 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_003f: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = RoundTo0_1(pos);
		return string.Format(CultureInfo.InvariantCulture, "{0}:{1:F1},{2:F1},{3:F1}", label.ToUpperInvariant(), val.x, val.y, val.z);
	}

	private Vector3 RoundTo0_1(Vector3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		return new Vector3(Mathf.Round(v.x * 10f) / 10f, Mathf.Round(v.y * 10f) / 10f, Mathf.Round(v.z * 10f) / 10f);
	}

	public void RemoveNearbyFallbackPins(Vector3 center, float radius)
	{
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Minimap.instance == (Object)null || !(AccessTools.Field(typeof(Minimap), "m_pins").GetValue(Minimap.instance) is List<PinData> list))
		{
			return;
		}
		List<PinData> list2 = new List<PinData>();
		foreach (PinData item in list)
		{
			if (!(Vector3.Distance(center, item.m_pos) > radius))
			{
				string name = item.m_name;
				if (!PinScanner.PinLabelMap.LabelToSettingInfo.ContainsKey(name))
				{
					list2.Add(item);
				}
			}
		}
		foreach (PinData item2 in list2)
		{
			Minimap.instance.RemovePin(item2);
		}
		_logger.LogWarning((object)$"Removed {list2.Count} fallback pins within {radius}m.");
	}
}
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;

		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()
		{
			if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
			{
				<>1__state = 0;
				return this;
			}
			return new <get_Children>d__43(0);
		}

		[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> <>7__wrap1;

		private IEnumerator<JSONNode> <>7__wrap2;

		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();
				}
			}
			<>7__wrap1 = null;
			<>7__wrap2 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			try
			{
				int num = <>1__state;
				JSONNode jSONNode = <>4__this;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -4;
					goto IL_008d;
				}
				<>1__state = -1;
				<>7__wrap1 = jSONNode.Children.GetEnumerator();
				<>1__state = -3;
				goto IL_00a7;
				IL_008d:
				if (<>7__wrap2.MoveNext())
				{
					JSONNode current = <>7__wrap2.Current;
					<>2__current = current;
					<>1__state = 1;
					return true;
				}
				<>m__Finally2();
				<>7__wrap2 = null;
				goto IL_00a7;
				IL_00a7:
				if (<>7__wrap1.MoveNext())
				{
					JSONNode current2 = <>7__wrap1.Current;
					<>7__wrap2 = current2.DeepChildren.GetEnumerator();
					<>1__state = -4;
					goto IL_008d;
				}
				<>m__Finally1();
				<>7__wrap1 = 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 (<>7__wrap1 != null)
			{
				<>7__wrap1.Dispose();
			}
		}

		private void <>m__Finally2()
		{
			<>1__state = -3;
			if (<>7__wrap2 != null)
			{
				<>7__wrap2.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()
			return new <get_Children>d__43(-2);
		}
	}

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

	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)
	{
		if (s != null)
		{
			return new JSONString(s);
		}
		return JSONNull.CreateOrGet();
	}

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

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

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

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

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

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

	public static implicit operator int(JSONNode d)
	{
		if (!(d == null))
		{
			return d.AsInt;
		}
		return 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)
	{
		if (!(d == null))
		{
			return d.AsLong;
		}
		return 0L;
	}

	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)
	{
		if (!(d == null))
		{
			return d.AsULong;
		}
		return 0uL;
	}

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

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

	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;
		}
		if (!flag)
		{
			return a.Equals(b);
		}
		return false;
	}

	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();
			switch (text)
			{
			case "false":
			case "true":
				return text == "true";
			case "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 <>7__wrap1;

		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();
				}
			}
			<>7__wrap1 = default(List<JSONNode>.Enumerator);
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			try
			{
				int num = <>1__state;
				JSONArray jSONArray = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>7__wrap1 = jSONArray.m_List.GetEnumerator();
					<>1__state = -3;
					break;
				case 1:
					<>1__state = -3;
					break;
				}
				if (<>7__wrap1.MoveNext())
				{
					JSONNode current = <>7__wrap1.Current;
					<>2__current = current;
					<>1__state = 1;
					return true;
				}
				<>m__Finally1();
				<>7__wrap1 = 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)<>7__wrap1).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;

	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()
			return new <get_Children>d__24(-2)
			{
				<>4__this = this
			};
		}
	}

	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 <>7__wrap1;

		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();
				}
			}
			<>7__wrap1 = default(Dictionary<string, JSONNode>.Enumerator);
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			try
			{
				int num = <>1__state;
				JSONObject jSONObject = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>7__wrap1 = jSONObject.m_Dict.GetEnumerator();
					<>1__state = -3;
					break;
				case 1:
					<>1__state = -3;
					break;
				}
				if (<>7__wrap1.MoveNext())
				{
					<>2__current = <>7__wrap1.Current.Value;
					<>1__state = 1;
					return true;
				}
				<>m__Finally1();
				<>7__wrap1 = 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)<>7__wrap1).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;

	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()
			return new <get_Children>d__27(-2)
			{
				<>4__this = this
			};
		}
	}

	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)
	{
		if (!(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))
		{
			return value is byte;
		}
		return true;
	}

	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;

	private string m_Key;

	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);
	}
}