Decompiled source of Crucible Modding Framework v1.1.0

plugins/Crucible.Core.dll

Decompiled 11 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using Microsoft.CodeAnalysis;
using RoboPhredDev.PotionCraft.Crucible.GameAPI;
using RoboPhredDev.PotionCraft.Crucible.Resources;
using RoboPhredDev.PotionCraft.Crucible.Yaml;
using UnityEngine;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization.NodeDeserializers;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("Crucible.Core")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Crucible.Core")]
[assembly: AssemblyTitle("Crucible.Core")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace RoboPhredDev.PotionCraft.Crucible
{
	public static class CrucibleLog
	{
		private static readonly Stack<string> LogScopeStack = new Stack<string>();

		public static void Log(string message, params object[] logParams)
		{
			WriteToLog(GetLogGUID(Assembly.GetCallingAssembly()), message, logParams);
		}

		public static void LogInScope(string modGUID, string message, params object[] logParams)
		{
			WriteToLog(modGUID, message, logParams);
		}

		public static void RunInLogScope(Assembly modAssembly, Action action)
		{
			RunInLogScope(GetLogGUID(modAssembly), action);
		}

		public static void RunInLogScope(string modGUID, Action action)
		{
			LogScopeStack.Push(modGUID);
			try
			{
				action();
			}
			finally
			{
				LogScopeStack.Pop();
			}
		}

		private static void WriteToLog(string modGUID, string message, params object[] logParams)
		{
			Debug.Log((object)("[" + modGUID + "]: " + string.Format(message, logParams)));
		}

		private static string GetLogGUID(Assembly assembly)
		{
			if (LogScopeStack.Count > 0)
			{
				return LogScopeStack.Peek();
			}
			BepInPlugin val = (from type in assembly.GetTypes()
				let attribute = (BepInPlugin)Attribute.GetCustomAttribute(type, typeof(BepInPlugin))
				where attribute != null
				select attribute).FirstOrDefault();
			if (val != null)
			{
				return val.GUID;
			}
			return assembly.FullName;
		}
	}
	public class CrucibleMissingDependencyException : Exception
	{
		public string ModGuid { get; }

		public string RequiredSemver { get; }

		public CrucibleMissingDependencyException(string message, string modGuid, string semver)
			: base(message)
		{
			ModGuid = modGuid;
			RequiredSemver = semver;
		}

		public static CrucibleMissingDependencyException CreateMissingDependencyException(string sourceGuid, string dependencyGuid, string semver)
		{
			return new CrucibleMissingDependencyException("Mod \"" + sourceGuid + "\" is missing required dependency \"" + dependencyGuid + "\"@" + semver + ".", dependencyGuid, semver);
		}

		public static CrucibleMissingDependencyException CreateBadVersionException(string sourceGuid, string dependencyGuid, string semver)
		{
			return new CrucibleMissingDependencyException("Mod \"" + sourceGuid + "\" is incompatible with dependency \"" + dependencyGuid + "\".  The mod requires a version matching \"" + semver + "\".", dependencyGuid, semver);
		}
	}
	[AttributeUsage(AttributeTargets.Class)]
	public class CrucibleRegistryAttributeAttribute : Attribute
	{
	}
	public static class CrucibleTypeRegistry
	{
		private static bool initialized;

		private static Dictionary<Type, HashSet<Type>> typesByAttribute;

		public static IEnumerable<Type> GetTypesByAttribute<T>()
		{
			return GetTypesByAttribute(typeof(T));
		}

		public static IEnumerable<Type> GetTypesByAttribute(Type t)
		{
			if (!typeof(Attribute).IsAssignableFrom(t))
			{
				throw new ArgumentException("The provided type must be an attribute.", "t");
			}
			if (t.GetCustomAttribute<CrucibleRegistryAttributeAttribute>() == null)
			{
				throw new ArgumentException("Target attribute must be marked with CrucibleRegistryAttributeAttribute.", "t");
			}
			EnsureTypesLoaded();
			if (typesByAttribute.TryGetValue(t, out var value))
			{
				return value.ToArray();
			}
			return new Type[0];
		}

		private static void EnsureTypesLoaded()
		{
			EnsureInitialized();
			if (typesByAttribute == null)
			{
				BuildTypesByAttribute();
			}
		}

		private static void EnsureInitialized()
		{
			if (!initialized)
			{
				initialized = true;
				AppDomain.CurrentDomain.AssemblyLoad += delegate
				{
					typesByAttribute = null;
				};
			}
		}

		private static void BuildTypesByAttribute()
		{
			Type[] array = GetCrucibleRegistryAttributes().ToArray();
			IEnumerable<Type> enumerable = from assembly in AppDomain.CurrentDomain.GetAssemblies()
				from type in assembly.GetTypes()
				select type;
			typesByAttribute = new Dictionary<Type, HashSet<Type>>();
			foreach (Type item in enumerable)
			{
				Type[] array2 = array;
				foreach (Type type2 in array2)
				{
					if (item.GetCustomAttribute(type2, inherit: true) != null)
					{
						if (!typesByAttribute.TryGetValue(type2, out var value))
						{
							value = new HashSet<Type>();
							typesByAttribute.Add(type2, value);
						}
						value.Add(item);
					}
				}
			}
		}

		private static IEnumerable<Type> GetCrucibleRegistryAttributes()
		{
			return from assembly in AppDomain.CurrentDomain.GetAssemblies()
				from type in assembly.GetTypes()
				where type.GetCustomAttribute<CrucibleRegistryAttributeAttribute>(inherit: true) != null
				select type;
		}
	}
	internal static class TypeExtensions
	{
		public static bool BaseTypeIncludes(this Type type, Type baseType)
		{
			do
			{
				if (type == baseType)
				{
					return true;
				}
			}
			while ((type = type.BaseType) != null);
			return false;
		}

		public static bool BaseTypeIncludesGeneric(this Type type, Type genericType, out Type genericInstantiation)
		{
			do
			{
				if (type.GetGenericTypeDefinition() == genericType)
				{
					genericInstantiation = type;
					return true;
				}
			}
			while ((type = type.BaseType) != null);
			genericInstantiation = null;
			return false;
		}
	}
}
namespace RoboPhredDev.PotionCraft.Crucible.Yaml
{
	public static class Deserializer
	{
		public static readonly INamingConvention NamingConvention = CamelCaseNamingConvention.Instance;

		private static readonly Stack<string> ParsingFiles = new Stack<string>();

		public static string CurrentFilePath
		{
			get
			{
				if (ParsingFiles.Count == 0)
				{
					return null;
				}
				return ParsingFiles.Peek();
			}
		}

		public static T DeserializeFromResource<T>(string resourcePath)
		{
			return WithResourceFileParser(resourcePath, (IParser parser) => BuildDeserializer().Deserialize<T>(parser));
		}

		public static object Deserialize(string resourcePath, Type type)
		{
			return WithResourceFileParser(resourcePath, (IParser parser) => BuildDeserializer().Deserialize(parser, type));
		}

		public static object DeserializeFromParser(string filePath, Type type, IParser parser)
		{
			ParsingFiles.Push(filePath);
			YamlException val = default(YamlException);
			try
			{
				return BuildDeserializer().Deserialize(parser, type);
			}
			catch (object obj) when (((Func<bool>)delegate
			{
				// Could not convert BlockContainer to single expression
				object obj2 = ((obj is YamlException) ? obj : null);
				System.Runtime.CompilerServices.Unsafe.SkipInit(out int result);
				if (obj2 == null)
				{
					result = 0;
				}
				else
				{
					val = (YamlException)obj2;
					result = ((!(val is YamlFileException)) ? 1 : 0);
				}
				return (byte)result != 0;
			}).Invoke())
			{
				throw new YamlFileException(CurrentFilePath, val.Start, val.End, ((Exception)(object)val).Message, (Exception)(object)val);
			}
			finally
			{
				ParsingFiles.Pop();
			}
		}

		public static object DeserializeFromParser(Type type, IParser parser)
		{
			return BuildDeserializer().Deserialize(parser, type);
		}

		public static T WithResourceFileParser<T>(string resourcePath, Func<IParser, T> func)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			ParsingFiles.Push(resourcePath);
			YamlException val = default(YamlException);
			try
			{
				MergingParser arg = new MergingParser((IParser)new Parser((TextReader)new StringReader(CrucibleResources.ReadAllText(resourcePath))));
				return func((IParser)(object)arg);
			}
			catch (object obj) when (((Func<bool>)delegate
			{
				// Could not convert BlockContainer to single expression
				object obj2 = ((obj is YamlException) ? obj : null);
				System.Runtime.CompilerServices.Unsafe.SkipInit(out int result);
				if (obj2 == null)
				{
					result = 0;
				}
				else
				{
					val = (YamlException)obj2;
					result = ((!(val is YamlFileException)) ? 1 : 0);
				}
				return (byte)result != 0;
			}).Invoke())
			{
				throw new YamlFileException(CurrentFilePath, val.Start, val.End, ((Exception)(object)val).Message, (Exception)(object)val);
			}
			finally
			{
				ParsingFiles.Pop();
			}
		}

		private static IDeserializer BuildDeserializer()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			DeserializerBuilder val = new DeserializerBuilder();
			((BuilderSkeleton<DeserializerBuilder>)(object)val).WithNamingConvention(NamingConvention).IgnoreUnmatchedProperties().WithNodeTypeResolver((INodeTypeResolver)(object)new ImportNodeTypeResolver(), (Action<IRegistrationLocationSelectionSyntax<INodeTypeResolver>>)delegate(IRegistrationLocationSelectionSyntax<INodeTypeResolver> s)
			{
				s.OnTop();
			})
				.WithNodeDeserializer((INodeDeserializer)(object)new ImportDeserializer(), (Action<IRegistrationLocationSelectionSyntax<INodeDeserializer>>)delegate(IRegistrationLocationSelectionSyntax<INodeDeserializer> s)
				{
					s.OnTop();
				})
				.WithNodeDeserializer((INodeDeserializer)(object)new DuckTypeDeserializer(), (Action<IRegistrationLocationSelectionSyntax<INodeDeserializer>>)delegate(IRegistrationLocationSelectionSyntax<INodeDeserializer> s)
				{
					s.OnTop();
				})
				.WithNodeDeserializer((INodeDeserializer)(object)new TypePropertyDeserializer(), (Action<IRegistrationLocationSelectionSyntax<INodeDeserializer>>)delegate(IRegistrationLocationSelectionSyntax<INodeDeserializer> s)
				{
					s.OnTop();
				});
			foreach (Type item in CrucibleTypeRegistry.GetTypesByAttribute<YamlDeserializerAttribute>())
			{
				object? obj = Activator.CreateInstance(item);
				INodeDeserializer val2 = (INodeDeserializer)((obj is INodeDeserializer) ? obj : null);
				if (val2 != null)
				{
					val.WithNodeDeserializer(val2, (Action<IRegistrationLocationSelectionSyntax<INodeDeserializer>>)delegate(IRegistrationLocationSelectionSyntax<INodeDeserializer> s)
					{
						s.OnTop();
					});
				}
			}
			val.WithNodeDeserializer<ExtendedObjectNodeDeserializer>((WrapperFactory<INodeDeserializer, ExtendedObjectNodeDeserializer>)((INodeDeserializer objectDeserializer) => new ExtendedObjectNodeDeserializer(objectDeserializer)), (Action<ITrackingRegistrationLocationSelectionSyntax<INodeDeserializer>>)delegate(ITrackingRegistrationLocationSelectionSyntax<INodeDeserializer> s)
			{
				s.InsteadOf<ObjectNodeDeserializer>();
			});
			return val.Build();
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true)]
	public class DuckTypeCandidateAttribute : Attribute
	{
		public Type CandidateType { get; }

		public DuckTypeCandidateAttribute(Type candidateType)
		{
			CandidateType = candidateType;
		}

		public static ICollection<Type> GetDuckCandidates(Type type)
		{
			return ((DuckTypeCandidateAttribute[])type.GetCustomAttributes(typeof(DuckTypeCandidateAttribute), inherit: false)).Select((DuckTypeCandidateAttribute attr) => attr.CandidateType).ToArray();
		}
	}
	internal class DuckTypeDeserializer : INodeDeserializer
	{
		public bool Deserialize(IParser reader, Type expectedType, Func<IParser, Type, object> nestedObjectDeserializer, out object value)
		{
			ICollection<Type> candidates = DuckTypeCandidateAttribute.GetDuckCandidates(expectedType);
			if (candidates.Count == 0)
			{
				value = null;
				return false;
			}
			if (ImportDeserializer.TryConsumeImport(reader, out var filePath))
			{
				value = Deserializer.WithResourceFileParser(filePath, delegate(IParser importParser)
				{
					ParserExtensions.Consume<StreamStart>(importParser);
					ParserExtensions.Consume<DocumentStart>(importParser);
					object result = DeserializeDuckType(importParser, expectedType, candidates, nestedObjectDeserializer);
					ParserExtensions.Consume<DocumentEnd>(importParser);
					ParserExtensions.Consume<StreamEnd>(importParser);
					return result;
				});
			}
			else
			{
				value = DeserializeDuckType(reader, expectedType, candidates, nestedObjectDeserializer);
			}
			return true;
		}

		private static object DeserializeDuckType(IParser reader, Type expectedType, ICollection<Type> candidates, Func<IParser, Type, object> nestedObjectDeserializer)
		{
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			ReplayParser replayParser = new ReplayParser();
			MappingStart val = ParserExtensions.Consume<MappingStart>(reader);
			replayParser.Enqueue((ParsingEvent)(object)val);
			List<string> list = new List<string>();
			MappingEnd val2 = default(MappingEnd);
			while (!ParserExtensions.TryConsume<MappingEnd>(reader, ref val2))
			{
				Scalar val3 = ParserExtensions.Consume<Scalar>(reader);
				list.Add(val3.Value);
				replayParser.Enqueue((ParsingEvent)(object)val3);
				int num = 0;
				do
				{
					ParsingEvent val4 = ParserExtensions.Consume<ParsingEvent>(reader);
					num += val4.NestingIncrease;
					replayParser.Enqueue(val4);
				}
				while (num > 0);
			}
			replayParser.Enqueue((ParsingEvent)(object)val2);
			Type type = ChooseType(candidates, list);
			if (type == null)
			{
				throw new YamlException(((ParsingEvent)val).Start, ((ParsingEvent)val2).End, "Cannot identify instance type for " + expectedType.Name + " based on its properties " + string.Join(", ", list) + ".  Must be one of: " + string.Join(", ", candidates.Select((Type x) => x.Name)));
			}
			replayParser.Start();
			return nestedObjectDeserializer((IParser)(object)replayParser, type);
		}

		private static Type ChooseType(ICollection<Type> candidates, IList<string> keys)
		{
			return (from candidate in candidates
				let yamlProperties = GetTypeYamlProperties(candidate)
				where !keys.Except(yamlProperties).Any()
				let matchCount = yamlProperties.Intersect(keys).Count()
				where matchCount > 0
				orderby matchCount descending
				select candidate).FirstOrDefault();
		}

		private static IReadOnlyList<string> GetTypeYamlProperties(Type type)
		{
			DuckTypeKeysAttribute duckTypeKeysAttribute = (DuckTypeKeysAttribute)type.GetCustomAttribute(typeof(DuckTypeKeysAttribute));
			if (duckTypeKeysAttribute != null)
			{
				return duckTypeKeysAttribute.Keys;
			}
			IEnumerable<string> first = from <>h__TransparentIdentifier1 in (from property in type.GetProperties(BindingFlags.Instance | BindingFlags.Public)
					select new
					{
						property = property,
						yamlAttribute = ((MemberInfo)property).GetCustomAttribute<YamlMemberAttribute>()
					}).Select(<>h__TransparentIdentifier0 =>
				{
					YamlMemberAttribute yamlAttribute2 = <>h__TransparentIdentifier0.yamlAttribute;
					return new
					{
						<>h__TransparentIdentifier0 = <>h__TransparentIdentifier0,
						name = (((yamlAttribute2 != null) ? yamlAttribute2.Alias : null) ?? Deserializer.NamingConvention.Apply(<>h__TransparentIdentifier0.property.Name))
					};
				})
				select <>h__TransparentIdentifier1.name;
			IEnumerable<string> second = from <>h__TransparentIdentifier1 in (from field in type.GetFields(BindingFlags.Instance | BindingFlags.Public)
					select new
					{
						field = field,
						yamlAttribute = ((MemberInfo)field).GetCustomAttribute<YamlMemberAttribute>()
					}).Select(<>h__TransparentIdentifier0 =>
				{
					YamlMemberAttribute yamlAttribute = <>h__TransparentIdentifier0.yamlAttribute;
					return new
					{
						<>h__TransparentIdentifier0 = <>h__TransparentIdentifier0,
						name = (((yamlAttribute != null) ? yamlAttribute.Alias : null) ?? Deserializer.NamingConvention.Apply(<>h__TransparentIdentifier0.field.Name))
					};
				})
				select <>h__TransparentIdentifier1.name;
			return first.Concat(second).ToList();
		}
	}
	[AttributeUsage(AttributeTargets.Class)]
	public class DuckTypeKeysAttribute : Attribute
	{
		public IReadOnlyList<string> Keys { get; }

		public DuckTypeKeysAttribute(string[] keys)
		{
			Keys = keys.ToList();
		}
	}
	public class ExtendedObjectNodeDeserializer : INodeDeserializer
	{
		private readonly INodeDeserializer nodeDeserializer;

		public ExtendedObjectNodeDeserializer(INodeDeserializer nodeDeserializer)
		{
			this.nodeDeserializer = nodeDeserializer;
		}

		public bool Deserialize(IParser reader, Type expectedType, Func<IParser, Type, object> nestedObjectDeserializer, out object value)
		{
			ReplayParser replayParser = ReplayParser.ParseObject(reader);
			reader = (IParser)(object)replayParser;
			Mark start = null;
			ParsingEvent val = default(ParsingEvent);
			if (ParserExtensions.Accept<ParsingEvent>(reader, ref val))
			{
				start = ((val != null) ? val.Start : null);
			}
			if (!nodeDeserializer.Deserialize(reader, expectedType, nestedObjectDeserializer, ref value))
			{
				return false;
			}
			ParsingEvent current = reader.Current;
			Mark end = ((current != null) ? current.End : null);
			if (value is IDeserializeExtraData deserializeExtraData)
			{
				replayParser.Reset();
				deserializeExtraData.OnDeserializeExtraData(replayParser);
			}
			if (value is IAfterYamlDeserialization afterYamlDeserialization)
			{
				afterYamlDeserialization.OnDeserializeCompleted(start, end);
			}
			return true;
		}
	}
	public interface IAfterYamlDeserialization
	{
		void OnDeserializeCompleted(Mark start, Mark end);
	}
	public interface IDeserializeExtraData
	{
		void OnDeserializeExtraData(ReplayParser parser);
	}
	internal class ImportDeserializer : INodeDeserializer
	{
		public static bool TryConsumeImport(IParser reader, out string filePath)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			NodeEvent val = default(NodeEvent);
			if (ParserExtensions.Accept<NodeEvent>(reader, ref val) && val.Tag == "!import")
			{
				ParserExtensions.Consume<NodeEvent>(reader);
				Scalar val2 = (Scalar)(object)((val is Scalar) ? val : null);
				if (val2 != null)
				{
					filePath = val2.Value;
				}
				else
				{
					filePath = ParserExtensions.Consume<Scalar>(reader).Value;
				}
				filePath = Path.Combine(Path.GetDirectoryName(Deserializer.CurrentFilePath), filePath);
				if (!CrucibleResources.Exists(filePath))
				{
					throw new YamlException(((ParsingEvent)val).Start, ((ParsingEvent)val).End, "Cannot import file \"" + filePath + "\" as the file does not exist in the current package.");
				}
				return true;
			}
			filePath = null;
			return false;
		}

		public bool Deserialize(IParser reader, Type expectedType, Func<IParser, Type, object> nestedObjectDeserializer, out object value)
		{
			if (TryConsumeImport(reader, out var filePath))
			{
				value = Deserializer.Deserialize(filePath, expectedType);
				return true;
			}
			value = null;
			return false;
		}
	}
	internal class ImportNodeTypeResolver : INodeTypeResolver
	{
		public bool Resolve(NodeEvent nodeEvent, ref Type currentType)
		{
			if (nodeEvent.Tag == "!import")
			{
				return true;
			}
			return false;
		}
	}
	public class OneOrMany<T> : IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable
	{
		private readonly List<T> contents;

		public int Count => contents.Count;

		public bool IsReadOnly => false;

		public T this[int index]
		{
			get
			{
				return contents[index];
			}
			set
			{
				contents[index] = value;
			}
		}

		public OneOrMany()
		{
			contents = new List<T>();
		}

		public OneOrMany(IEnumerable<T> source)
		{
			contents = source.ToList();
		}

		public OneOrMany(IEnumerable source)
		{
			contents = source.Cast<T>().ToList();
		}

		public void Add(T item)
		{
			contents.Add(item);
		}

		public void Clear()
		{
			contents.Clear();
		}

		public bool Contains(T item)
		{
			return contents.Contains(item);
		}

		public void CopyTo(T[] array, int arrayIndex)
		{
			contents.CopyTo(array, arrayIndex);
		}

		public IEnumerator<T> GetEnumerator()
		{
			return contents.GetEnumerator();
		}

		public int IndexOf(T item)
		{
			return contents.IndexOf(item);
		}

		public void Insert(int index, T item)
		{
			contents.Insert(index, item);
		}

		public bool Remove(T item)
		{
			return contents.Remove(item);
		}

		public void RemoveAt(int index)
		{
			contents.RemoveAt(index);
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return contents.GetEnumerator();
		}
	}
	public class ReplayParser : IParser
	{
		private readonly List<ParsingEvent> replayEvents = new List<ParsingEvent>();

		private IEnumerator<ParsingEvent> replayEnumerator;

		public ParsingEvent Current
		{
			get
			{
				if (replayEnumerator == null)
				{
					throw new InvalidOperationException("ReplayParser has not been activated.");
				}
				return replayEnumerator.Current;
			}
		}

		public static ReplayParser ParseObject(IParser reader)
		{
			ReplayParser replayParser = new ReplayParser();
			MappingStart parsingEvent = ParserExtensions.Consume<MappingStart>(reader);
			replayParser.Enqueue((ParsingEvent)(object)parsingEvent);
			List<string> list = new List<string>();
			MappingEnd parsingEvent2 = default(MappingEnd);
			while (!ParserExtensions.TryConsume<MappingEnd>(reader, ref parsingEvent2))
			{
				Scalar val = ParserExtensions.Consume<Scalar>(reader);
				list.Add(val.Value);
				replayParser.Enqueue((ParsingEvent)(object)val);
				int num = 0;
				do
				{
					ParsingEvent val2 = ParserExtensions.Consume<ParsingEvent>(reader);
					num += val2.NestingIncrease;
					replayParser.Enqueue(val2);
				}
				while (num > 0);
			}
			replayParser.Enqueue((ParsingEvent)(object)parsingEvent2);
			replayParser.Start();
			return replayParser;
		}

		public void Enqueue(ParsingEvent parsingEvent)
		{
			if (replayEnumerator != null)
			{
				throw new InvalidOperationException("Cannot enqueue to a ReplayParser that has already been started.");
			}
			replayEvents.Add(parsingEvent);
		}

		public void Start()
		{
			if (replayEnumerator != null)
			{
				throw new InvalidOperationException("This ReplayParser has already been started.");
			}
			replayEnumerator = replayEvents.GetEnumerator();
		}

		public void Reset()
		{
			replayEnumerator = replayEvents.GetEnumerator();
		}

		public bool MoveNext()
		{
			return replayEnumerator.MoveNext();
		}
	}
	[AttributeUsage(AttributeTargets.Class)]
	public class TypePropertyAttribute : Attribute
	{
		public string TypePropertyName { get; }

		public TypePropertyAttribute(string typePropertyName)
		{
			TypePropertyName = typePropertyName;
		}
	}
	[AttributeUsage(AttributeTargets.Class)]
	public class TypePropertyCandidateAttribute : Attribute
	{
		private static readonly Dictionary<Type, Dictionary<string, Type>> CandidateCache;

		public string TypeName { get; }

		static TypePropertyCandidateAttribute()
		{
			CandidateCache = new Dictionary<Type, Dictionary<string, Type>>();
			AppDomain.CurrentDomain.AssemblyLoad += delegate
			{
				CandidateCache.Clear();
			};
		}

		public TypePropertyCandidateAttribute(string typeName)
		{
			TypeName = typeName;
		}

		public static IDictionary<string, Type> GetCandidateTypes(Type baseType)
		{
			if (!CandidateCache.TryGetValue(baseType, out var value))
			{
				value = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
					from type in assembly.GetTypes()
					where baseType.IsAssignableFrom(type)
					let candidateAttribute = type.GetCustomAttribute<TypePropertyCandidateAttribute>()
					where candidateAttribute != null
					select new KeyValuePair<string, Type>(candidateAttribute.TypeName, type)).ToDictionary((KeyValuePair<string, Type> x) => x.Key, (KeyValuePair<string, Type> x) => x.Value);
				CandidateCache.Add(baseType, value);
			}
			return value;
		}
	}
	internal class TypePropertyDeserializer : INodeDeserializer
	{
		public bool Deserialize(IParser reader, Type expectedType, Func<IParser, Type, object> nestedObjectDeserializer, out object value)
		{
			TypePropertyAttribute typePropertyAttribute = expectedType.GetCustomAttribute<TypePropertyAttribute>(inherit: false);
			if (typePropertyAttribute == null || string.IsNullOrEmpty(typePropertyAttribute.TypePropertyName))
			{
				value = null;
				return false;
			}
			IDictionary<string, Type> candidates = TypePropertyCandidateAttribute.GetCandidateTypes(expectedType);
			if (ImportDeserializer.TryConsumeImport(reader, out var filePath))
			{
				value = Deserializer.WithResourceFileParser(filePath, delegate(IParser importParser)
				{
					ParserExtensions.Consume<StreamStart>(importParser);
					ParserExtensions.Consume<DocumentStart>(importParser);
					object result = DeserializeType(importParser, expectedType, typePropertyAttribute.TypePropertyName, candidates, nestedObjectDeserializer);
					ParserExtensions.Consume<DocumentEnd>(importParser);
					ParserExtensions.Consume<StreamEnd>(importParser);
					return result;
				});
			}
			else
			{
				value = DeserializeType(reader, expectedType, typePropertyAttribute.TypePropertyName, candidates, nestedObjectDeserializer);
			}
			return true;
		}

		private static object DeserializeType(IParser reader, Type expectedType, string typePropertyName, IDictionary<string, Type> candidates, Func<IParser, Type, object> nestedObjectDeserializer)
		{
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			ReplayParser replayParser = new ReplayParser();
			MappingStart val = ParserExtensions.Consume<MappingStart>(reader);
			replayParser.Enqueue((ParsingEvent)(object)val);
			string text = null;
			MappingEnd val2 = default(MappingEnd);
			while (!ParserExtensions.TryConsume<MappingEnd>(reader, ref val2))
			{
				Scalar val3 = ParserExtensions.Consume<Scalar>(reader);
				replayParser.Enqueue((ParsingEvent)(object)val3);
				if (val3.Value == typePropertyName)
				{
					Scalar val4 = ParserExtensions.Consume<Scalar>(reader);
					replayParser.Enqueue((ParsingEvent)(object)val4);
					text = val4.Value;
					continue;
				}
				int num = 0;
				do
				{
					ParsingEvent val5 = ParserExtensions.Consume<ParsingEvent>(reader);
					num += val5.NestingIncrease;
					replayParser.Enqueue(val5);
				}
				while (num > 0);
			}
			replayParser.Enqueue((ParsingEvent)(object)val2);
			if (!candidates.TryGetValue(text, out var value))
			{
				throw new YamlException(((ParsingEvent)val).Start, ((ParsingEvent)val2).End, "Cannot identify instance type for " + expectedType.Name + " based on its type property " + text + ".  Must be one of: " + string.Join(", ", candidates.Keys));
			}
			replayParser.Start();
			return nestedObjectDeserializer((IParser)(object)replayParser, value);
		}
	}
	[AttributeUsage(AttributeTargets.Class)]
	[CrucibleRegistryAttribute]
	public class YamlDeserializerAttribute : Attribute
	{
	}
	public static class YamlExceptionExtensions
	{
		public static string GetInnermostMessage(this YamlException exception)
		{
			Exception ex = (Exception)(object)exception;
			while (ex is YamlException && ex.InnerException != null)
			{
				ex = ex.InnerException;
			}
			return ex.Message;
		}
	}
	public class YamlFileException : YamlException
	{
		public string FilePath { get; }

		public YamlFileException(string filePath, string message)
			: base(message)
		{
			FilePath = filePath;
		}

		public YamlFileException(string filePath, Mark start, Mark end, string message)
			: base(start, end, message)
		{
			FilePath = filePath;
		}

		public YamlFileException(string filePath, Mark start, Mark end, string message, Exception innerException)
			: base(start, end, message, innerException)
		{
			FilePath = filePath;
		}

		public YamlFileException(string filePath, string message, Exception inner)
			: base(message, inner)
		{
			FilePath = filePath;
		}
	}
}
namespace RoboPhredDev.PotionCraft.Crucible.Yaml.Deserializers
{
	[YamlDeserializer]
	public class ColorDeserializer : INodeDeserializer
	{
		private class ColorParseObj
		{
			public float A { get; set; } = 1f;


			public float R { get; set; }

			public float G { get; set; }

			public float B { get; set; }
		}

		public bool Deserialize(IParser reader, Type expectedType, Func<IParser, Type, object> nestedObjectDeserializer, out object value)
		{
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			if (expectedType != typeof(Color) && Nullable.GetUnderlyingType(expectedType) != typeof(Color))
			{
				value = null;
				return false;
			}
			Scalar val = default(Scalar);
			if (ParserExtensions.TryConsume<Scalar>(reader, ref val))
			{
				string value2 = val.Value;
				if (value2.StartsWith("#"))
				{
					value2 = value2.Substring(1);
					if (value2.Length != 6)
					{
						throw new FormatException("Unknown color format.  Expected a hexadecimal string.");
					}
					if (!int.TryParse(value2, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var result))
					{
						throw new FormatException("Unknown color format.  Failed to parse hexadecimal value.");
					}
					value = (object)new Color
					{
						a = 1f,
						r = (float)(int)(byte)((result >> 16) & 0xFF) / 255f,
						g = (float)(int)(byte)((result >> 8) & 0xFF) / 255f,
						b = (float)(int)(byte)(result & 0xFF) / 255f
					};
					return true;
				}
				throw new FormatException("Unknown color format.  Expected a string starting with \"#\".");
			}
			ColorParseObj colorParseObj = (ColorParseObj)nestedObjectDeserializer(reader, typeof(ColorParseObj));
			value = (object)new Color(colorParseObj.R, colorParseObj.G, colorParseObj.B, colorParseObj.A);
			return true;
		}
	}
	[YamlDeserializer]
	public class LocalizedStringDeserializer : INodeDeserializer
	{
		public bool Deserialize(IParser reader, Type expectedType, Func<IParser, Type, object> nestedObjectDeserializer, out object value)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			if (expectedType != typeof(LocalizedString))
			{
				value = null;
				return false;
			}
			Scalar val = default(Scalar);
			if (ParserExtensions.TryConsume<Scalar>(reader, ref val))
			{
				value = (object)new LocalizedString(val.Value);
				return true;
			}
			Dictionary<string, string> dictionary = (Dictionary<string, string>)nestedObjectDeserializer(reader, typeof(Dictionary<string, string>));
			LocalizedString val2;
			if (dictionary.TryGetValue("default", out var value2))
			{
				val2 = new LocalizedString(value2);
				dictionary.Remove("default");
			}
			else
			{
				val2 = new LocalizedString();
			}
			foreach (KeyValuePair<string, string> item in dictionary)
			{
				val2.SetLocalization(item.Key, item.Value);
			}
			value = val2;
			return true;
		}
	}
	[YamlDeserializer]
	public class OneOrManyDeserializer : INodeDeserializer
	{
		public bool Deserialize(IParser reader, Type expectedType, Func<IParser, Type, object> nestedObjectDeserializer, out object value)
		{
			if (!expectedType.IsGenericType || expectedType.GetGenericTypeDefinition() != typeof(OneOrMany<>))
			{
				value = null;
				return false;
			}
			Type type = expectedType.GetGenericArguments()[0];
			SequenceStart val = default(SequenceStart);
			IEnumerable enumerable;
			if (ParserExtensions.Accept<SequenceStart>(reader, ref val))
			{
				enumerable = (IEnumerable)nestedObjectDeserializer(reader, typeof(List<>).MakeGenericType(type));
			}
			else
			{
				object value2 = nestedObjectDeserializer(reader, type);
				Array array = Array.CreateInstance(type, 1);
				array.SetValue(value2, 0);
				enumerable = array;
			}
			object[] args = new IEnumerable[1] { enumerable };
			value = Activator.CreateInstance(expectedType, args);
			return true;
		}
	}
	[YamlDeserializer]
	public class SpriteDeserializer : INodeDeserializer
	{
		internal class SpriteData
		{
			public Texture2D Texture { get; set; }

			public Vector2? Pivot { get; set; }
		}

		public bool Deserialize(IParser reader, Type expectedType, Func<IParser, Type, object> nestedObjectDeserializer, out object value)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			if (!typeof(Sprite).IsAssignableFrom(expectedType))
			{
				value = null;
				return false;
			}
			if (TryDeserializeFilename(reader, out value))
			{
				return true;
			}
			SpriteData spriteData = (SpriteData)nestedObjectDeserializer(reader, typeof(SpriteData));
			Texture2D texture = spriteData.Texture;
			if ((Object)(object)texture == (Object)null)
			{
				throw new Exception("Sprite must specify a texture.");
			}
			Sprite val = Sprite.Create(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), (Vector2)(((??)spriteData.Pivot) ?? new Vector2(0.5f, 0.5f)));
			((Object)val).name = ((Object)texture).name;
			value = val;
			return true;
		}

		private bool TryDeserializeFilename(IParser reader, out object value)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			Scalar val = default(Scalar);
			if (!ParserExtensions.TryConsume<Scalar>(reader, ref val))
			{
				value = null;
				return false;
			}
			string value2 = val.Value;
			byte[] array = CrucibleResources.ReadAllBytes(value2);
			Texture2D val2 = new Texture2D(0, 0, (TextureFormat)5, false, false)
			{
				filterMode = (FilterMode)1
			};
			if (!ImageConversion.LoadImage(val2, array))
			{
				throw new CrucibleResourceException("Failed to load image from resource at \"" + value2 + "\".");
			}
			Sprite val3 = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f));
			((Object)val3).name = value2;
			value = val3;
			return true;
		}
	}
	[YamlDeserializer]
	public class Texture2DDeserializer : INodeDeserializer
	{
		public bool Deserialize(IParser reader, Type expectedType, Func<IParser, Type, object> nestedObjectDeserializer, out object value)
		{
			if (!typeof(Texture2D).IsAssignableFrom(expectedType))
			{
				value = null;
				return false;
			}
			if (TryDeserializeFilename(reader, out value))
			{
				return true;
			}
			value = null;
			return false;
		}

		private bool TryDeserializeFilename(IParser reader, out object value)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			Scalar val = default(Scalar);
			if (!ParserExtensions.TryConsume<Scalar>(reader, ref val))
			{
				value = null;
				return false;
			}
			string value2 = val.Value;
			byte[] array = CrucibleResources.ReadAllBytes(value2);
			Texture2D val2 = new Texture2D(0, 0, (TextureFormat)5, false, false)
			{
				filterMode = (FilterMode)1
			};
			if (!ImageConversion.LoadImage(val2, array))
			{
				throw new CrucibleResourceException("Failed to load image from resource at \"" + value2 + "\".");
			}
			((Object)val2).name = value2;
			value = val2;
			return true;
		}
	}
	[YamlDeserializer]
	public class Vector2Deserializer : INodeDeserializer
	{
		private class Vector2ParseObj
		{
			public float X { get; set; }

			public float Y { get; set; }
		}

		public bool Deserialize(IParser reader, Type expectedType, Func<IParser, Type, object> nestedObjectDeserializer, out object value)
		{
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			if (expectedType != typeof(Vector2) && Nullable.GetUnderlyingType(expectedType) != typeof(Vector2))
			{
				value = null;
				return false;
			}
			Scalar val = default(Scalar);
			if (ParserExtensions.TryConsume<Scalar>(reader, ref val))
			{
				float[] array;
				try
				{
					array = (from x in val.Value.Split(new char[1] { ',' })
						select x.Trim() into x
						select float.Parse(x, CultureInfo.InvariantCulture)).ToArray();
				}
				catch
				{
					throw new FormatException("Invalid vector value.  Expected two floating point numbers.");
				}
				if (array.Length != 2)
				{
					throw new FormatException("Invalid vector value.  Expected two floating point numbers.");
				}
				value = (object)new Vector2(array[0], array[1]);
				return true;
			}
			Vector2ParseObj vector2ParseObj = (Vector2ParseObj)nestedObjectDeserializer(reader, typeof(Vector2ParseObj));
			value = (object)new Vector2(vector2ParseObj.X, vector2ParseObj.Y);
			return true;
		}
	}
}
namespace RoboPhredDev.PotionCraft.Crucible.SVG
{
	public class SvgPath
	{
		public string Data { get; set; }

		public Vector2 Scale { get; set; } = Vector2.one;


		public SvgPath()
		{
		}//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)


		public SvgPath(string path)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Data = path;
		}

		public IEnumerable<CrucibleBezierCurve> ToPathSegments()
		{
			string path = Data;
			Vector2 scale = new Vector2(Scale.x, Scale.y * -1f);
			Vector2 lastEnd = Vector2.zero;
			CrucibleBezierCurve val;
			while ((val = PartToCurve(ref path, lastEnd)) != null)
			{
				val.P1 *= scale;
				val.P2 *= scale;
				val.End *= scale;
				lastEnd = ((!val.IsRelative) ? val.End : (lastEnd + val.End));
				yield return val;
			}
		}

		public List<Vector2> ToPoints()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			string svgPath = Data;
			Vector2 partStart = Vector2.zero;
			Vector2 figureStart = Vector2.zero;
			List<Vector2> list = new List<Vector2>();
			bool flag = true;
			Vector2[] array;
			while ((array = PartToPoints(ref svgPath, ref partStart, ref figureStart)) != null)
			{
				if (array.Length == 0)
				{
					flag = true;
				}
				else if (flag)
				{
					flag = false;
					list.Add(figureStart);
				}
				list.AddRange(array);
			}
			Vector2 negY = new Vector2(1f, -1f);
			return list.ConvertAll((Vector2 x) => x * Scale * negY);
		}

		private static string GetToken(ref string svgPath)
		{
			StringBuilder stringBuilder = new StringBuilder();
			int i = 0;
			bool? flag = null;
			for (; i < svgPath.Length; i++)
			{
				char c = svgPath[i];
				if (c == ' ' || c == ',' || c == '\n' || c == '\r')
				{
					if (stringBuilder.Length > 0)
					{
						break;
					}
					continue;
				}
				if (!flag.HasValue)
				{
					flag = char.IsLetter(c);
				}
				else if (char.IsLetter(c) != flag.Value)
				{
					break;
				}
				stringBuilder.Append(c);
			}
			svgPath = svgPath.Substring(i);
			if (stringBuilder.Length == 0)
			{
				return null;
			}
			return stringBuilder.ToString();
		}

		private static float GetFloatTokenOrFail(ref string svgPath)
		{
			string token = GetToken(ref svgPath);
			if (!float.TryParse(token, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
			{
				throw new Exception("Failed to parse decimal value: \"" + token + "\".");
			}
			return result;
		}

		private static Vector2[] PartToPoints(ref string svgPath, ref Vector2 partStart, ref Vector2 figureStart)
		{
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			string token = GetToken(ref svgPath);
			if (token == null)
			{
				return null;
			}
			switch (token)
			{
			case "M":
				return AbsoluteMoveToPoints(ref svgPath, ref partStart, ref figureStart);
			case "L":
				return UpdatePartStart(AbsoluteLineToPoints(ref svgPath), ref partStart);
			case "H":
				return UpdatePartStart(RelativeLineToPoints(ref svgPath, partStart), ref partStart);
			case "V":
				return UpdatePartStart(AbsoluteVerticalToPoints(ref svgPath, partStart), ref partStart);
			case "C":
				return UpdatePartStart(AbsoluteCubicCurveToPoints(ref svgPath), ref partStart);
			case "m":
				return RelativeMoveToPoints(ref svgPath, ref partStart, ref figureStart);
			case "l":
				return UpdatePartStart(RelativeLineToPoints(ref svgPath, partStart), ref partStart);
			case "v":
				return UpdatePartStart(RelativeVerticalToPoints(ref svgPath, partStart), ref partStart);
			case "h":
				return UpdatePartStart(RelativeHorizontalToPoints(ref svgPath, partStart), ref partStart);
			case "c":
				return UpdatePartStart(RelativeCubicCurveToPoints(ref svgPath, partStart), ref partStart);
			case "Z":
			case "z":
				return ClosePoints(ref svgPath, ref partStart, ref figureStart);
			default:
				throw new Exception("Unsupported SVG path command \"" + token + "\".");
			}
		}

		private static Vector2[] UpdatePartStart(Vector2[] result, ref Vector2 partStart)
		{
			//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)
			partStart = result.Last();
			return result;
		}

		private static CrucibleBezierCurve PartToCurve(ref string svgPath, Vector2 start)
		{
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			string token = GetToken(ref svgPath);
			if (token == null)
			{
				return null;
			}
			switch (token)
			{
			case "M":
			case "L":
				return AbsoluteLineToCurve(ref svgPath);
			case "H":
				return AbsoluteHorizontalToCurve(ref svgPath, start);
			case "V":
				return AbsoluteVerticalToCurve(ref svgPath, start);
			case "C":
				return AbsoluteCubicCurveToCurve(ref svgPath);
			case "m":
			case "l":
				return RelativeLineToCurve(ref svgPath);
			case "v":
				return RelativeVerticalToCurve(ref svgPath);
			case "h":
				return RelativeHorizontalToCurve(ref svgPath);
			case "c":
				return RelativeCubicCurveToCurve(ref svgPath);
			default:
				throw new Exception("Unsupported SVG path command \"" + token + "\".");
			}
		}

		private static Vector2[] AbsoluteMoveToPoints(ref string svgPath, ref Vector2 partStart, ref Vector2 figureStart)
		{
			//IL_0014: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(GetFloatTokenOrFail(ref svgPath), GetFloatTokenOrFail(ref svgPath));
			partStart = val;
			figureStart = val;
			return (Vector2[])(object)new Vector2[0];
		}

		private static Vector2[] RelativeMoveToPoints(ref string svgPath, ref Vector2 partStart, ref Vector2 figureStart)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(GetFloatTokenOrFail(ref svgPath), GetFloatTokenOrFail(ref svgPath));
			partStart += val;
			figureStart = partStart;
			return (Vector2[])(object)new Vector2[0];
		}

		private static CrucibleBezierCurve AbsoluteLineToCurve(ref string svgPath)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return CrucibleBezierCurve.LineTo(new Vector2(GetFloatTokenOrFail(ref svgPath), GetFloatTokenOrFail(ref svgPath)));
		}

		private static Vector2[] AbsoluteLineToPoints(ref string svgPath)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(GetFloatTokenOrFail(ref svgPath), GetFloatTokenOrFail(ref svgPath));
			return (Vector2[])(object)new Vector2[1] { val };
		}

		private static CrucibleBezierCurve RelativeLineToCurve(ref string svgPath)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return CrucibleBezierCurve.RelativeLineTo(new Vector2(GetFloatTokenOrFail(ref svgPath), GetFloatTokenOrFail(ref svgPath)));
		}

		private static Vector2[] RelativeLineToPoints(ref string svgPath, Vector2 start)
		{
			//IL_0008: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(GetFloatTokenOrFail(ref svgPath) + start.x, GetFloatTokenOrFail(ref svgPath) + start.y);
			return (Vector2[])(object)new Vector2[1] { val };
		}

		private static CrucibleBezierCurve AbsoluteHorizontalToCurve(ref string svgPath, Vector2 start)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return CrucibleBezierCurve.LineTo(new Vector2(GetFloatTokenOrFail(ref svgPath), start.y));
		}

		private static CrucibleBezierCurve RelativeHorizontalToCurve(ref string svgPath)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			return CrucibleBezierCurve.RelativeLineTo(new Vector2(GetFloatTokenOrFail(ref svgPath), 0f));
		}

		private static Vector2[] RelativeHorizontalToPoints(ref string svgPath, Vector2 start)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(GetFloatTokenOrFail(ref svgPath) + start.x, start.y);
			return (Vector2[])(object)new Vector2[1] { val };
		}

		private static CrucibleBezierCurve AbsoluteVerticalToCurve(ref string svgPath, Vector2 start)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return CrucibleBezierCurve.LineTo(new Vector2(start.x, GetFloatTokenOrFail(ref svgPath)));
		}

		private static Vector2[] AbsoluteVerticalToPoints(ref string svgPath, Vector2 start)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(start.x, GetFloatTokenOrFail(ref svgPath));
			return (Vector2[])(object)new Vector2[1] { val };
		}

		private static CrucibleBezierCurve RelativeVerticalToCurve(ref string svgPath)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			return CrucibleBezierCurve.RelativeLineTo(new Vector2(0f, GetFloatTokenOrFail(ref svgPath)));
		}

		private static Vector2[] RelativeVerticalToPoints(ref string svgPath, Vector2 start)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(start.x, GetFloatTokenOrFail(ref svgPath) + start.y);
			return (Vector2[])(object)new Vector2[1] { val };
		}

		private static CrucibleBezierCurve AbsoluteCubicCurveToCurve(ref string svgPath)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = new Vector2(GetFloatTokenOrFail(ref svgPath), GetFloatTokenOrFail(ref svgPath));
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(GetFloatTokenOrFail(ref svgPath), GetFloatTokenOrFail(ref svgPath));
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(GetFloatTokenOrFail(ref svgPath), GetFloatTokenOrFail(ref svgPath));
			return CrucibleBezierCurve.CurveTo(val, val2, val3);
		}

		private static Vector2[] AbsoluteCubicCurveToPoints(ref string svgPath)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(GetFloatTokenOrFail(ref svgPath), GetFloatTokenOrFail(ref svgPath));
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(GetFloatTokenOrFail(ref svgPath), GetFloatTokenOrFail(ref svgPath));
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(GetFloatTokenOrFail(ref svgPath), GetFloatTokenOrFail(ref svgPath));
			return (Vector2[])(object)new Vector2[3] { val, val2, val3 };
		}

		private static CrucibleBezierCurve RelativeCubicCurveToCurve(ref string svgPath)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = new Vector2(GetFloatTokenOrFail(ref svgPath), GetFloatTokenOrFail(ref svgPath));
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(GetFloatTokenOrFail(ref svgPath), GetFloatTokenOrFail(ref svgPath));
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(GetFloatTokenOrFail(ref svgPath), GetFloatTokenOrFail(ref svgPath));
			return CrucibleBezierCurve.RelativeCurveTo(val, val2, val3);
		}

		private static Vector2[] RelativeCubicCurveToPoints(ref string svgPath, Vector2 start)
		{
			//IL_0008: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(GetFloatTokenOrFail(ref svgPath) + start.x, GetFloatTokenOrFail(ref svgPath) + start.y);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(GetFloatTokenOrFail(ref svgPath) + start.x, GetFloatTokenOrFail(ref svgPath) + start.y);
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(GetFloatTokenOrFail(ref svgPath) + start.x, GetFloatTokenOrFail(ref svgPath) + start.y);
			return (Vector2[])(object)new Vector2[3] { val, val2, val3 };
		}

		private static Vector2[] ClosePoints(ref string svgPath, ref Vector2 partStart, ref Vector2 figureStart)
		{
			//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_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			partStart = figureStart;
			return (Vector2[])(object)new Vector2[1] { figureStart };
		}
	}
	[YamlDeserializer]
	public class SvgPathDeserializer : INodeDeserializer
	{
		private bool suppressDeserializer;

		public bool Deserialize(IParser reader, Type expectedType, Func<IParser, Type, object> nestedObjectDeserializer, out object value)
		{
			if (suppressDeserializer)
			{
				value = null;
				return false;
			}
			if (expectedType != typeof(SvgPath))
			{
				value = null;
				return false;
			}
			Scalar val = default(Scalar);
			if (ParserExtensions.TryConsume<Scalar>(reader, ref val))
			{
				value = new SvgPath(val.Value);
				return true;
			}
			suppressDeserializer = true;
			try
			{
				value = nestedObjectDeserializer(reader, typeof(SvgPath));
				return true;
			}
			finally
			{
				suppressDeserializer = false;
			}
		}
	}
}
namespace RoboPhredDev.PotionCraft.Crucible.Resources
{
	public class CrucibleResourceException : Exception
	{
		public string ResourceName { get; set; }

		public CrucibleResourceException(string message)
			: base(message)
		{
		}
	}
	public static class CrucibleResources
	{
		private static readonly Stack<ICrucibleResourceProvider> ResourceProviderStack = new Stack<ICrucibleResourceProvider>();

		public static ICrucibleResourceProvider CurrentResourceProvider
		{
			get
			{
				if (ResourceProviderStack.Count == 0)
				{
					return null;
				}
				return ResourceProviderStack.Peek();
			}
		}

		public static bool Exists(string resourceName)
		{
			if (CurrentResourceProvider == null)
			{
				throw new CrucibleResourceException("No resource provider is active.")
				{
					ResourceName = resourceName
				};
			}
			return CurrentResourceProvider.Exists(resourceName);
		}

		public static string ReadAllText(string resourceName)
		{
			if (CurrentResourceProvider == null)
			{
				throw new CrucibleResourceException("No resource provider is active.")
				{
					ResourceName = resourceName
				};
			}
			return CurrentResourceProvider.ReadAllText(resourceName);
		}

		public static byte[] ReadAllBytes(string resourceName)
		{
			if (CurrentResourceProvider == null)
			{
				throw new CrucibleResourceException("No resource provider is active.")
				{
					ResourceName = resourceName
				};
			}
			return CurrentResourceProvider.ReadAllBytes(resourceName);
		}

		public static void WithResourceProvider(ICrucibleResourceProvider provider, Action action)
		{
			ResourceProviderStack.Push(provider);
			try
			{
				action();
			}
			finally
			{
				ResourceProviderStack.Pop();
			}
		}

		public static T WithResourceProvider<T>(ICrucibleResourceProvider provider, Func<T> action)
		{
			ResourceProviderStack.Push(provider);
			try
			{
				return action();
			}
			finally
			{
				ResourceProviderStack.Pop();
			}
		}
	}
	public class DirectoryResourceProvider : ICrucibleResourceProvider
	{
		private readonly string rootPath;

		public DirectoryResourceProvider(string directory)
		{
			rootPath = Path.GetFullPath(directory);
		}

		public bool Exists(string resourcePath)
		{
			return File.Exists(Path.Combine(rootPath, resourcePath));
		}

		public byte[] ReadAllBytes(string resource)
		{
			return File.ReadAllBytes(GetResourcePath(resource));
		}

		public string ReadAllText(string resource)
		{
			return File.ReadAllText(GetResourcePath(resource));
		}

		private string GetResourcePath(string resource)
		{
			string fullPath = Path.GetFullPath(Path.Combine(rootPath, resource));
			if (!fullPath.StartsWith(rootPath))
			{
				throw new CrucibleResourceException("The request resource \"" + resource + "\" is outside of the mod directory \"" + rootPath + "\".")
				{
					ResourceName = resource
				};
			}
			return fullPath;
		}
	}
	public interface ICrucibleResourceProvider
	{
		bool Exists(string resourceName);

		string ReadAllText(string resourceName);

		byte[] ReadAllBytes(string resourceName);
	}
	public class RelativeResourceProvider : ICrucibleResourceProvider
	{
		public ICrucibleResourceProvider Parent { get; }

		public string RelativePath { get; }

		public RelativeResourceProvider(ICrucibleResourceProvider parent, string relativePath)
		{
			Parent = parent;
			RelativePath = relativePath;
		}

		public bool Exists(string resourceName)
		{
			return Parent.Exists(Path.Combine(RelativePath, resourceName));
		}

		public byte[] ReadAllBytes(string resourceName)
		{
			resourceName = Path.Combine(RelativePath, resourceName);
			return Parent.ReadAllBytes(resourceName);
		}

		public string ReadAllText(string resourceName)
		{
			resourceName = Path.Combine(RelativePath, resourceName);
			return Parent.ReadAllText(resourceName);
		}
	}
	public class ZipResourceProvider : ICrucibleResourceProvider
	{
		private readonly ZipArchive zip;

		public ZipResourceProvider(string zipFilePath)
		{
			zip = ZipFile.OpenRead(zipFilePath);
		}

		public bool Exists(string resourceName)
		{
			return zip.Entries.Any((ZipArchiveEntry x) => x.FullName == resourceName);
		}

		public byte[] ReadAllBytes(string resourceName)
		{
			ZipArchiveEntry zipArchiveEntry = zip.Entries.FirstOrDefault((ZipArchiveEntry x) => x.FullName == resourceName);
			if (zipArchiveEntry == null)
			{
				throw new FileNotFoundException("Resource " + resourceName + " not found in zip file.");
			}
			using MemoryStream memoryStream = new MemoryStream();
			using Stream stream = zipArchiveEntry.Open();
			stream.CopyTo(memoryStream);
			return memoryStream.ToArray();
		}

		public string ReadAllText(string resourceName)
		{
			using Stream stream = (zip.Entries.FirstOrDefault((ZipArchiveEntry x) => x.FullName == resourceName) ?? throw new FileNotFoundException("Resource " + resourceName + " not found in zip file.")).Open();
			using StreamReader streamReader = new StreamReader(stream);
			return streamReader.ReadToEnd();
		}
	}
}
namespace RoboPhredDev.PotionCraft.Crucible.CruciblePackages
{
	public class CruciblePackageBepInExDependencyConfig : CruciblePackageDependencyConfig
	{
		public string BepInExGUID { get; set; }

		public override void EnsureDependencyMet()
		{
			if (!BepInExPluginUtilities.GetAllPlugins().Any((BepInPlugin x) => x.GUID == BepInExGUID))
			{
				throw CrucibleMissingDependencyException.CreateMissingDependencyException(base.PackageMod.GUID, BepInExGUID, "*");
			}
		}
	}
	public static class CruciblePackageConfigElementRegistry
	{
		private static readonly HashSet<Type> WarnedTypes = new HashSet<Type>();

		public static IEnumerable<Type> GetConfigRoots()
		{
			foreach (Type item in CrucibleTypeRegistry.GetTypesByAttribute<CruciblePackageConfigRootAttribute>())
			{
				if (!typeof(CruciblePackageConfigRoot).IsAssignableFrom(item))
				{
					WarnMisimplementedRoot(item);
				}
				yield return item;
			}
		}

		public static IEnumerable<Type> GetSubjectExtensionTypes<TSubject>()
		{
			var enumerable = from candidate in CrucibleTypeRegistry.GetTypesByAttribute<CruciblePackageConfigExtensionAttribute>()
				let attribute = (CruciblePackageConfigExtensionAttribute)Attribute.GetCustomAttribute(candidate, typeof(CruciblePackageConfigExtensionAttribute))
				where attribute.SubjectType.IsAssignableFrom(typeof(TSubject))
				select new
				{
					Type = candidate,
					Attribute = attribute
				};
			foreach (var item in enumerable)
			{
				if (VerifySubjectExtension(item.Type, item.Attribute))
				{
					yield return item.Type;
				}
			}
		}

		private static bool VerifySubjectExtension(Type classType, CruciblePackageConfigExtensionAttribute extensionAttribute)
		{
			if (!typeof(ICruciblePackageConfigExtension<>).MakeGenericType(extensionAttribute.SubjectType).IsAssignableFrom(classType) || !classType.BaseTypeIncludes(typeof(CruciblePackageConfigNode)))
			{
				WarnMisimplementedExtension(classType, extensionAttribute.SubjectType);
				return false;
			}
			return true;
		}

		private static void WarnMisimplementedRoot(Type type)
		{
			if (WarnedTypes.Add(type))
			{
				CrucibleLog.LogInScope("net.robophreddev.PotionCraft.Crucible", "Cannot use " + type.FullName + " as a config root because it lacks the appropriate " + typeof(CruciblePackageConfigRoot).Name + " interface.");
			}
		}

		private static void WarnMisimplementedExtension(Type type, Type subjectType)
		{
			if (WarnedTypes.Add(type))
			{
				CrucibleLog.LogInScope("net.robophreddev.PotionCraft.Crucible", "Cannot use " + type.FullName + " as a config extension for " + subjectType.Name + " because it either lacks the appropriate " + typeof(ICruciblePackageConfigExtension<>).Name + " interface, specifies the wrong TSubject, or does not implement CruciblePackageConfigNode.");
			}
		}
	}
	[AttributeUsage(AttributeTargets.Class)]
	[CrucibleRegistryAttribute]
	public class CruciblePackageConfigExtensionAttribute : Attribute
	{
		public Type SubjectType { get; }

		public CruciblePackageConfigExtensionAttribute(Type subject)
		{
			SubjectType = subject;
		}
	}
	public abstract class CruciblePackageConfigNode : IAfterYamlDeserialization
	{
		public CruciblePackageMod PackageMod { get; private set; }

		void IAfterYamlDeserialization.OnDeserializeCompleted(Mark start, Mark end)
		{
			CruciblePackageMod.OnNodeLoaded(this);
			OnDeserializeCompleted(start, end);
		}

		internal void SetParentMod(CruciblePackageMod packageMod)
		{
			PackageMod = packageMod;
		}

		protected virtual void OnDeserializeCompleted(Mark start, Mark end)
		{
		}
	}
	public abstract class CruciblePackageConfigRoot : CruciblePackageConfigNode
	{
		public abstract void ApplyConfiguration();
	}
	[AttributeUsage(AttributeTargets.Class)]
	[CrucibleRegistryAttribute]
	public class CruciblePackageConfigRootAttribute : Attribute
	{
	}
	public abstract class CruciblePackageConfigSubjectNode<TSubject> : CruciblePackageConfigNode, IDeserializeExtraData
	{
		private readonly List<ICruciblePackageConfigExtension<TSubject>> extensions = new List<ICruciblePackageConfigExtension<TSubject>>();

		public TSubject Subject { get; private set; }

		public void ApplyConfiguration()
		{
			Subject = GetSubject();
			OnApplyConfiguration(Subject);
			foreach (ICruciblePackageConfigExtension<TSubject> extension in extensions)
			{
				extension.OnApplyConfiguration(Subject);
			}
		}

		void IDeserializeExtraData.OnDeserializeExtraData(ReplayParser parser)
		{
			extensions.Clear();
			foreach (Type subjectExtensionType in CruciblePackageConfigElementRegistry.GetSubjectExtensionTypes<TSubject>())
			{
				parser.Reset();
				ICruciblePackageConfigExtension<TSubject> item = (ICruciblePackageConfigExtension<TSubject>)Deserializer.DeserializeFromParser(subjectExtensionType, (IParser)(object)parser);
				extensions.Add(item);
			}
		}

		protected abstract TSubject GetSubject();

		protected abstract void OnApplyConfiguration(TSubject subject);
	}
	[DuckTypeCandidate(typeof(CruciblePackageBepInExDependencyConfig))]
	public abstract class CruciblePackageDependencyConfig : CruciblePackageConfigNode
	{
		public abstract void EnsureDependencyMet();
	}
	public sealed class CruciblePackageMod : ICrucibleResourceProvider
	{
		private static List<CruciblePackageConfigNode> loadingNodes;

		private ICrucibleResourceProvider resources;

		private CruciblePackageModConfig parsedData;

		public string Name => parsedData.Name ?? ID;

		public string Author => parsedData.Author;

		public string Version => parsedData.Version;

		public List<CruciblePackageDependencyConfig> Dependencies => parsedData.Dependencies;

		public string ID { get; }

		public string GUID => "Crucible::$" + ID;

		public string Namespace => ID;

		public ICollection<CruciblePackageConfigRoot> Roots => parsedData.ParsedRoots;

		private CruciblePackageMod(string id, ICrucibleResourceProvider resourceProvider)
		{
			ID = id;
			resources = resourceProvider;
		}

		public static CruciblePackageMod LoadFromFolder(string directory)
		{
			loadingNodes = new List<CruciblePackageConfigNode>();
			try
			{
				CruciblePackageMod mod = new CruciblePackageMod(new DirectoryInfo(directory).Name, new DirectoryResourceProvider(directory));
				mod.parsedData = CrucibleResources.WithResourceProvider(mod, () => Deserializer.DeserializeFromResource<CruciblePackageModConfig>("package.yml"));
				loadingNodes.ForEach(delegate(CruciblePackageConfigNode x)
				{
					x.SetParentMod(mod);
				});
				return mod;
			}
			catch (Exception ex)
			{
				throw new CruciblePackageModLoadException("Failed to load crucible package from \"" + directory + "\": " + ex.Message, ex);
			}
			finally
			{
				loadingNodes = null;
			}
		}

		public static CruciblePackageMod LoadFromZip(string zipFilePath)
		{
			loadingNodes = new List<CruciblePackageConfigNode>();
			try
			{
				CruciblePackageMod mod = new CruciblePackageMod(Path.GetFileNameWithoutExtension(zipFilePath), new ZipResourceProvider(zipFilePath));
				mod.parsedData = CrucibleResources.WithResourceProvider(mod, () => Deserializer.DeserializeFromResource<CruciblePackageModConfig>("package.yml"));
				loadingNodes.ForEach(delegate(CruciblePackageConfigNode x)
				{
					x.SetParentMod(mod);
				});
				return mod;
			}
			catch (Exception ex)
			{
				throw new CruciblePackageModLoadException("Failed to load crucible package from \"" + zipFilePath + "\": " + ex.Message, ex);
			}
			finally
			{
				loadingNodes = null;
			}
		}

		public bool Exists(string resourceName)
		{
			return resources.Exists(resourceName);
		}

		public string ReadAllText(string resourceName)
		{
			return resources.ReadAllText(resourceName);
		}

		public byte[] ReadAllBytes(string resourceName)
		{
			return resources.ReadAllBytes(resourceName);
		}

		public void EnsureDependenciesMet()
		{
			if (Dependencies == null)
			{
				return;
			}
			foreach (CruciblePackageDependencyConfig dependency in Dependencies)
			{
				dependency.EnsureDependencyMet();
			}
		}

		public void ApplyConfiguration()
		{
			CrucibleResources.WithResourceProvider(this, delegate
			{
				CrucibleLog.RunInLogScope(Namespace, delegate
				{
					parsedData.ParsedRoots.ForEach(delegate(CruciblePackageConfigRoot x)
					{
						x.ApplyConfiguration();
					});
				});
			});
		}

		public override string ToString()
		{
			return ID + " (" + Namespace + ")";
		}

		internal static void OnNodeLoaded(CruciblePackageConfigNode node)
		{
			if (loadingNodes == null)
			{
				throw new Exception("Cannot instantiate a CruciblePackageConfigNode when no CruciblePackageMod is being loaded.");
			}
			loadingNodes.Add(node);
		}
	}
	public class CruciblePackageModConfig : IDeserializeExtraData
	{
		public List<CruciblePackageConfigRoot> ParsedRoots { get; } = new List<CruciblePackageConfigRoot>();


		public string Name { get; set; }

		public string Author { get; set; }

		public string Version { get; set; }

		public List<CruciblePackageDependencyConfig> Dependencies { get; set; } = new List<CruciblePackageDependencyConfig>();


		void IDeserializeExtraData.OnDeserializeExtraData(ReplayParser parser)
		{
			ParsedRoots.Clear();
			foreach (Type configRoot in CruciblePackageConfigElementRegistry.GetConfigRoots())
			{
				parser.Reset();
				ParsedRoots.Add((CruciblePackageConfigRoot)Deserializer.DeserializeFromParser(configRoot, (IParser)(object)parser));
			}
		}
	}
	public class CruciblePackageModLoadException : Exception
	{
		public string ModPath { get; set; }

		public CruciblePackageModLoadException(string message)
			: base(message)
		{
		}

		public CruciblePackageModLoadException(string message, Exception innerException)
			: base(message, innerException)
		{
		}
	}
	public interface ICruciblePackageConfigExtension<in TSubject>
	{
		void OnApplyConfiguration(TSubject subject);
	}
}

plugins/Crucible.dll

Decompiled 11 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using Microsoft.CodeAnalysis;
using PotionCraft.NotificationSystem;
using RoboPhredDev.PotionCraft.Crucible.CruciblePackages;
using RoboPhredDev.PotionCraft.Crucible.GameAPI;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("Crucible")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Crucible")]
[assembly: AssemblyTitle("Crucible")]
[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;
		}
	}
}
namespace RoboPhredDev.PotionCraft.Crucible
{
	[BepInPlugin("net.RoboPhredDev.PotionCraft.Crucible", "Crucible Modding Framework", "1.1.2.0")]
	public class CruciblePlugin : BaseUnityPlugin
	{
		private ICollection<CruciblePackageMod> mods;

		public void Awake()
		{
			CrucibleGameEvents.OnGameInitialized += delegate
			{
				CrucibleLog.Log("Loading Crucible mods.", Array.Empty<object>());
				mods = LoadAllConfigMods();
				CrucibleLog.Log("Activating Crucible mods.", Array.Empty<object>());
				foreach (CruciblePackageMod mod in mods)
				{
					ActivateMod(mod);
				}
			};
			CrucibleGameEvents.OnSaveLoaded += delegate(object _, CrucibleSaveEventArgs e)
			{
				CruciblePluginSaveData saveData = e.SaveFile.GetSaveData<CruciblePluginSaveData>();
				if (saveData.InstalledCruciblePackageIDs != null)
				{
					List<string> list = new List<string>();
					foreach (string package in saveData.InstalledCruciblePackageIDs)
					{
						if (!mods.Any((CruciblePackageMod m) => m.ID == package))
						{
							list.Add(package);
						}
					}
					int num = mods.Count((CruciblePackageMod x) => !saveData.InstalledCruciblePackageIDs.Contains(x.ID));
					if (list.Count > 0)
					{
						Notification.ShowText("Missing Crucible Packages", "Some mods that this save relies on were not found: " + string.Join(", ", list) + ".", (TextType)0);
					}
					else if (num > 0)
					{
						Notification.ShowText("New Crucible Packages", string.Format("{0} new {1} installed.", num, (num != 1) ? "mods were" : "mod was"), (TextType)0);
					}
				}
			};
			CrucibleGameEvents.OnSaveSaved += delegate(object _, CrucibleSaveEventArgs e)
			{
				e.SaveFile.SetSaveData<CruciblePluginSaveData>(new CruciblePluginSaveData
				{
					CrucibleCoreVersion = "1.0.0.0",
					InstalledCruciblePackageIDs = mods.Select((CruciblePackageMod m) => m.ID).ToList()
				});
			};
		}

		private static void ActivateMod(CruciblePackageMod mod)
		{
			//IL_0013: Expected O, but got Unknown
			try
			{
				mod.EnsureDependenciesMet();
				mod.ApplyConfiguration();
			}
			catch (CrucibleMissingDependencyException val)
			{
				Debug.Log((object)((Exception)val).Message);
			}
			catch (Exception ex)
			{
				Debug.Log((object)ex.ToExpandedString());
			}
		}

		private static ICollection<CruciblePackageMod> LoadAllConfigMods()
		{
			List<CruciblePackageMod> list = new List<CruciblePackageMod>();
			IEnumerable<CruciblePackageMod> collection = TryLoadPluginsDirectoryMods();
			list.AddRange(collection);
			string path = Path.Combine("crucible", "mods");
			if (!Directory.Exists(path))
			{
				Directory.CreateDirectory(path);
				return list;
			}
			IEnumerable<CruciblePackageMod> collection2 = from folder in Directory.GetDirectories(path)
				select TryLoadDirectoryMod(folder) into x
				where x != null
				select x;
			list.AddRange(collection2);
			IEnumerable<CruciblePackageMod> collection3 = from file in Directory.GetFiles(path, "*.zip")
				select TryLoadFileMod(file) into x
				where x != null
				select x;
			list.AddRange(collection3);
			return list;
		}

		private static IEnumerable<CruciblePackageMod> TryLoadPluginsDirectoryMods()
		{
			List<CruciblePackageMod> list = new List<CruciblePackageMod>();
			string pluginPath = Paths.PluginPath;
			IEnumerable<CruciblePackageMod> collection = from file in Directory.GetFiles(pluginPath, "*.zip", SearchOption.AllDirectories)
				select TryLoadFileMod(file) into x
				where x != null
				select x;
			list.AddRange(collection);
			IEnumerable<CruciblePackageMod> collection2 = from d in Directory.GetFiles(pluginPath, "package.yml", SearchOption.AllDirectories).Select(Directory.GetParent)
				select d.FullName into folder
				select TryLoadDirectoryMod(folder) into x
				where x != null
				select x;
			list.AddRange(collection2);
			return list;
		}

		private static CruciblePackageMod TryLoadDirectoryMod(string modFolder)
		{
			//IL_002b: Expected O, but got Unknown
			try
			{
				CruciblePackageMod val = CruciblePackageMod.LoadFromFolder(modFolder);
				CrucibleLog.Log("> Loaded mod \"" + val.Name + "\".", Array.Empty<object>());
				return val;
			}
			catch (CruciblePackageModLoadException val2)
			{
				CruciblePackageModLoadException ex = val2;
				CrucibleLog.Log("Failed to load mod at \"" + modFolder + "\": " + ((Exception)(object)ex).ToExpandedString(), Array.Empty<object>());
				return null;
			}
		}

		private static CruciblePackageMod TryLoadFileMod(string zipFilePath)
		{
			//IL_002b: Expected O, but got Unknown
			try
			{
				CruciblePackageMod val = CruciblePackageMod.LoadFromZip(zipFilePath);
				CrucibleLog.Log("> Loaded mod \"" + val.Name + "\".", Array.Empty<object>());
				return val;
			}
			catch (CruciblePackageModLoadException val2)
			{
				CruciblePackageModLoadException ex = val2;
				CrucibleLog.Log("Failed to load mod at \"" + zipFilePath + "\": " + ((Exception)(object)ex).ToExpandedString(), Array.Empty<object>());
				return null;
			}
		}
	}
	[Serializable]
	public struct CruciblePluginSaveData
	{
		public string CrucibleCoreVersion;

		public List<string> InstalledCruciblePackageIDs;
	}
	public static class ExceptionUtils
	{
		public static string ToExpandedString(this Exception ex)
		{
			StringBuilder stringBuilder = new StringBuilder();
			while (true)
			{
				stringBuilder.Append(ex.GetType().FullName);
				stringBuilder.Append(" ");
				stringBuilder.AppendLine(ex.Message);
				if (ex.InnerException == null)
				{
					break;
				}
				ex = ex.InnerException;
			}
			stringBuilder.AppendLine(ex.StackTrace);
			return stringBuilder.ToString();
		}
	}
}

plugins/Crucible.GameAPI.dll

Decompiled 11 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PotionCraft.Assemblies.GamepadNavigation;
using PotionCraft.Assemblies.GamepadNavigation.Conditions;
using PotionCraft.Core;
using PotionCraft.Core.SerializableDictionary;
using PotionCraft.Core.ValueContainers;
using PotionCraft.DialogueSystem.Dialogue;
using PotionCraft.DialogueSystem.Dialogue.Data;
using PotionCraft.DialogueSystem.Dialogue.LocalProperties;
using PotionCraft.FactionSystem;
using PotionCraft.LocalizationSystem;
using PotionCraft.ManagersSystem;
using PotionCraft.ManagersSystem.Game;
using PotionCraft.ManagersSystem.Npc;
using PotionCraft.ManagersSystem.SaveLoad;
using PotionCraft.ManagersSystem.TMP;
using PotionCraft.NotificationSystem;
using PotionCraft.Npc;
using PotionCraft.Npc.MonoBehaviourScripts;
using PotionCraft.Npc.MonoBehaviourScripts.Settings;
using PotionCraft.Npc.Parts;
using PotionCraft.Npc.Parts.Appearance;
using PotionCraft.Npc.Parts.Appearance.Accessories;
using PotionCraft.Npc.Parts.Settings;
using PotionCraft.ObjectBased;
using PotionCraft.ObjectBased.Deliveries;
using PotionCraft.ObjectBased.Haggle;
using PotionCraft.ObjectBased.InteractiveItem.SoundControllers;
using PotionCraft.ObjectBased.InteractiveItem.SoundControllers.Presets;
using PotionCraft.ObjectBased.RecipeMap;
using PotionCraft.ObjectBased.RecipeMap.Path;
using PotionCraft.ObjectBased.RecipeMap.RecipeMapItem.PotionEffectMapItem;
using PotionCraft.ObjectBased.RecipeMap.RecipeMapItem.PotionEffectMapItem.Settings;
using PotionCraft.ObjectBased.RecipeMap.RecipeMapItem.VortexMapItem;
using PotionCraft.ObjectBased.RecipeMap.RecipeMapItem.Zones;
using PotionCraft.ObjectBased.Stack;
using PotionCraft.ObjectBased.Stack.StackItem;
using PotionCraft.ObjectBased.UIElements.Books.RecipeBook;
using PotionCraft.ObjectBased.UIElements.ElementChangerWindow;
using PotionCraft.ObjectBased.UIElements.ElementChangerWindow.PotionCustomizationWindow;
using PotionCraft.ObjectBased.UIElements.PotionCraftPanel;
using PotionCraft.ObjectBased.UIElements.Tooltip;
using PotionCraft.QuestSystem;
using PotionCraft.SaveFileSystem;
using PotionCraft.SceneLoader;
using PotionCraft.ScriptableObjects;
using PotionCraft.ScriptableObjects.Ingredient;
using PotionCraft.ScriptableObjects.Potion;
using PotionCraft.Settings;
using PotionCraft.Utils;
using PotionCraft.Utils.BezierCurves;
using PotionCraft.Utils.Path;
using PotionCraft.Utils.SortingOrderSetter;
using RecipeMapZoneEditor;
using RoboPhredDev.PotionCraft.Crucible.GameAPI.BackwardsCompatibility;
using RoboPhredDev.PotionCraft.Crucible.GameAPI.GameHooks;
using TMPro;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.TextCore;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("Crucible.GameAPI")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Crucible.GameAPI")]
[assembly: AssemblyTitle("Crucible.GameAPI")]
[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;
		}
	}
}
namespace RoboPhredDev.PotionCraft.Crucible
{
	public static class GameObjectUtilities
	{
		private static GameObject cruciblePrefabRoot;

		public static GameObject CruciblePrefabRoot
		{
			get
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Expected O, but got Unknown
				if ((Object)(object)cruciblePrefabRoot == (Object)null)
				{
					cruciblePrefabRoot = new GameObject("Crucible Prefab Root");
					cruciblePrefabRoot.SetActive(false);
				}
				return cruciblePrefabRoot;
			}
		}
	}
}
namespace RoboPhredDev.PotionCraft.Crucible.GameAPI
{
	public static class BepInExPluginUtilities
	{
		private static bool isInitialized;

		private static BepInPlugin[] cachedPlugins;

		public static IEnumerable<BepInPlugin> GetAllPlugins()
		{
			EnsureInitialized();
			if (cachedPlugins == null)
			{
				cachedPlugins = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
					from type in assembly.GetTypes()
					let attribute = (BepInPlugin)Attribute.GetCustomAttribute(type, typeof(BepInPlugin))
					where attribute != null
					select attribute).ToArray();
			}
			return cachedPlugins;
		}

		public static string GetPluginGuidFromAssembly(Assembly assembly)
		{
			BepInPlugin[] array = (from type in assembly.GetTypes()
				let attribute = (BepInPlugin)Attribute.GetCustomAttribute(type, typeof(BepInPlugin))
				where attribute != null
				select attribute).ToArray();
			if (array.Length != 1)
			{
				return null;
			}
			return array[0].GUID;
		}

		public static string RequirePluginGuidFromAssembly(Assembly assembly)
		{
			BepInPlugin[] array = (from type in assembly.GetTypes()
				let attribute = (BepInPlugin)Attribute.GetCustomAttribute(type, typeof(BepInPlugin))
				where attribute != null
				select attribute).ToArray();
			if (array.Length == 0)
			{
				throw new BepInPluginRequiredException("No class in the assembly \"" + assembly.FullName + "\" contains the BepInPlugin attribute.");
			}
			if (array.Length > 1)
			{
				throw new BepInPluginRequiredException("The assembly \"" + assembly.FullName + "\" contains more than one class with the BepInPlugin attribute.");
			}
			return array[0].GUID;
		}

		private static void EnsureInitialized()
		{
			if (!isInitialized)
			{
				isInitialized = true;
				AppDomain.CurrentDomain.AssemblyLoad += delegate
				{
					cachedPlugins = null;
				};
			}
		}
	}
	public class BepInPluginRequiredException : Exception
	{
		public BepInPluginRequiredException(string message)
			: base(message)
		{
		}
	}
	public class CrucibleBezierCurve
	{
		public bool IsRelative { get; }

		public Vector2 P1 { get; set; } = Vector2.zero;


		public Vector2 P2 { get; set; } = Vector2.zero;


		public Vector2 End { get; set; } = Vector2.zero;


		public CrucibleBezierCurve(Vector2 end)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			P1 = end;
			P2 = end;
			End = end;
			IsRelative = false;
		}

		public CrucibleBezierCurve(Vector2 end, bool isRelative)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			P1 = end;
			P2 = end;
			End = end;
			IsRelative = isRelative;
		}

		public CrucibleBezierCurve(Vector2 p1, Vector2 p2, Vector2 endpoint)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			P1 = p1;
			P2 = p2;
			End = endpoint;
			IsRelative = false;
		}

		public CrucibleBezierCurve(Vector2 p1, Vector2 p2, Vector2 endpoint, bool isRelative)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			P1 = p1;
			P2 = p2;
			End = endpoint;
			IsRelative = isRelative;
		}

		public static CrucibleBezierCurve LineTo(Vector2 end)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return new CrucibleBezierCurve(end, isRelative: false);
		}

		public static CrucibleBezierCurve LineTo(float x, float y)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return new CrucibleBezierCurve(new Vector2(x, y), isRelative: false);
		}

		public static CrucibleBezierCurve RelativeLineTo(Vector2 end)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return new CrucibleBezierCurve(end, isRelative: true);
		}

		public static CrucibleBezierCurve RelativeLineTo(float x, float y)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return new CrucibleBezierCurve(new Vector2(x, y), isRelative: true);
		}

		public static CrucibleBezierCurve CurveTo(Vector2 p1, Vector2 p2, Vector2 endpoint)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//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)
			return new CrucibleBezierCurve(p1, p2, endpoint, isRelative: false);
		}

		public static CrucibleBezierCurve RelativeCurveTo(Vector2 p1, Vector2 p2, Vector2 endpoint)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//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)
			return new CrucibleBezierCurve(p1, p2, endpoint, isRelative: true);
		}

		internal static CrucibleBezierCurve FromPotioncraftCurve(CubicBezierCurve curve)
		{
			//IL_0001: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			return new CrucibleBezierCurve(curve.P1, curve.P2, ((BezierCurve)curve).PLast, isRelative: false);
		}

		internal CubicBezierCurve ToPotioncraftCurve(Vector2 start)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_001d: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = P1;
			Vector2 val2 = P2;
			Vector2 val3 = End;
			if (IsRelative)
			{
				val += start;
				val2 += start;
				val3 += start;
			}
			return new CubicBezierCurve(start, val, val2, val3);
		}
	}
	public sealed class CrucibleCustomerNpcTemplate : CrucibleNpcTemplate, IEquatable<CrucibleCustomerNpcTemplate>
	{
		public string RequestText
		{
			get
			{
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				return new Key("#quest_text_" + ((Object)Quest).name, (List<string>)null, false).GetText();
			}
			set
			{
				CrucibleLocalization.SetLocalizationKey("#quest_text_" + ((Object)Quest).name, value);
			}
		}

		public float SpawnChance
		{
			get
			{
				float result = default(float);
				if (((SerializableDictionaryBase<NpcTemplate, float, float>)(object)Settings<NpcManagerSettings>.Asset.plotNpc).TryGetValue(base.NpcTemplate, ref result))
				{
					return result;
				}
				throw new Exception("Unable to get spawn chance for plot npc because npc has not been added to the plot npc dictionary.");
			}
			set
			{
				if (value < 0f || value > 10f)
				{
					throw new ArgumentException("SpawnChance values must range from 0 to 10. Unable to set SpawnChance");
				}
				((SerializableDictionaryBase<NpcTemplate, float, float>)(object)Settings<NpcManagerSettings>.Asset.plotNpc)[base.NpcTemplate] = value;
			}
		}

		public CrucibleQuestEffectsCollection AcceptedEffects => new CrucibleQuestEffectsCollection(Quest);

		public Quest Quest => base.NpcTemplate.baseParts.OfType<Quest>().FirstOrDefault();

		internal CrucibleCustomerNpcTemplate(NpcTemplate npcTemplate)
			: base(npcTemplate)
		{
		}

		public static CrucibleCustomerNpcTemplate GetCustomerNpcTemplateById(string id)
		{
			NpcTemplate val = NpcTemplate.allNpcTemplates.templates.Find((NpcTemplate x) => ((Object)x).name == id);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			if (!val.baseParts.OfType<Quest>().Any())
			{
				return null;
			}
			return new CrucibleCustomerNpcTemplate(val);
		}

		public static CrucibleCustomerNpcTemplate CreateCustomerNpcTemplate(string name, string copyAppearanceFrom = null)
		{
			CrucibleNpcTemplate crucibleNpcTemplate = null;
			if (!string.IsNullOrEmpty(copyAppearanceFrom))
			{
				crucibleNpcTemplate = CrucibleNpcTemplate.GetNpcTemplateById(copyAppearanceFrom);
				if (crucibleNpcTemplate == null || crucibleNpcTemplate.IsTrader)
				{
					throw new ArgumentException("Could not find Customer NPC template with id \"" + copyAppearanceFrom + "\" to copy appearance from.", "copyAppearanceFrom");
				}
			}
			NpcTemplate val = CrucibleNpcTemplate.CreateNpcTemplate(name, crucibleNpcTemplate);
			CrucibleCustomerNpcTemplate crucibleCustomerNpcTemplate = new CrucibleCustomerNpcTemplate(val);
			crucibleCustomerNpcTemplate.Appearance.CopyFrom(crucibleNpcTemplate);
			((SerializableDictionaryBase<NpcTemplate, float, float>)(object)Settings<NpcManagerSettings>.Asset.plotNpc)[val] = 1f;
			crucibleCustomerNpcTemplate.NpcTemplate.showDontComeAgainOption = false;
			return crucibleCustomerNpcTemplate;
		}

		public void SetLocalizedRequestText(LocalizedString requestText)
		{
			CrucibleLocalization.SetLocalizationKey("quest_text_" + ((Object)Quest).name, requestText);
		}

		public bool Equals(CrucibleCustomerNpcTemplate other)
		{
			return (Object)(object)base.NpcTemplate == (Object)(object)other.NpcTemplate;
		}

		private static DialogueData GetTestDialogue2()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_002c: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: 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_00b1: Expected O, but got Unknown
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Expected O, but got Unknown
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Expected O, but got Unknown
			//IL_014b: Expected O, but got Unknown
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Expected O, but got Unknown
			//IL_021e: Expected O, but got Unknown
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Expected O, but got Unknown
			//IL_02a7: Expected O, but got Unknown
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Expected O, but got Unknown
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Expected O, but got Unknown
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Expected O, but got Unknown
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_036d: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Expected O, but got Unknown
			//IL_0384: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b2: Expected O, but got Unknown
			//IL_03b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e5: Expected O, but got Unknown
			//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0401: Unknown result type (might be due to invalid IL or missing references)
			//IL_0412: Expected O, but got Unknown
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_041d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0429: Unknown result type (might be due to invalid IL or missing references)
			//IL_043b: Expected O, but got Unknown
			DialogueData obj = ScriptableObject.CreateInstance<DialogueData>();
			StartDialogueNodeData val = (obj.startDialogue = new StartDialogueNodeData
			{
				guid = Guid.NewGuid().ToString()
			});
			DialogueNodeData val2 = new DialogueNodeData
			{
				guid = Guid.NewGuid().ToString(),
				key = "__intro",
				text = string.Empty,
				answers = new List<AnswerData>
				{
					new AnswerData("", "", "")
					{
						guid = Guid.NewGuid().ToString(),
						key = "__intro_getquest",
						text = string.Empty
					},
					new AnswerData("", "", "")
					{
						guid = Guid.NewGuid().ToString(),
						key = "__intro_test",
						text = string.Empty
					},
					new AnswerData("", "", "")
					{
						guid = Guid.NewGuid().ToString(),
						key = "__intro_end",
						text = string.Empty
					}
				}
			};
			CrucibleLocalization.SetLocalizationKey("__intro", "Hello, this is a dialogue demo!");
			CrucibleLocalization.SetLocalizationKey("__intro_getquest", "What do you want to buy?");
			CrucibleLocalization.SetLocalizationKey("__intro_test", "This is another player choice option.");
			CrucibleLocalization.SetLocalizationKey("__intro_end", "Goodbye!");
			obj.dialogues.Add(val2);
			DialogueNodeData val3 = new DialogueNodeData
			{
				guid = Guid.NewGuid().ToString(),
				key = "__test",
				text = string.Empty,
				answers = new List<AnswerData>
				{
					new AnswerData("", "", "")
					{
						guid = Guid.NewGuid().ToString(),
						key = "__test_return",
						text = string.Empty
					}
				}
			};
			CrucibleLocalization.SetLocalizationKey("__test", "This is another dialogue node.");
			CrucibleLocalization.SetLocalizationKey("__test_return", "Cool, lets start again.");
			obj.dialogues.Add(val3);
			PotionRequestNodeData val4 = new PotionRequestNodeData
			{
				guid = Guid.NewGuid().ToString(),
				morePort = new AnswerData("", "", "")
				{
					guid = Guid.NewGuid().ToString(),
					key = "__backtointro"
				}
			};
			CrucibleLocalization.SetLocalizationKey("__backtointro", "Let's start over");
			obj.potionRequests.Add(val4);
			EndOfDialogueNodeData val5 = new EndOfDialogueNodeData
			{
				guid = Guid.NewGuid().ToString()
			};
			obj.endsOfDialogue.Add(val5);
			obj.edges.Add(new EdgeData
			{
				output = ((NodeData)val).guid,
				input = ((NodeData)val2).guid
			});
			obj.edges.Add(new EdgeData
			{
				output = val2.answers[0].guid,
				input = ((NodeData)val4).guid
			});
			obj.edges.Add(new EdgeData
			{
				output = val2.answers[1].guid,
				input = ((NodeData)val3).guid
			});
			obj.edges.Add(new EdgeData
			{
				output = val2.answers[2].guid,
				input = ((NodeData)val5).guid
			});
			obj.edges.Add(new EdgeData
			{
				output = val3.answers[0].guid,
				input = ((NodeData)val2).guid
			});
			obj.edges.Add(new EdgeData
			{
				output = val4.morePort.guid,
				input = ((NodeData)val2).guid
			});
			obj.edges.Add(new EdgeData
			{
				output = ((NodeData)val4).guid,
				input = ((NodeData)val5).guid
			});
			return obj;
		}

		private static DialogueData GetTestDialogue1()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_002c: 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_004b: 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)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			//IL_0096: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Expected O, but got Unknown
			//IL_013c: Expected O, but got Unknown
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Expected O, but got Unknown
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Expected O, but got Unknown
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Expected O, but got Unknown
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Expected O, but got Unknown
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Expected O, but got Unknown
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Expected O, but got Unknown
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Expected O, but got Unknown
			DialogueData obj = ScriptableObject.CreateInstance<DialogueData>();
			StartDialogueNodeData val = (obj.startDialogue = new StartDialogueNodeData
			{
				guid = Guid.NewGuid().ToString()
			});
			PotionRequestNodeData val2 = new PotionRequestNodeData
			{
				guid = Guid.NewGuid().ToString(),
				morePort = new AnswerData("", "", "")
				{
					guid = Guid.NewGuid().ToString(),
					key = "__morePort__data",
					text = "Hell World!  This is a potion request question."
				}
			};
			CrucibleLocalization.SetLocalizationKey("__morePort__data", "This is a discussion option!");
			obj.potionRequests.Add(val2);
			DialogueNodeData val3 = new DialogueNodeData
			{
				guid = Guid.NewGuid().ToString(),
				key = "__requestanswerdata",
				text = "Hello world!  This is the potion request answer.",
				answers = new List<AnswerData>
				{
					new AnswerData("", "", "")
					{
						guid = Guid.NewGuid().ToString(),
						key = "__requestanswerdata_answer1",
						text = "Hello world!  This is answer data for requestAnswerData and I don't know what its here for."
					}
				}
			};
			CrucibleLocalization.SetLocalizationKey("__requestanswerdata", "This is an answer!");
			CrucibleLocalization.SetLocalizationKey("__requestanswerdata_answer1", "This is the player's response to the answer!");
			obj.dialogues.Add(val3);
			EndOfDialogueNodeData val4 = new EndOfDialogueNodeData
			{
				guid = Guid.NewGuid().ToString()
			};
			obj.endsOfDialogue.Add(val4);
			obj.edges.Add(new EdgeData
			{
				output = ((NodeData)val).guid,
				input = ((NodeData)val2).guid
			});
			obj.edges.Add(new EdgeData
			{
				output = ((NodeData)val2).guid,
				input = ((NodeData)val4).guid
			});
			obj.edges.Add(new EdgeData
			{
				output = ((NodeData)val2).guid,
				input = ((NodeData)val3).guid
			});
			obj.edges.Add(new EdgeData
			{
				output = ((NodeData)val3).guid,
				input = ((NodeData)val2).guid
			});
			obj.edges.Add(new EdgeData
			{
				output = val2.morePort.guid,
				input = ((NodeData)val3).guid
			});
			obj.edges.Add(new EdgeData
			{
				output = val3.answers[0].guid,
				input = ((NodeData)val2).guid
			});
			return obj;
		}
	}
	public class CrucibleDialogueData
	{
		public class CrucibleDialogueNode
		{
			public LocalizedString DialogueText { get; set; }

			public List<CrucibleAnswerNode> Answers { get; set; } = new List<CrucibleAnswerNode>();


			public bool IsQuestNode { get; set; }

			public bool HasQuestNode
			{
				get
				{
					if (!IsQuestNode)
					{
						return Answers.Any((CrucibleAnswerNode a) => a.NextNode?.HasQuestNode ?? false);
					}
					return true;
				}
			}

			public bool HasWayBackToBeginning => Answers.Any((CrucibleAnswerNode a) => a.HasWayBackToBeginning);

			public CrucibleDialogueNode NextNonQuestNode => Answers.Select((CrucibleAnswerNode a) => a.NextNonQuestNode).FirstOrDefault((CrucibleDialogueNode n) => n != null);

			public CrucibleDialogueNode TradeNode
			{
				get
				{
					if (!IsTradeNode)
					{
						return Answers.Select((CrucibleAnswerNode a) => a.NextNode).FirstOrDefault((CrucibleDialogueNode n) => n?.IsTradeNode ?? false);
					}
					return this;
				}
			}

			private bool IsTradeNode => Answers.Any((CrucibleAnswerNode a) => a.IsTradeAnswer);
		}

		public class CrucibleAnswerNode
		{
			public LocalizedString AnswerText { get; set; }

			public CrucibleDialogueNode NextNode { get; set; }

			public bool IsConversationEndAnswer { get; set; }

			public bool IsBackToBeginningAnswer { get; set; }

			public bool IsTradeAnswer { get; set; }

			public bool CanGoBack
			{
				get
				{
					if (NextNode != null && !IsBackToBeginningAnswer && !IsConversationEndAnswer)
					{
						return NextNode.HasWayBackToBeginning;
					}
					return true;
				}
			}

			public bool HasWayBackToBeginning
			{
				get
				{
					if (!IsBackToBeginningAnswer && !IsConversationEndAnswer)
					{
						return NextNode?.HasWayBackToBeginning ?? false;
					}
					return true;
				}
			}

			public CrucibleDialogueNode NextNonQuestNode
			{
				get
				{
					CrucibleDialogueNode nextNode = NextNode;
					if (nextNode != null && nextNode.IsQuestNode)
					{
						return NextNode?.NextNonQuestNode;
					}
					return NextNode;
				}
			}
		}

		public DialogueData DialogueData { get; }

		public CrucibleDialogueData()
		{
			DialogueData = ScriptableObject.CreateInstance<DialogueData>();
		}

		public CrucibleDialogueData(DialogueData dialogueData)
		{
			DialogueData = dialogueData;
		}

		public static CrucibleDialogueData CreateDialogueData(string localizationKey, CrucibleDialogueNode startingDialogue, bool showQuestDialogue, bool isTrader)
		{
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Expected O, but got Unknown
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Expected O, but got Unknown
			CrucibleDialogueData crucibleDialogueData = new CrucibleDialogueData();
			((Object)crucibleDialogueData.DialogueData).name = localizationKey + "_dialogue";
			int localizationKeyUniqueId = 0;
			if (isTrader)
			{
				CrucibleDialogueNode crucibleDialogueNode = startingDialogue.TradeNode;
				if (crucibleDialogueNode == null)
				{
					crucibleDialogueNode = startingDialogue;
				}
				crucibleDialogueNode.Answers.Insert(0, new CrucibleAnswerNode
				{
					AnswerText = "Trade",
					IsTradeAnswer = true
				});
				if (crucibleDialogueNode.Answers.Count > 3)
				{
					crucibleDialogueNode.Answers = crucibleDialogueNode.Answers.Take(3).ToList();
				}
				crucibleDialogueNode.Answers.Add(new CrucibleAnswerNode
				{
					IsConversationEndAnswer = true
				});
			}
			crucibleDialogueData.DialogueData.startDialogue = GetNode<StartDialogueNodeData>(localizationKey, ref localizationKeyUniqueId, startingDialogue);
			crucibleDialogueData.DialogueData.endsOfDialogue.Add(GetNode<EndOfDialogueNodeData>(localizationKey, ref localizationKeyUniqueId, startingDialogue));
			CreateDialogueNode(localizationKey, ref localizationKeyUniqueId, crucibleDialogueData, startingDialogue, ((NodeData)crucibleDialogueData.DialogueData.startDialogue).guid, showQuestDialogue, isTrader);
			crucibleDialogueData.DialogueData.textProperties.Add(new TextProperty("", "", (TextEntity)0)
			{
				entity = (TextEntity)0,
				name = "#end_of_dialogue"
			});
			crucibleDialogueData.DialogueData.textProperties.Add(new TextProperty("", "", (TextEntity)0)
			{
				entity = (TextEntity)0,
				name = "dialogue_back"
			});
			return crucibleDialogueData;
		}

		public CrucibleDialogueData Clone()
		{
			DialogueData obj = ScriptableObject.CreateInstance<DialogueData>();
			obj.startDialogue = CopyNode<StartDialogueNodeData>(DialogueData.startDialogue);
			obj.dialogues = DialogueData.dialogues.Select(CopyNode<DialogueNodeData>).ToList();
			obj.conditions = DialogueData.conditions.Select(CopyNode<IfOperatorNodeData>).ToList();
			obj.events = DialogueData.events.Select(CopyNode<EventNodeData>).ToList();
			obj.setVariables = DialogueData.setVariables.Select(CopyNode<SetVariableNodeData>).ToList();
			obj.changeVariables = DialogueData.changeVariables.Select(CopyNode<ChangeVariableNodeData>).ToList();
			obj.comments = DialogueData.comments.Select(CopyNode<CommentNodeData>).ToList();
			obj.tradings = DialogueData.tradings.Select(CopyNode<TradingNodeData>).ToList();
			obj.potionRequests = DialogueData.potionRequests.Select(CopyNode<PotionRequestNodeData>).ToList();
			obj.closenessPotionRequests = DialogueData.closenessPotionRequests.Select(CopyNode<ClosenessPotionRequestNodeData>).ToList();
			obj.endsOfDialogue = DialogueData.endsOfDialogue.Select(CopyNode<EndOfDialogueNodeData>).ToList();
			obj.logicalOperators = DialogueData.logicalOperators.Select(CopyNode<LogicalOperatorNodeData>).ToList();
			obj.notOperators = DialogueData.notOperators.Select(CopyNode<NotOperatorNodeData>).ToList();
			obj.comparisonOperators = DialogueData.comparisonOperators.Select(CopyNode<ComparisonOperatorNodeData>).ToList();
			obj.operands = DialogueData.operands.Select(CopyNode<OperandNodeData>).ToList();
			obj.edges = DialogueData.edges.Select(CopyEdge).ToList();
			obj.conditionProperties = DialogueData.conditionProperties.Select((ConditionProperty conditionProperty) => conditionProperty.Clone()).ToList();
			obj.textProperties = DialogueData.textProperties.Select((TextProperty textProperty) => textProperty.Clone()).ToList();
			return new CrucibleDialogueData(obj);
		}

		private static NodeData CreateDialogueNode(string localizationKey, ref int localizationKeyUniqueId, CrucibleDialogueData dialogueData, CrucibleDialogueNode dialogueNode, string parentGuid, bool showQuestDialogue, bool isTrader)
		{
			if (!showQuestDialogue)
			{
				CrucibleDialogueNode nextNonQuestNode = dialogueNode.NextNonQuestNode;
				if (nextNonQuestNode == null)
				{
					return null;
				}
				return CreateDialogueNode(localizationKey, ref localizationKeyUniqueId, dialogueData, nextNonQuestNode, parentGuid, showQuestDialogue, isTrader);
			}
			NodeData val2;
			if (dialogueNode.IsQuestNode)
			{
				NodeData val;
				if (isTrader)
				{
					ClosenessPotionRequestNodeData node = GetNode<ClosenessPotionRequestNodeData>(localizationKey, ref localizationKeyUniqueId, dialogueNode);
					dialogueData.DialogueData.closenessPotionRequests.Add(node);
					val = (NodeData)(object)node;
				}
				else
				{
					PotionRequestNodeData node2 = GetNode<PotionRequestNodeData>(localizationKey, ref localizationKeyUniqueId, dialogueNode);
					dialogueData.DialogueData.potionRequests.Add(node2);
					val = (NodeData)(object)node2;
				}
				val2 = val;
				CreateEdge(dialogueData, parentGuid, val.guid);
				if (isTrader)
				{
					CreateEdge(dialogueData, val.guid, GetNodeToGoBackTo(dialogueData, val).guid);
				}
				else
				{
					CreateEdge(dialogueData, val.guid, ((NodeData)dialogueData.DialogueData.endsOfDialogue.First()).guid);
				}
				if (dialogueNode.Answers.Count > 1)
				{
					dialogueNode.Answers = new List<CrucibleAnswerNode> { dialogueNode.Answers[0] };
				}
			}
			else
			{
				DialogueNodeData node3 = GetNode<DialogueNodeData>(localizationKey, ref localizationKeyUniqueId, dialogueNode);
				dialogueData.DialogueData.dialogues.Add(node3);
				val2 = (NodeData)(object)node3;
				CreateEdge(dialogueData, parentGuid, ((NodeData)node3).guid);
				if (!dialogueNode.Answers.Any())
				{
					dialogueNode.Answers.Add(new CrucibleAnswerNode
					{
						AnswerText = "[1]"
					});
				}
				if (dialogueNode.Answers.Count > 4)
				{
					dialogueNode.Answers = dialogueNode.Answers.Take(4).ToList();
				}
				if (dialogueNode.Answers.All((CrucibleAnswerNode a) => !a.CanGoBack))
				{
					if (dialogueNode.Answers.Count > 3)
					{
						dialogueNode.Answers = dialogueNode.Answers.Take(3).ToList();
					}
					dialogueNode.Answers.Add(new CrucibleAnswerNode
					{
						AnswerText = "[1]"
					});
				}
			}
			foreach (CrucibleAnswerNode answer in dialogueNode.Answers)
			{
				if (!showQuestDialogue)
				{
					CrucibleDialogueNode nextNode = answer.NextNode;
					if (nextNode != null && nextNode.IsQuestNode)
					{
						continue;
					}
				}
				CreateAnswer(localizationKey, ref localizationKeyUniqueId, dialogueData, val2, answer, showQuestDialogue, isTrader);
			}
			return val2;
		}

		private static void CreateAnswer(string localizationKey, ref int localizationKeyUniqueId, CrucibleDialogueData dialogueData, NodeData parent, CrucibleAnswerNode answer, bool showQuestDialogue, bool isTrader)
		{
			//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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			string key;
			if (answer.IsConversationEndAnswer && answer.AnswerText == null)
			{
				key = "end_of_dialogue";
			}
			else
			{
				key = $"{localizationKey}_dialogue_answer_{localizationKeyUniqueId}";
				CrucibleLocalization.SetLocalizationKey(key, answer.AnswerText);
			}
			localizationKeyUniqueId++;
			AnswerData val = new AnswerData("", "", "")
			{
				guid = Guid.NewGuid().ToString(),
				key = key
			};
			AddAnswerToParent(parent, val);
			if (answer.IsTradeAnswer)
			{
				TradingNodeData node = GetNode<TradingNodeData>(localizationKey, ref localizationKeyUniqueId, (CrucibleDialogueNode)null);
				dialogueData.DialogueData.tradings.Add(node);
				CreateEdge(dialogueData, val.guid, ((NodeData)node).guid);
				CreateEdge(dialogueData, ((NodeData)node).guid, parent.guid);
			}
			else if (answer.IsConversationEndAnswer)
			{
				EndOfDialogueNodeData val2 = dialogueData.DialogueData.endsOfDialogue.First();
				CreateEdge(dialogueData, val.guid, ((NodeData)val2).guid);
			}
			else if (answer.IsBackToBeginningAnswer)
			{
				NodeData next = ((NodeData)dialogueData.DialogueData.startDialogue).GetNext(dialogueData.DialogueData, 0);
				CreateEdge(dialogueData, val.guid, next.guid);
			}
			else if (answer.NextNode == null)
			{
				NodeData nodeToGoBackTo = GetNodeToGoBackTo(dialogueData, parent);
				CreateEdge(dialogueData, val.guid, nodeToGoBackTo.guid);
			}
			else
			{
				CreateDialogueNode(localizationKey, ref localizationKeyUniqueId, dialogueData, answer.NextNode, val.guid, showQuestDialogue, isTrader);
			}
		}

		private static NodeData GetNodeToGoBackTo(CrucibleDialogueData dialogueData, NodeData node)
		{
			string parent = ((IEnumerable<EdgeData>)dialogueData.DialogueData.edges).FirstOrDefault((Func<EdgeData, bool>)((EdgeData e) => e.input.Equals(node.guid))).output;
			PotionRequestNodeData val = ((IEnumerable<PotionRequestNodeData>)dialogueData.DialogueData.potionRequests).FirstOrDefault((Func<PotionRequestNodeData, bool>)((PotionRequestNodeData p) => p.morePort.guid.Equals(parent)));
			if (val != null)
			{
				return (NodeData)(object)val;
			}
			DialogueNodeData val2 = ((IEnumerable<DialogueNodeData>)dialogueData.DialogueData.dialogues).FirstOrDefault((Func<DialogueNodeData, bool>)((DialogueNodeData p) => p.answers.Any((AnswerData a) => a.guid.Equals(parent))));
			if (val2 != null)
			{
				return (NodeData)(object)val2;
			}
			return (NodeData)(object)dialogueData.DialogueData.endsOfDialogue.First();
		}

		private static void AddAnswerToParent(NodeData parent, AnswerData answer)
		{
			DialogueNodeData val = (DialogueNodeData)(object)((parent is DialogueNodeData) ? parent : null);
			if (val == null)
			{
				PotionRequestNodeData val2 = (PotionRequestNodeData)(object)((parent is PotionRequestNodeData) ? parent : null);
				if (val2 != null)
				{
					val2.morePort = answer;
				}
			}
			else
			{
				val.answers.Add(answer);
			}
		}

		private static void CreateEdge(CrucibleDialogueData dialogueData, string output, string input)
		{
			//IL_000b: 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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			dialogueData.DialogueData.edges.Add(new EdgeData
			{
				output = output,
				input = input
			});
		}

		private static T GetNode<T>(string localizationKey, ref int localizationKeyUniqueId, CrucibleDialogueNode node) where T : NodeData, new()
		{
			T val = new T();
			((NodeData)val).guid = Guid.NewGuid().ToString();
			object obj = val;
			DialogueNodeData val2 = (DialogueNodeData)((obj is DialogueNodeData) ? obj : null);
			if (val2 != null)
			{
				string key = $"{localizationKey}_dialogue_{localizationKeyUniqueId}";
				CrucibleLocalization.SetLocalizationKey(key, node.DialogueText);
				val2.key = key;
				localizationKeyUniqueId++;
			}
			return val;
		}

		private static T CopyNode<T>(T source) where T : NodeData, new()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0328: Unknown result type (might be due to invalid IL or missing references)
			//IL_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			T val = new T();
			((NodeData)val).guid = ((NodeData)source).guid;
			((NodeData)val).position = ((NodeData)source).position;
			T val2 = val;
			object obj = source;
			DialogueNodeData val3 = (DialogueNodeData)((obj is DialogueNodeData) ? obj : null);
			if (val3 == null)
			{
				object obj2 = source;
				IfOperatorNodeData val4 = (IfOperatorNodeData)((obj2 is IfOperatorNodeData) ? obj2 : null);
				if (val4 == null)
				{
					object obj3 = source;
					EventNodeData val5 = (EventNodeData)((obj3 is EventNodeData) ? obj3 : null);
					if (val5 == null)
					{
						object obj4 = source;
						SetVariableNodeData val6 = (SetVariableNodeData)((obj4 is SetVariableNodeData) ? obj4 : null);
						if (val6 == null)
						{
							object obj5 = source;
							ChangeVariableNodeData val7 = (ChangeVariableNodeData)((obj5 is ChangeVariableNodeData) ? obj5 : null);
							if (val7 == null)
							{
								object obj6 = source;
								CommentNodeData val8 = (CommentNodeData)((obj6 is CommentNodeData) ? obj6 : null);
								if (val8 == null)
								{
									object obj7 = source;
									PotionRequestNodeData val9 = (PotionRequestNodeData)((obj7 is PotionRequestNodeData) ? obj7 : null);
									if (val9 == null)
									{
										object obj8 = source;
										LogicalOperatorNodeData val10 = (LogicalOperatorNodeData)((obj8 is LogicalOperatorNodeData) ? obj8 : null);
										if (val10 == null)
										{
											object obj9 = source;
											ComparisonOperatorNodeData val11 = (ComparisonOperatorNodeData)((obj9 is ComparisonOperatorNodeData) ? obj9 : null);
											if (val11 == null)
											{
												object obj10 = source;
												OperandNodeData val12 = (OperandNodeData)((obj10 is OperandNodeData) ? obj10 : null);
												if (val12 != null)
												{
													object obj11 = val2;
													((OperandNodeData)((obj11 is OperandNodeData) ? obj11 : null)).type = val12.type;
													object obj12 = val2;
													((OperandNodeData)((obj12 is OperandNodeData) ? obj12 : null)).value = val12.value;
													object obj13 = val2;
													((OperandNodeData)((obj13 is OperandNodeData) ? obj13 : null)).customValue = val12.customValue;
												}
											}
											else
											{
												object obj14 = val2;
												((ComparisonOperatorNodeData)((obj14 is ComparisonOperatorNodeData) ? obj14 : null)).type = val11.type;
												object obj15 = val2;
												((ComparisonOperatorNodeData)((obj15 is ComparisonOperatorNodeData) ? obj15 : null)).operand1Guid = val11.operand1Guid;
												object obj16 = val2;
												((ComparisonOperatorNodeData)((obj16 is ComparisonOperatorNodeData) ? obj16 : null)).operand2Guid = val11.operand2Guid;
											}
										}
										else
										{
											object obj17 = val2;
											((LogicalOperatorNodeData)((obj17 is LogicalOperatorNodeData) ? obj17 : null)).type = val10.type;
											object obj18 = val2;
											((LogicalOperatorNodeData)((obj18 is LogicalOperatorNodeData) ? obj18 : null)).operand1Guid = val10.operand1Guid;
											object obj19 = val2;
											((LogicalOperatorNodeData)((obj19 is LogicalOperatorNodeData) ? obj19 : null)).operand2Guid = val10.operand2Guid;
										}
									}
									else
									{
										object obj20 = val2;
										((PotionRequestNodeData)((obj20 is PotionRequestNodeData) ? obj20 : null)).morePort = CopyAnswer(val9.morePort);
									}
								}
								else
								{
									object obj21 = val2;
									((CommentNodeData)((obj21 is CommentNodeData) ? obj21 : null)).text = val8.text;
								}
							}
							else
							{
								object obj22 = val2;
								((ChangeVariableNodeData)((obj22 is ChangeVariableNodeData) ? obj22 : null)).title = val7.title;
								object obj23 = val2;
								((ChangeVariableNodeData)((obj23 is ChangeVariableNodeData) ? obj23 : null)).properties = val7.properties.Select(CopyMethod).ToList();
							}
						}
						else
						{
							object obj24 = val2;
							((SetVariableNodeData)((obj24 is SetVariableNodeData) ? obj24 : null)).title = val6.title;
							object obj25 = val2;
							((SetVariableNodeData)((obj25 is SetVariableNodeData) ? obj25 : null)).properties = val6.properties.Select(CopyMethod).ToList();
						}
					}
					else
					{
						object obj26 = val2;
						((EventNodeData)((obj26 is EventNodeData) ? obj26 : null)).title = val5.title;
						object obj27 = val2;
						((EventNodeData)((obj27 is EventNodeData) ? obj27 : null)).events = val5.events.Select(CopyMethod).ToList();
					}
				}
				else
				{
					object obj28 = val2;
					((IfOperatorNodeData)((obj28 is IfOperatorNodeData) ? obj28 : null)).title = val4.title;
					object obj29 = val2;
					((IfOperatorNodeData)((obj29 is IfOperatorNodeData) ? obj29 : null)).truePortGuid = val4.truePortGuid;
					object obj30 = val2;
					((IfOperatorNodeData)((obj30 is IfOperatorNodeData) ? obj30 : null)).falsePortGuid = val4.falsePortGuid;
					object obj31 = val2;
					((IfOperatorNodeData)((obj31 is IfOperatorNodeData) ? obj31 : null)).boolPortGuid = val4.boolPortGuid;
				}
			}
			else
			{
				object obj32 = val2;
				((DialogueNodeData)((obj32 is DialogueNodeData) ? obj32 : null)).title = val3.title;
				object obj33 = val2;
				((DialogueNodeData)((obj33 is DialogueNodeData) ? obj33 : null)).key = val3.key;
				object obj34 = val2;
				((DialogueNodeData)((obj34 is DialogueNodeData) ? obj34 : null)).text = val3.text;
				object obj35 = val2;
				((DialogueNodeData)((obj35 is DialogueNodeData) ? obj35 : null)).answers = val3.answers.Select(CopyAnswer).ToList();
			}
			return val2;
		}

		private static AnswerData CopyAnswer(AnswerData source)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			return new AnswerData("", "", "")
			{
				guid = source.guid,
				key = source.key,
				text = source.text
			};
		}

		private static Method CopyMethod(Method source)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			return new Method
			{
				name = source.name,
				parameters = source.parameters
			};
		}

		private static EdgeData CopyEdge(EdgeData edge)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			return new EdgeData
			{
				output = edge.output,
				input = edge.input
			};
		}
	}
	public static class CrucibleGameEvents
	{
		private static bool isInitialized;

		private static EventHandler<CrucibleSaveEventArgs> onSaveLoaded;

		private static EventHandler<CrucibleSaveEventArgs> onSaveSaved;

		public static event EventHandler OnGameInitialized
		{
			add
			{
				EnsureInitialized();
				GameInitEvent.OnGameInitialized += value;
			}
			remove
			{
				GameInitEvent.OnGameInitialized -= value;
			}
		}

		public static event EventHandler<CrucibleSaveEventArgs> OnSaveLoaded
		{
			add
			{
				EnsureInitialized();
				onSaveLoaded = (EventHandler<CrucibleSaveEventArgs>)Delegate.Combine(onSaveLoaded, value);
			}
			remove
			{
				onSaveLoaded = (EventHandler<CrucibleSaveEventArgs>)Delegate.Remove(onSaveLoaded, value);
			}
		}

		public static event EventHandler<CrucibleSaveEventArgs> OnSaveSaved
		{
			add
			{
				EnsureInitialized();
				onSaveSaved = (EventHandler<CrucibleSaveEventArgs>)Delegate.Combine(onSaveSaved, value);
			}
			remove
			{
				onSaveSaved = (EventHandler<CrucibleSaveEventArgs>)Delegate.Remove(onSaveSaved, value);
			}
		}

		private static void EnsureInitialized()
		{
			if (!isInitialized)
			{
				isInitialized = true;
				SaveLoadEvent.OnGameLoaded += HandleSaveLoaded;
				SaveLoadEvent.OnGameSaved += HandleSaveSaved;
			}
		}

		private static void HandleSaveLoaded(object sender, SaveLoadEventArgs e)
		{
			if (onSaveLoaded == null)
			{
				return;
			}
			using CrucibleSaveFile saveFile = new CrucibleSaveFile(e.File);
			onSaveLoaded(null, new CrucibleSaveEventArgs(saveFile));
		}

		private static void HandleSaveSaved(object sender, SaveLoadEventArgs e)
		{
			if (onSaveSaved == null)
			{
				return;
			}
			using CrucibleSaveFile saveFile = new CrucibleSaveFile(e.File);
			onSaveSaved(null, new CrucibleSaveEventArgs(saveFile));
		}
	}
	public static class CrucibleGameFolders
	{
	}
	public sealed class CrucibleIcon
	{
		public string ID => ((Object)Icon).name;

		public Icon Icon { get; }

		public Texture2D IconTexture
		{
			get
			{
				return Icon.textures[0];
			}
			set
			{
				Icon.textures[0] = value;
			}
		}

		public CrucibleIcon(Icon icon)
		{
			Icon = icon;
		}

		public static CrucibleIcon GetIconByID(string id)
		{
			Icon val = Icon.allIcons.Find((Icon x) => ((Object)x).name == id);
			if (!((ComparableScriptableObject<SerializablePanelElement>)(object)val != (ComparableScriptableObject<SerializablePanelElement>)null))
			{
				return null;
			}
			return new CrucibleIcon(val);
		}

		public static CrucibleIcon FromTexture(string id, Texture2D texture)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			if ((ComparableScriptableObject<SerializablePanelElement>)(object)Icon.allIcons.Find((Icon x) => ((Object)x).name == id) != (ComparableScriptableObject<SerializablePanelElement>)null)
			{
				throw new ArgumentException("Icon with ID \"" + id + "\" already exists.", "id");
			}
			Texture2D val = TextureUtilities.CreateBlankTexture(1, 1, Color.clear);
			Icon val2 = ScriptableObject.CreateInstance<Icon>();
			((Object)val2).name = id;
			val2.textures = (Texture2D[])(object)new Texture2D[1] { texture };
			val2.contourTexture = val;
			val2.scratchesTexture = val;
			val2.defaultIconColors = (Color[])(object)new Color[1] { GetDefaultColor() };
			RegisterIcon(val2);
			return new CrucibleIcon(val2);
		}

		public CrucibleIcon Clone(string id)
		{
			if ((ComparableScriptableObject<SerializablePanelElement>)(object)Icon.allIcons.Find((Icon x) => ((Object)x).name == id) != (ComparableScriptableObject<SerializablePanelElement>)null)
			{
				throw new ArgumentException("Icon with ID \"" + id + "\" already exists.", "id");
			}
			Icon icon = Icon;
			Icon obj = ScriptableObject.CreateInstance<Icon>();
			((Object)icon).name = id;
			obj.textures = icon.textures;
			obj.contourTexture = icon.contourTexture;
			obj.scratchesTexture = icon.scratchesTexture;
			obj.defaultIconColors = icon.defaultIconColors;
			Icon.allIcons.Add(icon);
			return new CrucibleIcon(obj);
		}

		public void SetTexture(Texture2D texture)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			Icon icon = Icon;
			icon.textures = (Texture2D[])(object)new Texture2D[1] { texture };
			icon.defaultIconColors = (Color[])(object)new Color[1] { GetDefaultColor() };
			ClearCache();
		}

		public void ClearCache()
		{
			(Traverse.Create((object)Icon).Field("renderedVariants").GetValue() as IList).Clear();
		}

		private static void RegisterIcon(Icon icon)
		{
			Icon.allIcons.Add(icon);
			PotionSkinChangerWindow val = Object.FindObjectOfType<PotionSkinChangerWindow>();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Traverse<ElementChangerPanelGroup> val2 = Traverse.Create((object)val).Field<ElementChangerPanelGroup>("iconSkinChangerPanelGroup");
			if (val2 != null)
			{
				ElementChangerPanel mainPanel = val2.Value.mainPanel;
				IconSkinChangerPanel val3 = (IconSkinChangerPanel)(object)((mainPanel is IconSkinChangerPanel) ? mainPanel : null);
				if ((Object)(object)val3 != (Object)null)
				{
					((ElementChangerPanelWithElements)val3).elements.Add((SerializablePanelElement)(object)icon);
				}
			}
		}

		private static Color GetDefaultColor()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			return new Color(0.894f, 0.894f, 0.894f, 1f);
		}
	}
	public sealed class CrucibleIngredient : CrucibleInventoryItem
	{
		private static readonly HashSet<Ingredient> AtlasOverriddenIngredients = new HashSet<Ingredient>();

		private static readonly HashSet<Ingredient> StackOverriddenIngredients = new HashSet<Ingredient>();

		private static bool overridesInitialized = false;

		private static CrucibleSpriteAtlas spriteAtlas;

		public Ingredient Ingredient => (Ingredient)base.InventoryItem;

		public string Name
		{
			get
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				return new Key(LocalizationKey, (List<string>)null, false).GetText();
			}
			set
			{
				CrucibleLocalization.SetLocalizationKey(LocalizationKey, value);
			}
		}

		public string Description
		{
			get
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				return new Key(LocalizationKey + "_description", (List<string>)null, false).GetText();
			}
			set
			{
				CrucibleLocalization.SetLocalizationKey(LocalizationKey + "_description", value);
			}
		}

		public Sprite RecipeStepIcon
		{
			get
			{
				return Ingredient.recipeMarkIcon;
			}
			set
			{
				Ingredient.recipeMarkIcon = value;
			}
		}

		public Sprite IngredientListIcon
		{
			get
			{
				return Ingredient.smallIcon;
			}
			set
			{
				if (!((Texture)value.texture).isReadable)
				{
					throw new ArgumentException("IngredientListIcon can only be set to sprites with readable textures.  The texture data must be available to bake into a sprite atlas.");
				}
				if (value.packed)
				{
					throw new ArgumentException("IngredientListIcon only supports sprites that are not derived from sprite sheets.  The texture data must be available to bake into a sprite atlas.");
				}
				Ingredient.smallIcon = value;
				SetIngredientIcon(Ingredient, value.texture);
			}
		}

		public Color GroundColor
		{
			get
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				return Ingredient.grindedSubstanceColor;
			}
			set
			{
				//IL_0006: 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)
				Ingredient.grindedSubstanceColor = value;
			}
		}

		public bool CanBeDamaged
		{
			get
			{
				return Ingredient.canBeDamaged;
			}
			set
			{
				Ingredient.canBeDamaged = value;
			}
		}

		public bool IsTeleportationIngredient
		{
			get
			{
				return Ingredient.isTeleportationIngredient;
			}
			set
			{
				Ingredient.isTeleportationIngredient = value;
			}
		}

		public float PathLength => ((Path)Ingredient.path).Length;

		public float PathPregrindPercentage
		{
			get
			{
				return ((EvenlySpacedPointsPath)Ingredient.path).grindedPathStartsFrom;
			}
			set
			{
				if (value < 0f || value >= 1f)
				{
					throw new ArgumentOutOfRangeException("value", "Grind percentage must be at least 0 and less than 1.");
				}
				((EvenlySpacedPointsPath)Ingredient.path).grindedPathStartsFrom = value;
			}
		}

		public bool IsStackItemSolid
		{
			get
			{
				return Ingredient.isSolid;
			}
			set
			{
				Ingredient.isSolid = value;
			}
		}

		private string LocalizationKey => "ingredient_" + ((Object)base.InventoryItem).name;

		private CrucibleIngredient(Ingredient ingredient)
			: base((InventoryItem)(object)ingredient)
		{
		}

		public static CrucibleIngredient CreateIngredient(string id, string copyFromId = "Waterbloom")
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			if (GetIngredientById(id) != null)
			{
				throw new ArgumentException("An ingredient with the given id of \"" + id + "\" already exists.");
			}
			Ingredient val = Ingredient.allIngredients.Find((Ingredient x) => ((Object)x).name == copyFromId);
			if ((Object)(object)val == (Object)null)
			{
				val = GetBaseIngredientForOldId(copyFromId);
				if ((Object)(object)val == (Object)null)
				{
					throw new ArgumentException("Cannot find ingredient \"" + copyFromId + "\" to copy settings from.");
				}
			}
			Ingredient val2 = ScriptableObject.CreateInstance<Ingredient>();
			((Object)val2).name = id;
			GameObject val3 = new GameObject("Ingredient_" + id);
			val3.transform.parent = GameObjectUtilities.CruciblePrefabRoot.transform;
			val3.SetActive(false);
			CrucibleIngredient result = new CrucibleIngredient(val2)
			{
				InventoryIcon = ((InventoryItem)val).inventoryIconObject,
				RecipeStepIcon = val.recipeMarkIcon,
				IngredientListIcon = SpriteUtilities.CreateBlankSprite(16, 16, Color.red),
				Price = ((InventoryItem)val).GetPrice(),
				CanBeDamaged = val.canBeDamaged,
				IsTeleportationIngredient = val.isTeleportationIngredient
			};
			IngredientPath val4 = val3.AddComponent<IngredientPath>();
			((Path)val4).path = ((Path)val.path).path.ToList();
			((EvenlySpacedPointsPath)val4).grindedPathStartsFrom = ((EvenlySpacedPointsPath)val.path).grindedPathStartsFrom;
			val2.path = val4;
			val2.itemStackPrefab = val.itemStackPrefab;
			val2.grindedSubstanceColor = val.grindedSubstanceColor;
			val2.grindedSubstance = val.grindedSubstance;
			val2.physicalParticleType = val.physicalParticleType;
			val2.effectMovement = val.effectMovement;
			val2.effectCollision = val.effectCollision;
			val2.effectPlantGathering = val.effectPlantGathering;
			val2.viscosityDown = val.viscosityDown;
			val2.viscosityUp = val.viscosityUp;
			val2.isSolid = val.isSolid;
			val2.spotPlantPrefab = val.spotPlantPrefab;
			val2.spotPlantSpawnTypes = new List<GrowingSpotType>();
			val2.soundPreset = val.soundPreset;
			val2.grindStatusByLeafGrindingCurve = val.grindStatusByLeafGrindingCurve;
			val2.substanceGrindingSettings = val.substanceGrindingSettings;
			val2.grindedSubstanceMaxAmount = val.grindedSubstanceMaxAmount;
			val2.OnAwake();
			Ingredient.allIngredients.Add(val2);
			return result;
		}

		public static CrucibleIngredient GetIngredientById(string id)
		{
			Ingredient val = Ingredient.allIngredients.Find((Ingredient x) => ((Object)x).name == id);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			return new CrucibleIngredient(val);
		}

		public static IEnumerable<CrucibleIngredient> GetAllIngredients()
		{
			return Ingredient.allIngredients.Select((Ingredient x) => new CrucibleIngredient(x));
		}

		public static CrucibleIngredient GetIngredientForOldId(string oldId)
		{
			Ingredient baseIngredientForOldId = GetBaseIngredientForOldId(oldId);
			if ((Object)(object)baseIngredientForOldId == (Object)null)
			{
				return null;
			}
			return new CrucibleIngredient(baseIngredientForOldId);
		}

		public void SetLocalizedName(LocalizedString name)
		{
			CrucibleLocalization.SetLocalizationKey(LocalizationKey, name);
		}

		public void SetLocalizedDescription(LocalizedString description)
		{
			CrucibleLocalization.SetLocalizationKey(LocalizationKey + "_description", description);
		}

		public void SetStack(CrucibleIngredientStackItem rootItem)
		{
			SetStack(new CrucibleIngredientStackItem[1] { rootItem });
		}

		public void SetStack(IEnumerable<CrucibleIngredientStackItem> rootItems)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			//IL_00c5: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Expected O, but got Unknown
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Expected O, but got Unknown
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Expected O, but got Unknown
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Expected O, but got Unknown
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Expected O, but got Unknown
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			EnsureOverrides();
			GameObject val = new GameObject
			{
				name = base.ID + " Stack"
			};
			val.transform.parent = GameObjectUtilities.CruciblePrefabRoot.transform;
			val.SetActive(false);
			val.AddComponent<Rigidbody2D>();
			Stack val2 = val.AddComponent<Stack>();
			((ItemFromInventory)val2).inventoryItem = base.InventoryItem;
			Traverse obj = Traverse.Create((object)val2);
			obj.Property<ItemFromInventoryController>("SoundController", (object[])null).Value = (ItemFromInventoryController)new SoundController((ItemFromInventory)(object)val2, (ItemFromInventoryPreset)(object)Ingredient.soundPreset);
			obj.Field<float>("assemblingSpeed").Value = 3f;
			val.AddComponent<StackHighlight>();
			val.AddComponent<StackVisualEffects>().stackScript = val2;
			StackTooltipContentProvider obj2 = val.AddComponent<StackTooltipContentProvider>();
			Traverse.Create((object)obj2).Field("stack").SetValue((object)val2);
			((TooltipContentProvider)obj2).fadingType = (FadingType)1;
			((TooltipContentProvider)obj2).positioningSettings = new List<PositioningSettings>
			{
				new PositioningSettings
				{
					bindingPoint = (BindingPoint)1,
					freezeX = false,
					freezeY = true,
					position = new Vector2(0f, -0.05f),
					tooltipCorner = (TooltipCorner)1
				},
				new PositioningSettings
				{
					bindingPoint = (BindingPoint)3,
					freezeX = true,
					freezeY = false,
					position = new Vector2(0.05f, 0f),
					tooltipCorner = (TooltipCorner)1
				},
				new PositioningSettings
				{
					bindingPoint = (BindingPoint)2,
					freezeX = false,
					freezeY = true,
					position = new Vector2(0f, 0.05f),
					tooltipCorner = (TooltipCorner)0
				},
				new PositioningSettings
				{
					bindingPoint = (BindingPoint)2,
					freezeX = true,
					freezeY = false,
					position = new Vector2(-0.05f, 0f),
					tooltipCorner = (TooltipCorner)2
				}
			};
			val.AddComponent<SortingOrderSetter>();
			GameObject val3 = new GameObject
			{
				name = "SlotObject"
			};
			val3.transform.parent = val.transform;
			Slot val4 = val3.AddComponent<Slot>();
			val4.conditions = (Condition[])(object)new Condition[1] { (Condition)20 };
			val3.AddComponent<ItemFromInventorySectionFinder>();
			Traverse.Create((object)val3.AddComponent<StackSlotPositionProvider>()).Field("stack").SetValue((object)val2);
			val3.AddComponent<SpriteRenderer>().sprite = SpriteUtilities.CreateBlankSprite(1, 1, Color.clear).WithName("Crucible empty slot sprite");
			val4.lineSubObject = val3.AddComponent<SlotSubLine>();
			val4.cursorAnchorSubObject = val3.AddComponent<SlotSubCursorAnchor>();
			val4.mainAnchorSubObject = val3.AddComponent<SlotSubMainAnchor>();
			val4.forbiddenAngleSubObject = val3.AddComponent<SlotSubSector>();
			foreach (CrucibleIngredientStackItem rootItem in rootItems)
			{
				CreateStackItem(rootItem).transform.parent = val.transform;
			}
			StackOverriddenIngredients.Add(Ingredient);
			Ingredient.itemStackPrefab = val;
			ReinitializeIngredient();
		}

		public IEnumerable<CrucibleBezierCurve> GetPath()
		{
			foreach (CubicBezierCurve item in ((Path)Ingredient.path).path)
			{
				yield return CrucibleBezierCurve.FromPotioncraftCurve(item);
			}
		}

		public void SetPath(IEnumerable<CrucibleBezierCurve> path)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			List<CubicBezierCurve> list = new List<CubicBezierCurve>();
			Vector2 start = Vector2.zero;
			foreach (CrucibleBezierCurve item in path)
			{
				CubicBezierCurve val = item.ToPotioncraftCurve(start);
				list.Add(val);
				start = ((BezierCurve)val).PLast;
			}
			((Path)Ingredient.path).path = list;
			((EvenlySpacedPointsPath)Ingredient.path).CalculateEvenlySpacedPoints();
			Traverse.Create((object)Ingredient).Method("CalculatePotentials", new Type[1] { typeof(IngredientPath) }, (object[])null).GetValue(new object[1] { Ingredient.path });
		}

		private static Ingredient GetBaseIngredientForOldId(string oldId)
		{
			if (!OldIngredientIdConvert.IngredientConvertDict.TryGetValue(oldId, out var _))
			{
				return null;
			}
			return Ingredient.allIngredients.Find((Ingredient x) => ((Object)x).name == oldId);
		}

		private static void SetIngredientIcon(Ingredient ingredient, Texture2D texture)
		{
			EnsureOverrides();
			if (spriteAtlas == null)
			{
				spriteAtlas = new CrucibleSpriteAtlas("CrucibleIngredients");
				CrucibleSpriteAtlasManager.AddAtlas(spriteAtlas);
			}
			spriteAtlas.SetIcon(((Object)ingredient).name.Replace(" ", string.Empty) + " SmallIcon", texture, 0f, ((Texture)texture).height - 15);
			AtlasOverriddenIngredients.Add(ingredient);
		}

		private static void EnsureOverrides()
		{
			if (overridesInitialized)
			{
				return;
			}
			overridesInitialized = true;
			IngredientsListResolveAtlasEvent.OnAtlasRequest += delegate(object _, ScriptableObjectAtlasRequestEventArgs e)
			{
				ScriptableObject @object = e.Object;
				Ingredient val2 = (Ingredient)(object)((@object is Ingredient) ? @object : null);
				if (val2 != null && AtlasOverriddenIngredients.Contains(val2))
				{
					e.AtlasResult = spriteAtlas.AtlasName;
				}
			};
			StackSpawnNewItemEvent.OnSpawnNewItemPreInititialize += delegate(object _, StackSpawnNewItemEventArgs e)
			{
				InventoryItem inventoryItem = ((ItemFromInventory)e.Stack).inventoryItem;
				Ingredient val = (Ingredient)(object)((inventoryItem is Ingredient) ? inventoryItem : null);
				if (val != null && StackOverriddenIngredients.Contains(val))
				{
					((Component)e.Stack).gameObject.SetActive(true);
					Object.Destroy((Object)(object)((ItemFromInventory)e.Stack).slot.cursorAnchorSubObject);
					Object.Destroy((Object)(object)((ItemFromInventory)e.Stack).slot.lineSubObject);
					Object.Destroy((Object)(object)((ItemFromInventory)e.Stack).slot.mainAnchorSubObject);
					Object.Destroy((Object)(object)((ItemFromInventory)e.Stack).slot.forbiddenAngleSubObject);
				}
			};
		}

		private void ReinitializeIngredient()
		{
			Traverse obj = Traverse.Create((object)Ingredient);
			obj.Method("CalculateStatesAndPrefabs", Array.Empty<object>()).GetValue();
			obj.Property<int>("MaxItems", (object[])null).Value = Ingredient.itemStackPrefab.transform.childCount;
			obj.Method("CalculateTotalCurveValue", Array.Empty<object>()).GetValue();
			Traverse.Create((object)Ingredient.substanceGrindingSettings).Method("CalculateTotalCurveValue", Array.Empty<object>()).GetValue();
		}

		private GameObject CreateStackItem(CrucibleIngredientStackItem crucibleStackItem, int depth = 0)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject
			{
				name = $"{base.ID} Stack Item {depth}"
			};
			val.transform.parent = GameObjectUtilities.CruciblePrefabRoot.transform;
			val.transform.localPosition = Vector2.op_Implicit(crucibleStackItem.PositionInStack);
			val.transform.localRotation = Quaternion.Euler(0f, 0f, crucibleStackItem.AngleInStack);
			GameObject val2 = new GameObject
			{
				name = "Collider Outer",
				layer = LayerMask.NameToLayer("IngredientsOuter")
			};
			val2.transform.parent = val.transform;
			val2.transform.localPosition = Vector3.zero;
			val2.transform.localRotation = Quaternion.identity;
			PolygonCollider2D val3 = val2.AddComponent<PolygonCollider2D>();
			GameObject val4 = new GameObject
			{
				name = "Collider Inner",
				layer = LayerMask.NameToLayer("IngredientsInner")
			};
			val4.transform.parent = val.transform;
			val4.transform.localPosition = Vector3.zero;
			val2.transform.localRotation = Quaternion.identity;
			PolygonCollider2D val5 = val4.AddComponent<PolygonCollider2D>();
			List<Vector2> colliderPolygon = crucibleStackItem.ColliderPolygon;
			List<Vector2> list = crucibleStackItem.InnerColliderPolygon ?? crucibleStackItem.ColliderPolygon;
			if (colliderPolygon != null && colliderPolygon.Count > 0)
			{
				val3.pathCount = 1;
				val3.SetPath(0, colliderPolygon);
			}
			else
			{
				List<Vector2> list2 = new List<Vector2>
				{
					new Vector2(-0.3f, -0.3f),
					new Vector2(0.3f, -0.3f),
					new Vector2(0.3f, 0.3f),
					new Vector2(-0.3f, 0.3f)
				};
				val3.SetPath(0, list2);
			}
			if (list != null && list.Count > 0)
			{
				val5.pathCount = 1;
				val5.SetPath(0, list);
			}
			else
			{
				List<Vector2> list3 = new List<Vector2>
				{
					new Vector2(-0.3f, -0.3f),
					new Vector2(0.3f, -0.3f),
					new Vector2(0.3f, 0.3f),
					new Vector2(-0.3f, 0.3f)
				};
				val5.SetPath(0, list3);
			}
			SpriteRenderer val6 = val.AddComponent<SpriteRenderer>();
			val6.sprite = crucibleStackItem.Sprite;
			IngredientFromStack val7 = val.AddComponent<IngredientFromStack>();
			((StackItem)val7).spriteRenderers = (SpriteRenderer[])(object)new SpriteRenderer[1] { val6 };
			val7.colliderOuter = val3;
			val7.colliderInner = val5;
			val7.NextStagePrefabs = crucibleStackItem.GrindChildren.Select((CrucibleIngredientStackItem x) => CreateStackItem(x, depth + 1)).ToArray();
			val.AddComponent<SortingGroup>();
			return val;
		}
	}
	public class CrucibleIngredientStackItem
	{
		public Sprite Sprite { get; set; }

		public Vector2 PositionInStack { get; set; }

		public float AngleInStack { get; set; }

		public List<Vector2> ColliderPolygon { get; set; }

		public List<Vector2> InnerColliderPolygon { get; set; }

		public List<CrucibleIngredientStackItem> GrindChildren { get; set; } = new List<CrucibleIngredientStackItem>();

	}
	public class CrucibleInventoryItem : IEquatable<CrucibleInventoryItem>, ICrucibleInventoryItemProvider
	{
		public string ID => ((Object)InventoryItem).name;

		public Sprite InventoryIcon
		{
			get
			{
				return InventoryItem.inventoryIconObject;
			}
			set
			{
				InventoryItem.inventoryIconObject = value;
			}
		}

		public float Price
		{
			get
			{
				return Traverse.Create((object)InventoryItem).Field<float>("price").Value;
			}
			set
			{
				Traverse.Create((object)InventoryItem).Field<float>("price").Value = value;
			}
		}

		public int DefaultClosenessRequirement { get; set; }

		internal InventoryItem InventoryItem { get; }

		internal CrucibleInventoryItem(InventoryItem item)
		{
			InventoryItem = item;
		}

		public static CrucibleInventoryItem GetByName(string inventoryItemName)
		{
			return new CrucibleInventoryItem(InventoryItem.GetByName(inventoryItemName));
		}

		CrucibleInventoryItem ICrucibleInventoryItemProvider.GetInventoryItem()
		{
			return this;
		}

		public bool Equals(CrucibleInventoryItem other)
		{
			return (Object)(object)InventoryIcon == (Object)(object)other.InventoryIcon;
		}

		public void GiveToPlayer(int count)
		{
			Managers.Player.inventory.AddItem(InventoryItem, count, true, true);
		}
	}
	public static class CrucibleLocalization
	{
		private static readonly Dictionary<string, LocalizedString> Localization = new Dictionary<string, LocalizedString>();

		private static bool initialized = false;

		public static void SetLocalizationKey(string key, string value)
		{
			TryInitialize();
			Localization[key] = value;
		}

		public static void SetLocalizationKey(string key, LocalizedString value)
		{
			TryInitialize();
			Localization[key] = value;
		}

		private static void TryInitialize()
		{
			if (initialized)
			{
				return;
			}
			initialized = true;
			KeyGetTextEvent.OnGetText += delegate(object _, KeyGetTextEventArgs e)
			{
				if (Localization.TryGetValue(e.Key, out var value))
				{
					e.Result = value;
				}
			};
		}
	}
	public sealed class CrucibleNpcAppearance
	{
		public enum ColorLayer
		{
			Base,
			Colorable1,
			Colorable2,
			Colorable3,
			Colorable4
		}

		public class AppearanceArraySetter
		{
			private readonly int index;

			public Sprite Background { get; set; }

			public Sprite Contour { get; set; }

			public Sprite Scratches { get; set; }

			internal AppearanceArraySetter(int index)
			{
				this.index = index;
			}

			internal void Set(ColorablePart[] parts)
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Expected O, but got Unknown
				if (parts.Length <= index)
				{
					throw new InvalidOperationException("Part array is too small.");
				}
				parts[index] = new ColorablePart
				{
					background = (Background ?? BlankSprite),
					contour = (Contour ?? BlankSprite),
					scratches = (Scratches ?? BlankSprite)
				};
			}
		}

		public sealed class Emotion : AppearanceArraySetter
		{
			internal Emotion(int index)
				: base(index)
			{
			}

			public static Emotion NegativeReaction(Sprite contour, Sprite background = null, Sprite scratches = null)
			{
				return new Emotion(0)
				{
					Background = background,
					Contour = contour,
					Scratches = scratches
				};
			}

			public static Emotion Anger2(Sprite contour, Sprite background = null, Sprite scratches = null)
			{
				return new Emotion(1)
				{
					Background = background,
					Contour = contour,
					Scratches = scratches
				};
			}

			public static Emotion Anger1(Sprite contour, Sprite background = null, Sprite scratches = null)
			{
				return new Emotion(2)
				{
					Background = background,
					Contour = contour,
					Scratches = scratches
				};
			}

			public static Emotion Idle(Sprite contour, Sprite background = null, Sprite scratches = null)
			{
				return new Emotion(3)
				{
					Background = background,
					Contour = contour,
					Scratches = scratches
				};
			}

			public static Emotion Happy1(Sprite contour, Sprite background = null, Sprite scratches = null)
			{
				return new Emotion(4)
				{
					Background = background,
					Contour = contour,
					Scratches = scratches
				};
			}

			public static Emotion PositiveReaction(Sprite contour, Sprite background = null, Sprite scratches = null)
			{
				return new Emotion(5)
				{
					Background = background,
					Contour = contour,
					Scratches = scratches
				};
			}
		}

		public class Layer : AppearanceArraySetter
		{
			internal Layer(int index)
				: base(index)
			{
			}

			public static Layer Base(Sprite background, Sprite contour = null, Sprite scratches = null)
			{
				return new Layer(0)
				{
					Background = background,
					Contour = contour,
					Scratches = scratches
				};
			}

			public static Layer Colorable1(Sprite background, Sprite contour = null, Sprite scratches = null)
			{
				return new Layer(1)
				{
					Background = background,
					Contour = contour,
					Scratches = scratches
				};
			}

			public static Layer Colorable2(Sprite background, Sprite contour = null, Sprite scratches = null)
			{
				return new Layer(2)
				{
					Background = background,
					Contour = contour,
					Scratches = scratches
				};
			}

			public static Layer Colorable3(Sprite background, Sprite contour = null, Sprite scratches = null)
			{
				return new Layer(3)
				{
					Background = background,
					Contour = contour,
					Scratches = scratches
				};
			}

			public static Layer Colorable4(Sprite background, Sprite contour = null, Sprite scratches = null)
			{
				return new Layer(4)
				{
					Background = background,
					Contour = contour,
					Scratches = scratches
				};
			}
		}

		public sealed class Hair : AppearanceArraySetter
		{
			internal Hair(int index)
				: base(index)
			{
			}

			public static Hair Right(Sprite background, Sprite contour = null, Sprite scratches = null)
			{
				return new Hair(0)
				{
					Background = background,
					Contour = contour,
					Scratches = scratches
				};
			}

			public static Hair Left(Sprite background, Sprite contour = null, Sprite scratches = null)
			{
				return new Hair(1)
				{
					Background = background,
					Contour = contour,
					Scratches = scratches
				};
			}

			public static Hair Back(Sprite background, Sprite contour = null, Sprite scratches = null)
			{
				return new Hair(2)
				{
					Background = background,
					Contour = contour,
					Scratches = scratches
				};
			}
		}

		private static readonly Sprite BlankSprite = SpriteUtilities.CreateBlankSprite(1, 1, Color.clear).WithName("Crucible cleared appearance sprite");

		private static readonly ColorablePart BlankColorablePart = new ColorablePart
		{
			background = BlankSprite,
			contour = BlankSprite,
			scratches = BlankSprite
		};

		private readonly NpcTemplate npcTemplate;

		internal CrucibleNpcAppearance(NpcTemplate template)
		{
			npcTemplate = template;
		}

		public void ClearHeadShapes()
		{
			SkullShape val = ScriptableObject.CreateInstance<SkullShape>();
			val.mask = BlankSprite;
			val.shape = BlankColorablePart;
			npcTemplate.appearance.skullShape.partsInGroup = new PartContainer<SkullShape>[1]
			{
				new PartContainer<SkullShape>
				{
					part = val
				}
			};
		}

		public void AddHeadShape(Sprite headShape, float chance = 1f)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			Bounds bounds = headShape.bounds;
			int width = (int)Math.Ceiling(((Bounds)(ref bounds)).size.x);
			bounds = headShape.bounds;
			Sprite mask = SpriteUtilities.CreateBlankSprite(width, (int)Math.Ceiling(((Bounds)(ref bounds)).size.y), Color.clear);
			AddHeadShape(mask, headShape, null, null, chance);
		}

		public void AddHeadShape(Sprite mask, Sprite background, Sprite contour = null, Sprite scratches = null, float chance = 1f)
		{
			//IL_000e: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			SkullShape val = ScriptableObject.CreateInstance<SkullShape>();
			val.mask = mask;
			val.shape = new ColorablePart
			{
				background = background,
				contour = contour,
				scratches = scratches
			};
			PartContainer<SkullShape> val2 = new PartContainer<SkullShape>
			{
				part = val,
				chanceBtwParts = chance
			};
			PartContainerGroup<SkullShape> skullShape = npcTemplate.appearance.skullShape;
			if (skullShape.partsInGroup.Length == 1)
			{
				SkullShape part = skullShape.partsInGroup[0].part;
				object obj;
				if (part == null)
				{
					obj = null;
				}
				else
				{
					ColorablePart shape = part.shape;
					if (shape == null)
					{
						obj = null;
					}
					else
					{
						Sprite background2 = shape.background;
						obj = ((background2 != null) ? ((Object)background2).name : null);
					}
				}
				if ((string?)obj == ((Object)BlankSprite).name)
				{
					skullShape.partsInGroup = new PartContainer<SkullShape>[1] { val2 };
					goto IL_00d3;
				}
			}
			skullShape.partsInGroup = skullShape.partsInGroup.Concat(new PartContainer<SkullShape>[1] { val2 }).ToArray();
			goto IL_00d3;
			IL_00d3:
			((Object)val).name = $"skull_shape {skullShape.partsInGroup.Length}";
		}

		public void ClearBodies()
		{
			ColorablePart[] array = Enumerable.Repeat<ColorablePart>(BlankColorablePart, 5).ToArray();
			Body val = ScriptableObject.CreateInstance<Body>();
			val.bodyBase = array;
			val.bodyBaseSkin = BlankColorablePart;
			val.handBack = array;
			val.handBackSkin = BlankColorablePart;
			val.handFront = array;
			val.handFrontSkin = BlankColorablePart;
			npcTemplate.appearance.body.partsInGroup = new PartContainer<Body>[1]
			{
				new PartContainer<Body>
				{
					part = val
				}
			};
		}

		public void AddBody(Sprite body, Sprite leftArm, Sprite rightArm, float chance = 1f)
		{
			AddBody(new Layer[1] { Layer.Base(body) }, new Layer[1] { Layer.Base(leftArm) }, new Layer[1] { Layer.Base(rightArm) }, chance);
		}

		public void AddBody(Layer[] bodyLayers, Layer[] leftArmLayers, Layer[] rightArmLayers, float chance = 1f)
		{
			Body val = ScriptableObject.CreateInstance<Body>();
			val.bodyBase = Enumerable.Repeat<ColorablePart>(BlankColorablePart, 5).ToArray();
			val.bodyBaseSkin = BlankColorablePart;
			Layer[] array = bodyLayers;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].Set(val.bodyBase);
			}
			val.handBack = Enumerable.Repeat<ColorablePart>(BlankColorablePart, 5).ToArray();
			val.handBackSkin = BlankColorablePart;
			array = leftArmLayers;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].Set(val.handBack);
			}
			val.handFront = Enumerable.Repeat<ColorablePart>(BlankColorablePart, 5).ToArray();
			val.handFrontSkin = BlankColorablePart;
			array = rightArmLayers;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].Set(val.handFront);
			}
			PartContainer<Body> val2 = new PartContainer<Body>
			{
				part = val,
				chanceBtwParts = chance
			};
			PartContainerGroup<Body> body = npcTemplate.appearance.body;
			if (body.partsInGroup.Length == 1)
			{
				Body part = body.partsInGroup[0].part;
				if (part != null && part.bodyBase?.Length >= 1)
				{
					Body part2 = body.partsInGroup[0].part;
					object obj;
					if (part2 == null)
					{
						obj = null;
					}
					else
					{
						ColorablePart obj2 = part2.bodyBase[0];
						if (obj2 == null)
						{
							obj = null;
						}
						else
						{
							Sprite background = obj2.background;
							obj = ((background != null) ? ((Object)background).name : null);
						}
					}
					if ((string?)obj == ((Object)BlankSprite).name)
					{
						body.partsInGroup = new PartContainer<Body>[1] { val2 };
						goto IL_01c9;
					}
				}
			}
			body.partsInGroup = body.partsInGroup.Concat(new PartContainer<Body>[1] { val2 }).ToArray();
			goto IL_01c9;
			IL_01c9:
			((Object)val).name = $"body {body.partsInGroup.Length}";
		}

		public void AddBeard(Sprite background, Sprite contour, Sprite scratches, float chance)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			Beard val = ScriptableObject.CreateInstance<Beard>();
			val.beardBase = new ColorablePart
			{
				background = background,
				contour = contour,
				scratches = scratches
			};
			PartContainer<Beard> val2 = new PartContainer<Beard>
			{
				part = val,
				chanceBtwParts = chance
			};
			PartContainerGroup<Beard> beard = npcTemplate.appearance.beard;
			if (beard.partsInGroup.Length == 1)
			{
				Beard part = beard.partsInGroup[0].part;
				object obj;
				if (part == null)
				{
					obj = null;
				}
				else
				{
					ColorablePart beardBase = part.beardBase;
					if (beardBase == null)
					{
						obj = null;
					}
					else
					{
						Sprite background2 = beardBase.background;
						obj = ((background2 != null) ? ((Object)background2).name : null);
					}
				}
				if ((string?)obj == ((Object)BlankSprite).name)
				{
					beard.partsInGroup = new PartContainer<Beard>[1] { val2 };
					goto IL_00cb;
				}
			}
			beard.partsInGroup = beard.partsInGroup.Concat(new PartContainer<Beard>[1] { val2 }).ToArray();
			goto IL_00cb;
			IL_00cb:
			((Object)val).name = $"beard {beard.partsInGroup.Length}";
		}

		public void ClearBeards()
		{
			Beard val = ScriptableObject.CreateInstance<Beard>();
			val.beardBase = BlankColorablePart;
			npcTemplate.appearance.beard.partsInGroup = new PartContainer<Beard>[1]
			{
				new PartContainer<Beard>
				{
					part = val
				}
			};
		}

		public void ClearFaces()
		{
			Face val = ScriptableObject.CreateInstance<Face>();
			val.skin = (val.hair = Enumerable.Repeat<ColorablePart>(BlankColorablePart, 6).ToArray());
			npcTemplate.appearance.face.partsInGroup = new PartContainer<Face>[1]
			{
				new PartContainer<Face>
				{
					part = val
				}
			};
		}

		public void AddFace(Sprite idle, float chance = 1f)
		{
			AddFace(new Emotion[1] { Emotion.Idle(idle) }, chance);
		}

		public void AddFace(Sprite idle, Sprite positiveReaction, Sprite negativeReaction, float chance = 1f)
		{
			AddFace(new Emotion[3]
			{
				Emotion.Idle(idle),
				Emotion.PositiveReaction(positiveReaction),
				Emotion.NegativeReaction(negativeReaction)
			}, chance);
		}

		public void AddFace(Emotion[] emotions, float chance = 1f)
		{
			Face val = ScriptableObject.CreateInstance<Face>();
			val.hair = Enumerable.Repeat<ColorablePart>(BlankColorablePart, 6).ToArray();
			for (int i = 0; i < emotions.Length; i++)
			{
				emotions[i].Set(val.hair);
			}
			ColorablePart val2 = val.hair[3];
			if (((Object)val2.contour).name != ((Object)BlankSprite).name)
			{
				for (int j = 0; j < val.hair.Length; j++)
				{
					if (j != 3 && ((Object)val.hair[j].contour).name == ((Object)BlankSprite).name)
					{
						val.hair[j] = val2;
					}
				}
			}
			val.skin = Enumerable.Repeat<ColorablePart>(BlankColorablePart, 6).ToArray();
			PartContainer<Face> val3 = new PartContainer<Face>
			{
				part = val,
				chanceBtwParts = chance
			};
			PartContainerGroup<Face> face = npcTemplate.appearance.face;
			if (face.partsInGroup.Length == 1)
			{
				Face part = face.partsInGroup[0].part;
				if (part != null && part.hair?.Length >= 6)
				{
					Face part2 = face.partsInGroup[0].part;
					object obj;
					if (part2 == null)
					{
						obj = null;
					}
					else
					{
						ColorablePart obj2 = part2.hair[3];
						if (obj2 == null)
						{
							obj = null;
						}
						else
						{
							Sprite contour = obj2.contour;
							obj = ((contour != null) ? ((Object)contour).name : null);
						}
					}
					if ((string?)obj == ((Object)BlankSprite).name)
					{
						face.partsInGroup = new PartContainer<Face>[1] { val3 };
						goto IL_01bd;
					}
				}
			}
			face.partsInGroup = face.partsInGroup.Concat(new PartContainer<Face>[1] { val3 }).ToArray();
			goto IL_01bd;
			IL_01bd:
			((Object)val).name = $"face {face.partsInGroup.Length}";
		}

		public void ClearEyes()
		{
			Eyes val = ScriptableObject.CreateInstance<Eyes>();
			val.left = BlankSprite;
			val.right = BlankSprite;
			npcTemplate.appearance.eyes.partsInGroup = new PartContainer<Eyes>[1]
			{
				new PartContainer<Eyes>
				{
					part = val
				}
			};
		}

		public void AddEyes(Sprite leftEye, Sprite rightEye, float chance = 1f)
		{
			Eyes val = ScriptableObject.CreateInstance<Eyes>();
			val.left = leftEye;
			val.right = rightEye;
			PartContainer<Eyes> val2 = new PartContainer<Eyes>
			{
				part = val,
				chanceBtwPart

plugins/Crucible.Ingredients.dll

Decompiled 11 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using Microsoft.CodeAnalysis;
using RoboPhredDev.PotionCraft.Crucible.CruciblePackages;
using RoboPhredDev.PotionCraft.Crucible.GameAPI;
using RoboPhredDev.PotionCraft.Crucible.SVG;
using RoboPhredDev.PotionCraft.Crucible.Yaml;
using UnityEngine;
using YamlDotNet.Core;
using YamlDotNet.Serialization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("Crucible.Ingredients")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Crucible.Ingredients")]
[assembly: AssemblyTitle("Crucible.Ingredients")]
[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;
		}
	}
}
namespace RoboPhredDev.PotionCraft.Crucible.Ingredients
{
	public class CrucibleIngredientConfig : CruciblePackageConfigSubjectNode<CrucibleIngredient>
	{
		[YamlMember(Alias = "id")]
		public string ID { get; set; }

		public LocalizedString Name { get; set; }

		public LocalizedString Description { get; set; }

		public string InheritFrom { get; set; }

		public Sprite InventoryImage { get; set; }

		public Sprite RecipeStepImage { get; set; }

		public Sprite IngredientListIcon { get; set; }

		public float? BasePrice { get; set; }

		public SvgPath Path { get; set; }

		public float? GrindStartPercent { get; set; }

		public Color? GroundColor { get; set; }

		public bool? IsTeleportationIngredient { get; set; }

		public OneOrMany<CrucibleIngredientStackItemConfig> StackItems { get; set; }

		public bool? IsStackItemsSolid { get; set; }

		public int ClosenessRequirement { get; set; }

		public override string ToString()
		{
			return ((CruciblePackageConfigNode)this).PackageMod.Namespace + "." + ID;
		}

		protected override void OnDeserializeCompleted(Mark start, Mark end)
		{
			if (string.IsNullOrWhiteSpace(ID))
			{
				throw new Exception($"Ingredient at {start} must have an id.");
			}
		}

		protected override CrucibleIngredient GetSubject()
		{
			string text = ((CruciblePackageConfigNode)this).PackageMod.Namespace + "." + ID;
			return CrucibleIngredient.GetIngredientById(text) ?? CrucibleIngredient.CreateIngredient(text, InheritFrom ?? "Waterbloom");
		}

		protected override void OnApplyConfiguration(CrucibleIngredient subject)
		{
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			if (Name != null)
			{
				subject.SetLocalizedName(Name);
			}
			if (Description != null)
			{
				subject.SetLocalizedDescription(Description);
			}
			if ((Object)(object)InventoryImage != (Object)null)
			{
				((CrucibleInventoryItem)subject).InventoryIcon = InventoryImage;
			}
			if ((Object)(object)RecipeStepImage != (Object)null)
			{
				subject.RecipeStepIcon = RecipeStepImage;
			}
			if ((Object)(object)IngredientListIcon != (Object)null)
			{
				subject.IngredientListIcon = IngredientListIcon;
			}
			if (BasePrice.HasValue)
			{
				((CrucibleInventoryItem)subject).Price = BasePrice.Value;
			}
			if (IsTeleportationIngredient.HasValue)
			{
				subject.IsTeleportationIngredient = IsTeleportationIngredient.Value;
			}
			if (GrindStartPercent.HasValue)
			{
				subject.PathPregrindPercentage = GrindStartPercent.Value;
			}
			if (Path != null)
			{
				subject.SetPath(Path.ToPathSegments());
			}
			if (GroundColor.HasValue)
			{
				subject.GroundColor = GroundColor.Value;
			}
			if (StackItems != null && StackItems.Count > 0)
			{
				subject.SetStack(((IEnumerable<CrucibleIngredientStackItemConfig>)StackItems).Select((CrucibleIngredientStackItemConfig x) => x.ToStackItem()));
			}
			if (IsStackItemsSolid.HasValue)
			{
				subject.IsStackItemSolid = IsStackItemsSolid.Value;
			}
			if (ClosenessRequirement > 0)
			{
				((CrucibleInventoryItem)subject).DefaultClosenessRequirement = ClosenessRequirement;
			}
		}
	}
	[CruciblePackageConfigRoot]
	public class CrucibleIngredientsConfigRoot : CruciblePackageConfigRoot
	{
		public List<CrucibleIngredientConfig> Ingredients { get; set; } = new List<CrucibleIngredientConfig>();


		public override void ApplyConfiguration()
		{
			Ingredients.ForEach(delegate(CrucibleIngredientConfig x)
			{
				((CruciblePackageConfigSubjectNode<CrucibleIngredient>)x).ApplyConfiguration();
			});
		}
	}
	[BepInPlugin("net.RoboPhredDev.PotionCraft.Crucible.Ingredients", "Ingredient support for Crucible Modding Framework", "1.1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class CrucibleIngredientsPlugin : BaseUnityPlugin
	{
	}
	public class CrucibleIngredientStackItemConfig : CruciblePackageConfigNode
	{
		public Sprite Sprite { get; set; }

		public Vector2 PositionInStack { get; set; }

		public float AngleInStack { get; set; }

		public SvgPath Collision { get; set; }

		public SvgPath SelfCollision { get; set; }

		public OneOrMany<CrucibleIngredientStackItemConfig> GrindsInto { get; set; }

		public CrucibleIngredientStackItem ToStackItem()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_004a: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			if (SelfCollision != null && string.IsNullOrEmpty(SelfCollision.Data))
			{
				SvgPath selfCollision = SelfCollision;
				SvgPath collision = Collision;
				selfCollision.Data = ((collision != null) ? collision.Data : null);
			}
			CrucibleIngredientStackItem val = new CrucibleIngredientStackItem
			{
				Sprite = Sprite,
				PositionInStack = PositionInStack,
				AngleInStack = AngleInStack
			};
			SvgPath collision2 = Collision;
			val.ColliderPolygon = ((collision2 != null) ? collision2.ToPoints() : null);
			SvgPath selfCollision2 = SelfCollision;
			val.InnerColliderPolygon = ((selfCollision2 != null) ? selfCollision2.ToPoints() : null);
			CrucibleIngredientStackItem val2 = val;
			if (GrindsInto != null)
			{
				val2.GrindChildren = ((IEnumerable<CrucibleIngredientStackItemConfig>)GrindsInto).Select((CrucibleIngredientStackItemConfig x) => x.ToStackItem()).ToList();
			}
			return val2;
		}
	}
}

plugins/Crucible.NPCs.dll

Decompiled 11 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using Microsoft.CodeAnalysis;
using RoboPhredDev.PotionCraft.Crucible.CruciblePackages;
using RoboPhredDev.PotionCraft.Crucible.GameAPI;
using RoboPhredDev.PotionCraft.Crucible.Yaml;
using UnityEngine;
using YamlDotNet.Serialization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("Crucible.NPCs")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Crucible.NPCs")]
[assembly: AssemblyTitle("Crucible.NPCs")]
[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;
		}
	}
}
namespace RoboPhredDev.PotionCraft.Crucible.NPCs
{
	public class CrucibleAdditionalEffectsQuestRequirementConfig : CrucibleQuestRequirementConfig
	{
		public bool AdditionalEffect { get; set; } = true;


		public override CrucibleQuestRequirement GetSubject()
		{
			return CrucibleQuestRequirement.GetByName("AdditionalEffects");
		}
	}
	[CruciblePackageConfigRoot]
	public class CrucibleCustomersConfigRoot : CruciblePackageConfigRoot
	{
		public List<CrucibleCustomerConfig> Customers { get; set; } = new List<CrucibleCustomerConfig>();


		public List<CrucibleTraderConfig> Traders { get; set; } = new List<CrucibleTraderConfig>();


		public override void ApplyConfiguration()
		{
			Customers.ForEach(delegate(CrucibleCustomerConfig x)
			{
				((CruciblePackageConfigSubjectNode<CrucibleCustomerNpcTemplate>)x).ApplyConfiguration();
			});
			Traders.ForEach(delegate(CrucibleTraderConfig x)
			{
				((CruciblePackageConfigSubjectNode<CrucibleTraderNpcTemplate>)x).ApplyConfiguration();
			});
		}
	}
	public abstract class CrucibleEffectChanceConfig : CruciblePackageConfigNode
	{
		public string EffectID { get; set; }

		public int ChanceToAppear { get; set; } = 1;

	}
	public class CrucibleFactionConfig : CruciblePackageConfigRoot
	{
		public List<CrucibleSpawnChanceConfig> SpawnChance { get; set; } = new List<CrucibleSpawnChanceConfig>
		{
			new CrucibleRangeSpawnChanceConfig()
		};


		public int MinChapter { get; set; } = 1;


		public int MaxChapter { get; set; } = 10;


		public string VisualMood { get; set; } = "Normal";


		public List<CrucibleEffectChanceConfig> QuestEffectChances { get; set; } = new List<CrucibleEffectChanceConfig>();


		public override void ApplyConfiguration()
		{
			throw new NotImplementedException();
		}
	}
	public class CrucibleHagglingThemesConfig : CruciblePackageConfigNode
	{
		public string VeryEasyTheme { get; set; }

		public string EasyTheme { get; set; }

		public string MediumTheme { get; set; }

		public string HardTheme { get; set; }

		public string VeryHardTheme { get; set; }

		public void ApplyConfiguration(CrucibleNpcTemplate subject)
		{
			subject.SetHagglingThemes(VeryEasyTheme, EasyTheme, MediumTheme, HardTheme, VeryHardTheme);
		}
	}
	public class CrucibleNpcAppearanceConfig
	{
		public class HeadShapeConfig
		{
			public float Chance { get; set; } = 1f;


			public Sprite Mask { get; set; }

			public Sprite Background { get; set; }

			public Sprite Contour { get; set; }

			public Sprite Scratches { get; set; }

			public void Apply(CrucibleNpcTemplate npc)
			{
				npc.Appearance.AddHeadShape(Mask, Background, Contour, Scratches, Chance);
			}
		}

		public class BodyConfig
		{
			public float Chance { get; set; } = 1f;


			public Sprite Torso { get; set; }

			public Sprite LeftArm { get; set; }

			public Sprite RightArm { get; set; }

			public void Apply(CrucibleNpcTemplate npc)
			{
				npc.Appearance.AddBody(Torso ?? BlankSprite, LeftArm ?? BlankSprite, RightArm ?? BlankSprite, Chance);
			}
		}

		public class FaceConfig
		{
			public float Chance { get; set; } = 1f;


			public Sprite PositiveReaction { get; set; }

			public Sprite NegativeReaction { get; set; }

			public Sprite Idle { get; set; }

			public Sprite Anger1 { get; set; }

			public Sprite Anger2 { get; set; }

			public Sprite Happy1 { get; set; }

			public void Apply(CrucibleNpcTemplate npc)
			{
				List<Emotion> list = new List<Emotion>();
				if (Object.op_Implicit((Object)(object)PositiveReaction))
				{
					list.Add(Emotion.PositiveReaction(PositiveReaction, (Sprite)null, (Sprite)null));
				}
				if (Object.op_Implicit((Object)(object)NegativeReaction))
				{
					list.Add(Emotion.NegativeReaction(NegativeReaction, (Sprite)null, (Sprite)null));
				}
				if (Object.op_Implicit((Object)(object)Idle))
				{
					list.Add(Emotion.Idle(Idle, (Sprite)null, (Sprite)null));
				}
				if (Object.op_Implicit((Object)(object)Anger1))
				{
					list.Add(Emotion.Anger1(Anger1, (Sprite)null, (Sprite)null));
				}
				if (Object.op_Implicit((Object)(object)Anger2))
				{
					list.Add(Emotion.Anger2(Anger2, (Sprite)null, (Sprite)null));
				}
				if (Object.op_Implicit((Object)(object)Happy1))
				{
					list.Add(Emotion.Happy1(Happy1, (Sprite)null, (Sprite)null));
				}
				npc.Appearance.AddFace(list.ToArray(), Chance);
			}
		}

		public class EyesConfig
		{
			public float Chance { get; set; } = 1f;


			public Sprite LeftEye { get; set; }

			public Sprite RightEye { get; set; }

			public void Apply(CrucibleNpcTemplate npc)
			{
				npc.Appearance.AddEyes(LeftEye ?? BlankSprite, RightEye ?? BlankSprite, Chance);
			}
		}

		public class HairStyleConfig
		{
			public float Chance { get; set; } = 1f;


			public Sprite FrontLeft { get; set; }

			public Sprite FrontRight { get; set; }

			public Sprite Back { get; set; }

			public void Apply(CrucibleNpcTemplate npc)
			{
				List<Hair> list = new List<Hair>();
				if ((Object)(object)FrontLeft != (Object)null)
				{
					list.Add(Hair.Left(FrontLeft, (Sprite)null, (Sprite)null));
				}
				if ((Object)(object)FrontRight != (Object)null)
				{
					list.Add(Hair.Right(FrontRight, (Sprite)null, (Sprite)null));
				}
				if ((Object)(object)Back != (Object)null)
				{
					list.Add(Hair.Back(Back, (Sprite)null, (Sprite)null));
				}
				npc.Appearance.AddHairStyle(list.ToArray(), Chance);
			}
		}

		public class BeardConfig
		{
			public float Chance { get; set; } = 1f;


			public Sprite Background { get; set; }

			public Sprite Contour { get; set; }

			public Sprite Scratches { get; set; }

			public void Apply(CrucibleNpcTemplate npc)
			{
				npc.Appearance.AddBeard(Background ?? BlankSprite, Contour ?? BlankSprite, Scratches ?? BlankSprite, Chance);
			}
		}

		private static readonly Sprite BlankSprite = SpriteUtilities.WithName(SpriteUtilities.CreateBlankSprite(1, 1, Color.clear), "Crucible unset appearance sprite");

		public OneOrMany<HeadShapeConfig> HeadShape { get; set; }

		public OneOrMany<HairStyleConfig> HairStyle { get; set; }

		public OneOrMany<FaceConfig> Face { get; set; }

		public OneOrMany<EyesConfig> Eyes { get; set; }

		public OneOrMany<BeardConfig> Beard { get; set; }

		public OneOrMany<BodyConfig> Body { get; set; }

		public void ApplyAppearance(CrucibleNpcTemplate npc)
		{
			if (HeadShape != null)
			{
				npc.Appearance.ClearHeadShapes();
				foreach (HeadShapeConfig item in HeadShape)
				{
					item.Apply(npc);
				}
			}
			if (HairStyle != null)
			{
				npc.Appearance.ClearHairStyles();
				foreach (HairStyleConfig item2 in HairStyle)
				{
					item2.Apply(npc);
				}
			}
			if (Face != null)
			{
				npc.Appearance.ClearFaces();
				foreach (FaceConfig item3 in Face)
				{
					item3.Apply(npc);
				}
			}
			if (Eyes != null)
			{
				npc.Appearance.ClearEyes();
				foreach (EyesConfig eye in Eyes)
				{
					eye.Apply(npc);
				}
			}
			if (Beard != null)
			{
				npc.Appearance.ClearBeards();
				foreach (BeardConfig item4 in Beard)
				{
					item4.Apply(npc);
				}
			}
			if (Body == null)
			{
				return;
			}
			npc.Appearance.ClearBodies();
			foreach (BodyConfig item5 in Body)
			{
				item5.Apply(npc);
			}
		}
	}
	public abstract class CrucibleNPCConfig<T> : CruciblePackageConfigSubjectNode<T> where T : CrucibleNpcTemplate
	{
		[YamlMember(Alias = "id")]
		public string ID { get; set; }

		public string InheritFrom { get; set; } = "Brewer";


		public int MaximumCloseness { get; set; } = -1;


		public int MinimumDaysOfCooldown { get; set; }

		public int MaximumDaysOfCooldown { get; set; }

		public CrucibleNpcAppearanceConfig Appearance { get; set; }

		public OneOrMany<CrucibleNPCDialogueQuestConfig> Quests { get; set; } = new OneOrMany<CrucibleNPCDialogueQuestConfig>();


		public OneOrMany<string> Tags { get; set; }

		public string Gender { get; set; }

		public string VisualMood { get; set; }

		public CrucibleHagglingThemesConfig HagglingThemes { get; set; }

		public override string ToString()
		{
			return ((CruciblePackageConfigNode)this).PackageMod.Namespace + "." + ID;
		}

		protected override void OnApplyConfiguration(T subject)
		{
			Appearance?.ApplyAppearance((CrucibleNpcTemplate)(object)subject);
			if (MinimumDaysOfCooldown > 0 && MaximumDaysOfCooldown > 0)
			{
				if (MinimumDaysOfCooldown > MaximumDaysOfCooldown)
				{
					throw new ArgumentException("MinimumDaysOfCooldown must be less than or equal to MaximumDaysOfCooldown!");
				}
				((CrucibleNpcTemplate)subject).DaysOfCooldown = (MinimumDaysOfCooldown, MaximumDaysOfCooldown);
			}
			if (!string.IsNullOrEmpty(Gender))
			{
				((CrucibleNpcTemplate)subject).Gender = Gender;
			}
			if (!string.IsNullOrEmpty(VisualMood))
			{
				((CrucibleNpcTemplate)subject).VisualMood = VisualMood;
			}
			if (MaximumCloseness > 0)
			{
				((CrucibleNpcTemplate)subject).SetMaximumCloseness(MaximumCloseness);
			}
			HagglingThemes?.ApplyConfiguration((CrucibleNpcTemplate)(object)subject);
			((CrucibleNpcTemplate)subject).PrepareClosenessQuestsForNewQuests();
			_ = ((CrucibleNpcTemplate)subject).ClosenessQuests;
			List<CrucibleNPCDialogueQuestConfig> source = ((IEnumerable<CrucibleNPCDialogueQuestConfig>)Quests).OrderByDescending((CrucibleNPCDialogueQuestConfig d) => d.ClosenessRequirement).ToList();
			int num = 0;
			int maximumCloseness = ((CrucibleNpcTemplate)subject).MaximumCloseness;
			int closeness;
			for (closeness = 0; closeness < maximumCloseness; closeness++)
			{
				CrucibleNPCDialogueQuestConfig crucibleNPCDialogueQuestConfig = source.FirstOrDefault((CrucibleNPCDialogueQuestConfig d) => d.ClosenessRequirement >= 0 && d.ClosenessRequirement <= closeness);
				if (crucibleNPCDialogueQuestConfig == null)
				{
					continue;
				}
				bool flag = subject is CrucibleCustomerNpcTemplate || crucibleNPCDialogueQuestConfig.ClosenessRequirement == closeness;
				if ((flag && crucibleNPCDialogueQuestConfig.Quest != null) || subject is CrucibleCustomerNpcTemplate)
				{
					if (crucibleNPCDialogueQuestConfig.Quest == null)
					{
						throw new ArgumentException("Dialgue without quests is not allowed for customer npcs. Each unique dialogue tree must also define a quest.");
					}
					CrucibleQuest val = ((CrucibleNpcTemplate)subject).ClosenessQuests[closeness];
					if (string.IsNullOrEmpty(crucibleNPCDialogueQuestConfig.Quest.ID) || (int.TryParse(crucibleNPCDialogueQuestConfig.Quest.ID, out var result) && result == closeness - 1))
					{
						crucibleNPCDialogueQuestConfig.Quest.ID = closeness.ToString();
					}
					crucibleNPCDialogueQuestConfig.Quest.ID = ((CrucibleNpcTemplate)subject).ID + "." + crucibleNPCDialogueQuestConfig.Quest.ID;
					crucibleNPCDialogueQuestConfig.Quest.ApplyConfiguration(val);
					val.SetQuestText(crucibleNPCDialogueQuestConfig.Dialogue, crucibleNPCDialogueQuestConfig.Quest.SubsequentVisitsQuestText);
					num++;
				}
				((CrucibleNpcTemplate)subject).ApplyDialogueForClosenessLevel(closeness, crucibleNPCDialogueQuestConfig.Dialogue, flag);
			}
			if (num < Quests.Count)
			{
				CrucibleLog.Log($"Some quests were not applied to NPC due to issues with specified closeness requirements. Be sure you have specified a closeness requirement for each quest and that each closeness is less than the maximum closeness level ({((CrucibleNpcTemplate)subject).MaximumCloseness}).", Array.Empty<object>());
			}
			if (Tags == null)
			{
				return;
			}
			foreach (string tag in Tags)
			{
				((CrucibleNpcTemplate)subject).AddTag(tag);
			}
		}
	}
	[BepInPlugin("net.RoboPhredDev.PotionCraft.Crucible.NPCs", "NPC support for Crucible Modding Framework", "1.1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class CrucibleNPCsPlugin : BaseUnityPlugin
	{
	}
	public class CrucibleRangeSpawnChanceConfig : CrucibleSpawnChanceConfig
	{
		public float KarmaMin { get; set; } = -100f;


		public float KarmaMax { get; set; } = 100f;

	}
	public class CrucibleSinglePointSpawnChanceConfig : CrucibleSpawnChanceConfig
	{
		public float Karma { get; set; }
	}
	[DuckTypeCandidate(typeof(CrucibleRangeSpawnChanceConfig))]
	[DuckTypeCandidate(typeof(CrucibleSinglePointSpawnChanceConfig))]
	public abstract class CrucibleSpawnChanceConfig : CruciblePackageConfigNode
	{
		public float ChanceToAppear { get; set; } = 50f;

	}
	public class CrucibleCustomerConfig : CrucibleNPCConfig<CrucibleCustomerNpcTemplate>
	{
		public float ChanceToAppear { get; set; } = 1f;


		public override string ToString()
		{
			return ((CruciblePackageConfigNode)this).PackageMod.Namespace + "." + base.ID;
		}

		protected override CrucibleCustomerNpcTemplate GetSubject()
		{
			string text = ((CruciblePackageConfigNode)this).PackageMod.Namespace + "." + base.ID;
			return CrucibleCustomerNpcTemplate.GetCustomerNpcTemplateById(text) ?? CrucibleCustomerNpcTemplate.CreateCustomerNpcTemplate(text, base.InheritFrom);
		}

		protected override void OnApplyConfiguration(CrucibleCustomerNpcTemplate subject)
		{
			foreach (CrucibleNPCDialogueQuestConfig quest in base.Quests)
			{
				if (!quest.Dialogue.HasQuestNode)
				{
					quest.Dialogue.IsQuestNode = true;
				}
			}
			base.OnApplyConfiguration(subject);
			if (ChanceToAppear > 0f)
			{
				subject.SpawnChance = ChanceToAppear;
			}
		}
	}
	public class CrucibleMainIngredientQuestRequirementConfig : CrucibleQuestRequirementConfig
	{
		public string MainIngredient { get; set; }

		public override CrucibleQuestRequirement GetSubject()
		{
			return CrucibleQuestRequirement.GetByName("MainIngredient");
		}

		public override void ApplyConfiguration(CrucibleQuestRequirement reqSubject)
		{
			reqSubject.RequirementIngredient = MainIngredient;
		}
	}
	public class CrucibleMaxIngredientsQuestRequirementConfig : CrucibleQuestRequirementConfig
	{
		public int MaximumIngredients { get; set; } = 3;


		public override CrucibleQuestRequirement GetSubject()
		{
			if (MaximumIngredients < 0 || MaximumIngredients > 3)
			{
				throw new ArgumentException("Maximum ingredient quest requirement must be greater than 0 and less than 3.");
			}
			return CrucibleQuestRequirement.GetByName($"MaxIngredients{MaximumIngredients}");
		}
	}
	public class CrucibleNeedIngredientQuestRequirementConfig : CrucibleQuestRequirementConfig
	{
		public string NeedAtleastOneIngredient { get; set; }

		public override CrucibleQuestRequirement GetSubject()
		{
			return CrucibleQuestRequirement.GetByName("NeedOneParticularIngredient");
		}

		public override void ApplyConfiguration(CrucibleQuestRequirement reqSubject)
		{
			reqSubject.RequirementIngredient = NeedAtleastOneIngredient;
		}
	}
	public class CrucibleNoIngredientQuestRequirementConfig : CrucibleQuestRequirementConfig
	{
		public string IngredientNotAllowed { get; set; }

		public override CrucibleQuestRequirement GetSubject()
		{
			return CrucibleQuestRequirement.GetByName("NoParticularIngredient");
		}

		public override void ApplyConfiguration(CrucibleQuestRequirement reqSubject)
		{
			reqSubject.RequirementIngredient = IngredientNotAllowed;
		}
	}
	public class CrucibleNPCDialogueQuestConfig : CruciblePackageConfigNode
	{
		public int ClosenessRequirement { get; set; }

		public CrucibleNPCQuestConfig Quest { get; set; }

		public CrucibleDialogueNode Dialogue { get; set; }
	}
	public class CrucibleNPCQuestConfig : CruciblePackageConfigNode
	{
		[YamlMember(Alias = "id")]
		public string ID { get; set; }

		public int KarmaReward { get; set; }

		public OneOrMany<string> DesiredEffects { get; set; } = new OneOrMany<string>();


		public LocalizedString SubsequentVisitsQuestText { get; set; }

		public int MinimumChapter { get; set; }

		public int MaximumChapter { get; set; } = 10;


		public bool GenerateRandomMandatoryRequirements { get; set; }

		public OneOrMany<CrucibleQuestRequirementConfig> MandatoryRequirements { get; set; } = new OneOrMany<CrucibleQuestRequirementConfig>();


		public bool GenerateRandomOptionalRequirements { get; set; }

		public OneOrMany<CrucibleQuestRequirementConfig> OptionalRequirements { get; set; } = new OneOrMany<CrucibleQuestRequirementConfig>();


		public void ApplyConfiguration(CrucibleQuest subject)
		{
			subject.ID = ((CruciblePackageConfigNode)this).PackageMod.Namespace + "." + ID;
			subject.KarmaReward = KarmaReward;
			subject.DesiredEffects = ((IEnumerable<string>)DesiredEffects).ToList();
			subject.MinMaxChapters = (MinimumChapter, MaximumChapter);
			subject.GenerateRandomMandatoryRequirements = GenerateRandomMandatoryRequirements;
			foreach (CrucibleQuestRequirementConfig mandatoryRequirement in MandatoryRequirements)
			{
				CrucibleQuestRequirement subject2 = mandatoryRequirement.GetSubject();
				subject.AddMandatoryRequirement(subject2);
				mandatoryRequirement.ApplyConfiguration(subject2);
			}
			subject.GenerateRandomOptionalRequirements = GenerateRandomOptionalRequirements;
			foreach (CrucibleQuestRequirementConfig optionalRequirement in OptionalRequirements)
			{
				CrucibleQuestRequirement subject3 = optionalRequirement.GetSubject();
				subject.AddOptionalRequirement(subject3);
				optionalRequirement.ApplyConfiguration(subject3);
			}
		}
	}
	[DuckTypeCandidate(typeof(CrucibleAdditionalEffectsQuestRequirementConfig))]
	[DuckTypeCandidate(typeof(CrucibleMainIngredientQuestRequirementConfig))]
	[DuckTypeCandidate(typeof(CrucibleMaxIngredientsQuestRequirementConfig))]
	[DuckTypeCandidate(typeof(CrucibleNeedIngredientQuestRequirementConfig))]
	[DuckTypeCandidate(typeof(CrucibleNoIngredientQuestRequirementConfig))]
	[DuckTypeCandidate(typeof(CrucibleStrongPotionQuestRequirementConfig))]
	[DuckTypeCandidate(typeof(CrucibleWeakPotionQuestRequirementConfig))]
	public abstract class CrucibleQuestRequirementConfig : CruciblePackageConfigNode
	{
		public abstract CrucibleQuestRequirement GetSubject();

		public virtual void ApplyConfiguration(CrucibleQuestRequirement reqSubject)
		{
		}
	}
	public class CrucibleStrongPotionQuestRequirementConfig : CrucibleQuestRequirementConfig
	{
		public bool OnlyStrongPotions { get; set; } = true;


		public override CrucibleQuestRequirement GetSubject()
		{
			return CrucibleQuestRequirement.GetByName("OnlyStrongPotions");
		}
	}
	public class CrucibleWeakPotionQuestRequirementConfig : CrucibleQuestRequirementConfig
	{
		public bool OnlyWeakPotions { get; set; } = true;


		public override CrucibleQuestRequirement GetSubject()
		{
			return CrucibleQuestRequirement.GetByName("OnlyWeakPotions");
		}
	}
	[DuckTypeCandidate(typeof(CrucibleInventoryItemSoldByNpcTemplateConfig))]
	[DuckTypeCandidate(typeof(CrucibleInventoryItemSoldByNpcTagConfig))]
	[DuckTypeCandidate(typeof(CrucibleInventoryItemSoldByNpcStaticConfig))]
	public abstract class CrucibleInventoryItemSoldByConfig : CruciblePackageConfigNode
	{
		public float ChanceToAppear { get; set; } = 1f;


		public int MinCount { get; set; } = 1;


		public int MaxCount { get; set; } = 1;


		public int? ClosenessRequirement { get; set; }

		public virtual void OnApplyConfiguration(CrucibleInventoryItem inventoryItem)
		{
			foreach (CrucibleTraderNpcTemplate trader in GetTraders())
			{
				trader.AddTradeItem(inventoryItem, ChanceToAppear, MinCount, MaxCount, ClosenessRequirement ?? inventoryItem.DefaultClosenessRequirement);
			}
		}

		protected abstract IEnumerable<CrucibleTraderNpcTemplate> GetTraders();
	}
	public class CrucibleInventoryItemSoldByNpcStaticConfig : CrucibleInventoryItemSoldByConfig
	{
		public string InventoryItemName { get; set; }

		public void OnApplyConfiguration(CrucibleTraderNpcTemplate subject)
		{
			CrucibleInventoryItem byName = CrucibleInventoryItem.GetByName(InventoryItemName);
			subject.AddTradeItem(byName, base.ChanceToAppear, base.MinCount, base.MaxCount, base.ClosenessRequirement.GetValueOrDefault());
		}

		protected override IEnumerable<CrucibleTraderNpcTemplate> GetTraders()
		{
			throw new NotImplementedException();
		}
	}
	public class CrucibleInventoryItemSoldByNpcTagConfig : CrucibleInventoryItemSoldByConfig
	{
		public OneOrMany<string> NpcTag { get; set; }

		protected override IEnumerable<CrucibleTraderNpcTemplate> GetTraders()
		{
			if (NpcTag == null)
			{
				return (IEnumerable<CrucibleTraderNpcTemplate>)(object)new CrucibleTraderNpcTemplate[0];
			}
			return (from template in CrucibleNpcTemplate.GetAllNpcTemplates()
				where template.IsTrader
				where ((IEnumerable<string>)NpcTag).All((string x) => template.HasTag(x))
				select template.AsTrader()).Distinct();
		}
	}
	public class CrucibleInventoryItemSoldByNpcTemplateConfig : CrucibleInventoryItemSoldByConfig
	{
		public OneOrMany<string> NpcTemplateName { get; set; }

		protected override IEnumerable<CrucibleTraderNpcTemplate> GetTraders()
		{
			foreach (string item in NpcTemplateName)
			{
				CrucibleNpcTemplate npcTemplateById = CrucibleNpcTemplate.GetNpcTemplateById(item);
				if (npcTemplateById == null)
				{
					throw new Exception("NPC template " + item + " not found.");
				}
				if (!npcTemplateById.IsTrader)
				{
					throw new Exception("NPC template " + item + " is not a trader.");
				}
				yield return npcTemplateById.AsTrader();
			}
		}
	}
	[CruciblePackageConfigExtension(typeof(ICrucibleInventoryItemProvider))]
	public class CrucibleInventoryItemTraderExtensionConfig : CruciblePackageConfigNode, ICruciblePackageConfigExtension<ICrucibleInventoryItemProvider>
	{
		public OneOrMany<CrucibleInventoryItemSoldByConfig> SoldBy { get; set; }

		public void OnApplyConfiguration(ICrucibleInventoryItemProvider subject)
		{
			if (SoldBy == null)
			{
				return;
			}
			CrucibleInventoryItem inventoryItem = subject.GetInventoryItem();
			foreach (CrucibleInventoryItemSoldByConfig item in SoldBy)
			{
				item.OnApplyConfiguration(inventoryItem);
			}
		}
	}
	public class CrucibleTraderConfig : CrucibleNPCConfig<CrucibleTraderNpcTemplate>
	{
		public int MinimumKarmaForSpawn { get; set; } = int.MaxValue;


		public int MaximumKarmaForSpawn { get; set; } = int.MaxValue;


		public int UnlockAtChapter { get; set; }

		public int Gold { get; set; } = int.MaxValue;


		public OneOrMany<CrucibleInventoryItemSoldByNpcStaticConfig> Items { get; set; }

		public int DayTimeForSpawn { get; set; } = int.MaxValue;


		public override string ToString()
		{
			return ((CruciblePackageConfigNode)this).PackageMod.Namespace + "." + base.ID;
		}

		protected override CrucibleTraderNpcTemplate GetSubject()
		{
			string text = ((CruciblePackageConfigNode)this).PackageMod.Namespace + "." + base.ID;
			return CrucibleTraderNpcTemplate.GetTraderNpcTemplateById(text) ?? CrucibleTraderNpcTemplate.CreateTraderNpcTemplate(text, base.InheritFrom);
		}

		protected override void OnApplyConfiguration(CrucibleTraderNpcTemplate subject)
		{
			base.OnApplyConfiguration(subject);
			if (UnlockAtChapter > 0)
			{
				subject.UnlockAtChapter = UnlockAtChapter;
			}
			if (MinimumKarmaForSpawn != int.MaxValue && MaximumKarmaForSpawn != int.MaxValue)
			{
				subject.KarmaForSpawn = (MinimumKarmaForSpawn, MaximumKarmaForSpawn);
			}
			if (DayTimeForSpawn != int.MaxValue)
			{
				((CrucibleNpcTemplate)subject).DayTimeForSpawn = DayTimeForSpawn;
			}
			if (Items == null)
			{
				return;
			}
			subject.ClearTradeItems();
			foreach (CrucibleInventoryItemSoldByNpcStaticConfig item in Items)
			{
				item.OnApplyConfiguration(subject);
			}
		}
	}
}

plugins/Crucible.PotionBottles.dll

Decompiled 11 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using Microsoft.CodeAnalysis;
using RoboPhredDev.PotionCraft.Crucible.CruciblePackages;
using RoboPhredDev.PotionCraft.Crucible.GameAPI;
using RoboPhredDev.PotionCraft.Crucible.SVG;
using UnityEngine;
using YamlDotNet.Serialization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("Crucible.PotionBottles")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Crucible.PotionBottles")]
[assembly: AssemblyTitle("Crucible.PotionBottles")]
[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;
		}
	}
}
namespace RoboPhredDev.PotionCraft.Crucible.PotionBottles
{
	public class CruciblePotionBottleConfig : CruciblePackageConfigSubjectNode<CruciblePotionBottle>
	{
		[YamlMember(Alias = "id")]
		public string ID { get; set; }

		public Sprite BottleIcon { get; set; }

		public Sprite BottleForeground { get; set; }

		public Sprite BottleShadows { get; set; }

		public Sprite BottleCork { get; set; }

		public Sprite BottleScratches { get; set; }

		public Sprite BottleMask { get; set; }

		public SvgPath BottleCollision { get; set; }

		public Vector2? LabelOffset { get; set; }

		public Sprite LiquidMain { get; set; }

		public Sprite Liquid2Of2 { get; set; }

		public Sprite Liquid1Of3 { get; set; }

		public Sprite Liquid3Of3 { get; set; }

		public Sprite Liquid1Of4 { get; set; }

		public Sprite Liquid3Of4 { get; set; }

		public Sprite Liquid4Of4 { get; set; }

		public Sprite Liquid1Of5 { get; set; }

		public Sprite Liquid2Of5 { get; set; }

		public Sprite Liquid4Of5 { get; set; }

		public Sprite Liquid5Of5 { get; set; }

		protected override CruciblePotionBottle GetSubject()
		{
			string text = ((CruciblePackageConfigNode)this).PackageMod.Namespace + "." + ID;
			return CruciblePotionBottle.GetPotionBottleById(text) ?? CruciblePotionBottle.CreatePotionBottle(text);
		}

		protected override void OnApplyConfiguration(CruciblePotionBottle subject)
		{
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)BottleIcon != (Object)null)
			{
				subject.BottleIcon = BottleIcon;
			}
			if ((Object)(object)BottleForeground != (Object)null)
			{
				subject.BottleForeground = BottleForeground;
			}
			if ((Object)(object)BottleShadows != (Object)null)
			{
				subject.BottleShadows = BottleShadows;
			}
			if ((Object)(object)BottleCork != (Object)null)
			{
				subject.BottleCork = BottleCork;
			}
			if ((Object)(object)BottleScratches != (Object)null)
			{
				subject.BottleScratches = BottleScratches;
			}
			if ((Object)(object)BottleMask != (Object)null)
			{
				subject.BottleMask = BottleMask;
			}
			if (LabelOffset.HasValue)
			{
				subject.LabelOffset = LabelOffset.Value;
			}
			if (BottleCollision != null)
			{
				subject.SetColliderPolygon((IEnumerable<Vector2>)BottleCollision.ToPoints());
			}
			if ((Object)(object)LiquidMain != (Object)null)
			{
				subject.LiquidMain = LiquidMain;
			}
			if ((Object)(object)Liquid2Of2 != (Object)null)
			{
				subject.Liquid2Of2 = Liquid2Of2;
			}
			if ((Object)(object)Liquid1Of3 != (Object)null)
			{
				subject.Liquid1Of3 = Liquid1Of3;
			}
			if ((Object)(object)Liquid3Of3 != (Object)null)
			{
				subject.Liquid3Of3 = Liquid3Of3;
			}
			if ((Object)(object)Liquid1Of4 != (Object)null)
			{
				subject.Liquid1Of4 = Liquid1Of4;
			}
			if ((Object)(object)Liquid3Of4 != (Object)null)
			{
				subject.Liquid3Of4 = Liquid3Of4;
			}
			if ((Object)(object)Liquid4Of4 != (Object)null)
			{
				subject.Liquid4Of4 = Liquid4Of4;
			}
			if ((Object)(object)Liquid1Of5 != (Object)null)
			{
				subject.Liquid1Of5 = Liquid1Of5;
			}
			if ((Object)(object)Liquid2Of5 != (Object)null)
			{
				subject.Liquid2Of5 = Liquid2Of5;
			}
			if ((Object)(object)Liquid4Of5 != (Object)null)
			{
				subject.Liquid4Of5 = Liquid4Of5;
			}
			if ((Object)(object)Liquid5Of5 != (Object)null)
			{
				subject.Liquid5Of5 = Liquid5Of5;
			}
		}
	}
	public class CruciblePotionBottleIconConfig : CruciblePackageConfigSubjectNode<CrucibleIcon>
	{
		[YamlMember(Alias = "id")]
		public string ID { get; set; }

		public Texture2D Icon { get; set; }

		protected override CrucibleIcon GetSubject()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			string text = ((CruciblePackageConfigNode)this).PackageMod.Namespace + "." + ID;
			return CrucibleIcon.GetIconByID(text) ?? CrucibleIcon.FromTexture(text, TextureUtilities.CreateBlankTexture(10, 10, Color.clear));
		}

		protected override void OnApplyConfiguration(CrucibleIcon subject)
		{
			if ((Object)(object)Icon != (Object)null)
			{
				subject.IconTexture = Icon;
			}
		}
	}
	[CruciblePackageConfigRoot]
	public class CruciblePotionBottlesConfigRoot : CruciblePackageConfigRoot
	{
		public List<CruciblePotionBottleConfig> PotionBottles { get; set; } = new List<CruciblePotionBottleConfig>();


		public List<CruciblePotionBottleIconConfig> PotionBottleIcons { get; set; } = new List<CruciblePotionBottleIconConfig>();


		public List<CruciblePotionBottleStickerConfig> PotionBottleStickers { get; set; } = new List<CruciblePotionBottleStickerConfig>();


		public override void ApplyConfiguration()
		{
			PotionBottles.ForEach(delegate(CruciblePotionBottleConfig x)
			{
				((CruciblePackageConfigSubjectNode<CruciblePotionBottle>)x).ApplyConfiguration();
			});
			PotionBottleIcons.ForEach(delegate(CruciblePotionBottleIconConfig x)
			{
				((CruciblePackageConfigSubjectNode<CrucibleIcon>)x).ApplyConfiguration();
			});
			PotionBottleStickers.ForEach(delegate(CruciblePotionBottleStickerConfig x)
			{
				((CruciblePackageConfigSubjectNode<CruciblePotionSticker>)x).ApplyConfiguration();
			});
		}
	}
	[BepInPlugin("net.RoboPhredDev.PotionCraft.Crucible.PotionBottles", "Potion Bottle support for Crucible Modding Framework", "1.1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class CruciblePotionBottlesPlugin : BaseUnityPlugin
	{
	}
	public class CruciblePotionBottleStickerConfig : CruciblePackageConfigSubjectNode<CruciblePotionSticker>
	{
		[YamlMember(Alias = "id")]
		public string ID { get; set; }

		public Sprite Foreground { get; set; }

		public Sprite Background { get; set; }

		public Sprite MenuIcon { get; set; }

		protected override CruciblePotionSticker GetSubject()
		{
			string text = ((CruciblePackageConfigNode)this).PackageMod.Namespace + "." + ID;
			return CruciblePotionSticker.CreatePotionSticker(text) ?? CruciblePotionSticker.CreatePotionSticker(text);
		}

		protected override void OnApplyConfiguration(CruciblePotionSticker subject)
		{
			if ((Object)(object)Foreground != (Object)null)
			{
				subject.Foreground = Foreground;
			}
			if ((Object)(object)Background != (Object)null)
			{
				subject.Background = Background;
			}
			if ((Object)(object)MenuIcon != (Object)null)
			{
				subject.MenuIcon = MenuIcon;
			}
		}
	}
}

plugins/YamlDotNet.dll

Decompiled 11 months ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.CodeAnalysis;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Core.Tokens;
using YamlDotNet.Helpers;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.Converters;
using YamlDotNet.Serialization.EventEmitters;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization.NodeDeserializers;
using YamlDotNet.Serialization.NodeTypeResolvers;
using YamlDotNet.Serialization.ObjectFactories;
using YamlDotNet.Serialization.ObjectGraphTraversalStrategies;
using YamlDotNet.Serialization.ObjectGraphVisitors;
using YamlDotNet.Serialization.TypeInspectors;
using YamlDotNet.Serialization.TypeResolvers;
using YamlDotNet.Serialization.Utilities;
using YamlDotNet.Serialization.ValueDeserializers;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: ComVisible(false)]
[assembly: AssemblyFileVersion("8.1.2.0")]
[assembly: AssemblyInformationalVersion("8.1.2")]
[assembly: AssemblyTitle("YamlDotNet")]
[assembly: AssemblyDescription("The YamlDotNet library.")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("YamlDotNet")]
[assembly: AssemblyCopyright("Copyright (c) Antoine Aubry and contributors 2008 - 2019")]
[assembly: AssemblyTrademark("")]
[assembly: CLSCompliant(true)]
[assembly: InternalsVisibleTo("YamlDotNet.Test, PublicKey=002400000480000094000000060200000024000052534131000400000100010065e52a453dde5c5b4be5bbe2205755727fce80244b79b894faf8793d80f7db9a96d360b51c220782db32aacee4cb5b8a91bee33aeec700e1f21895c4baadef501eeeac609220d1651603b378173811ee5bb6a002df973d38821bd2fef820c00c174a69faec326a1983b570f07ec66147026b9c8753465de3a8d0c44b613b02af")]
[assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
[assembly: AssemblyVersion("8.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	internal sealed class AllowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	internal sealed class DisallowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	internal sealed class DoesNotReturnAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal sealed class DoesNotReturnIfAttribute : Attribute
	{
		public bool ParameterValue { get; }

		public DoesNotReturnIfAttribute(bool parameterValue)
		{
			ParameterValue = parameterValue;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class MaybeNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal sealed class MaybeNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public MaybeNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class NotNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]
	internal sealed class NotNullIfNotNullAttribute : Attribute
	{
		public string ParameterName { get; }

		public NotNullIfNotNullAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal sealed class NotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public NotNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
}
namespace YamlDotNet
{
	internal static class StandardRegexOptions
	{
		public const RegexOptions Compiled = RegexOptions.Compiled;
	}
	internal static class ReflectionExtensions
	{
		private static readonly FieldInfo? remoteStackTraceField = typeof(Exception).GetField("_remoteStackTraceString", BindingFlags.Instance | BindingFlags.NonPublic);

		public static Type? BaseType(this Type type)
		{
			return type.BaseType;
		}

		public static bool IsValueType(this Type type)
		{
			return type.IsValueType;
		}

		public static bool IsGenericType(this Type type)
		{
			return type.IsGenericType;
		}

		public static bool IsInterface(this Type type)
		{
			return type.IsInterface;
		}

		public static bool IsEnum(this Type type)
		{
			return type.IsEnum;
		}

		public static bool IsDbNull(this object value)
		{
			return value is DBNull;
		}

		public static bool HasDefaultConstructor(this Type type)
		{
			if (!type.IsValueType)
			{
				return type.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null) != null;
			}
			return true;
		}

		public static TypeCode GetTypeCode(this Type type)
		{
			return Type.GetTypeCode(type);
		}

		public static PropertyInfo? GetPublicProperty(this Type type, string name)
		{
			return type.GetProperty(name);
		}

		public static IEnumerable<PropertyInfo> GetPublicProperties(this Type type)
		{
			BindingFlags instancePublic = BindingFlags.Instance | BindingFlags.Public;
			if (!type.IsInterface)
			{
				return type.GetProperties(instancePublic);
			}
			return new Type[1] { type }.Concat(type.GetInterfaces()).SelectMany((Type i) => i.GetProperties(instancePublic));
		}

		public static IEnumerable<FieldInfo> GetPublicFields(this Type type)
		{
			return type.GetFields(BindingFlags.Instance | BindingFlags.Public);
		}

		public static IEnumerable<MethodInfo> GetPublicStaticMethods(this Type type)
		{
			return type.GetMethods(BindingFlags.Static | BindingFlags.Public);
		}

		public static MethodInfo? GetPublicStaticMethod(this Type type, string name, params Type[] parameterTypes)
		{
			return type.GetMethod(name, BindingFlags.Static | BindingFlags.Public, null, parameterTypes, null);
		}

		public static MethodInfo? GetPublicInstanceMethod(this Type type, string name)
		{
			return type.GetMethod(name, BindingFlags.Instance | BindingFlags.Public);
		}

		public static Exception Unwrap(this TargetInvocationException ex)
		{
			Exception innerException = ex.InnerException;
			if (innerException == null)
			{
				return ex;
			}
			if (remoteStackTraceField != null)
			{
				remoteStackTraceField.SetValue(innerException, innerException.StackTrace + "\r\n");
			}
			return innerException;
		}

		public static bool IsInstanceOf(this Type type, object o)
		{
			return type.IsInstanceOfType(o);
		}

		public static Attribute[] GetAllCustomAttributes<TAttribute>(this PropertyInfo property)
		{
			return Attribute.GetCustomAttributes(property, typeof(TAttribute));
		}
	}
	internal sealed class CultureInfoAdapter : CultureInfo
	{
		private readonly IFormatProvider provider;

		public CultureInfoAdapter(CultureInfo baseCulture, IFormatProvider provider)
			: base(baseCulture.LCID)
		{
			this.provider = provider;
		}

		public override object? GetFormat(Type? formatType)
		{
			return provider.GetFormat(formatType);
		}
	}
	internal static class PropertyInfoExtensions
	{
		public static object? ReadValue(this PropertyInfo property, object target)
		{
			return property.GetValue(target, null);
		}
	}
}
namespace YamlDotNet.Serialization
{
	public abstract class BuilderSkeleton<TBuilder> where TBuilder : BuilderSkeleton<TBuilder>
	{
		internal INamingConvention namingConvention = NullNamingConvention.Instance;

		internal ITypeResolver typeResolver;

		internal readonly YamlAttributeOverrides overrides;

		internal readonly LazyComponentRegistrationList<Nothing, IYamlTypeConverter> typeConverterFactories;

		internal readonly LazyComponentRegistrationList<ITypeInspector, ITypeInspector> typeInspectorFactories;

		private bool ignoreFields;

		protected abstract TBuilder Self { get; }

		internal BuilderSkeleton(ITypeResolver typeResolver)
		{
			overrides = new YamlAttributeOverrides();
			typeConverterFactories = new LazyComponentRegistrationList<Nothing, IYamlTypeConverter>
			{
				{
					typeof(YamlDotNet.Serialization.Converters.GuidConverter),
					(Nothing _) => new YamlDotNet.Serialization.Converters.GuidConverter(jsonCompatible: false)
				},
				{
					typeof(SystemTypeConverter),
					(Nothing _) => new SystemTypeConverter()
				}
			};
			typeInspectorFactories = new LazyComponentRegistrationList<ITypeInspector, ITypeInspector>();
			this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver");
		}

		internal ITypeInspector BuildTypeInspector()
		{
			ITypeInspector typeInspector = new ReadablePropertiesTypeInspector(typeResolver);
			if (!ignoreFields)
			{
				typeInspector = new CompositeTypeInspector(new ReadableFieldsTypeInspector(typeResolver), typeInspector);
			}
			return typeInspectorFactories.BuildComponentChain(typeInspector);
		}

		public TBuilder IgnoreFields()
		{
			ignoreFields = true;
			return Self;
		}

		public TBuilder WithNamingConvention(INamingConvention namingConvention)
		{
			this.namingConvention = namingConvention ?? throw new ArgumentNullException("namingConvention");
			return Self;
		}

		public TBuilder WithTypeResolver(ITypeResolver typeResolver)
		{
			this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver");
			return Self;
		}

		public abstract TBuilder WithTagMapping(string tag, Type type);

		public TBuilder WithAttributeOverride<TClass>(Expression<Func<TClass, object>> propertyAccessor, Attribute attribute)
		{
			overrides.Add(propertyAccessor, attribute);
			return Self;
		}

		public TBuilder WithAttributeOverride(Type type, string member, Attribute attribute)
		{
			overrides.Add(type, member, attribute);
			return Self;
		}

		public TBuilder WithTypeConverter(IYamlTypeConverter typeConverter)
		{
			return WithTypeConverter(typeConverter, delegate(IRegistrationLocationSelectionSyntax<IYamlTypeConverter> w)
			{
				w.OnTop();
			});
		}

		public TBuilder WithTypeConverter(IYamlTypeConverter typeConverter, Action<IRegistrationLocationSelectionSyntax<IYamlTypeConverter>> where)
		{
			IYamlTypeConverter typeConverter2 = typeConverter;
			if (typeConverter2 == null)
			{
				throw new ArgumentNullException("typeConverter");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(typeConverterFactories.CreateRegistrationLocationSelector(typeConverter2.GetType(), (Nothing _) => typeConverter2));
			return Self;
		}

		public TBuilder WithTypeConverter<TYamlTypeConverter>(WrapperFactory<IYamlTypeConverter, IYamlTypeConverter> typeConverterFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IYamlTypeConverter>> where) where TYamlTypeConverter : IYamlTypeConverter
		{
			WrapperFactory<IYamlTypeConverter, IYamlTypeConverter> typeConverterFactory2 = typeConverterFactory;
			if (typeConverterFactory2 == null)
			{
				throw new ArgumentNullException("typeConverterFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(typeConverterFactories.CreateTrackingRegistrationLocationSelector(typeof(TYamlTypeConverter), (IYamlTypeConverter wrapped, Nothing _) => typeConverterFactory2(wrapped)));
			return Self;
		}

		public TBuilder WithoutTypeConverter<TYamlTypeConverter>() where TYamlTypeConverter : IYamlTypeConverter
		{
			return WithoutTypeConverter(typeof(TYamlTypeConverter));
		}

		public TBuilder WithoutTypeConverter(Type converterType)
		{
			if (converterType == null)
			{
				throw new ArgumentNullException("converterType");
			}
			typeConverterFactories.Remove(converterType);
			return Self;
		}

		public TBuilder WithTypeInspector<TTypeInspector>(Func<ITypeInspector, TTypeInspector> typeInspectorFactory) where TTypeInspector : ITypeInspector
		{
			return WithTypeInspector(typeInspectorFactory, delegate(IRegistrationLocationSelectionSyntax<ITypeInspector> w)
			{
				w.OnTop();
			});
		}

		public TBuilder WithTypeInspector<TTypeInspector>(Func<ITypeInspector, TTypeInspector> typeInspectorFactory, Action<IRegistrationLocationSelectionSyntax<ITypeInspector>> where) where TTypeInspector : ITypeInspector
		{
			Func<ITypeInspector, TTypeInspector> typeInspectorFactory2 = typeInspectorFactory;
			if (typeInspectorFactory2 == null)
			{
				throw new ArgumentNullException("typeInspectorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(typeInspectorFactories.CreateRegistrationLocationSelector(typeof(TTypeInspector), (ITypeInspector inner) => typeInspectorFactory2(inner)));
			return Self;
		}

		public TBuilder WithTypeInspector<TTypeInspector>(WrapperFactory<ITypeInspector, ITypeInspector, TTypeInspector> typeInspectorFactory, Action<ITrackingRegistrationLocationSelectionSyntax<ITypeInspector>> where) where TTypeInspector : ITypeInspector
		{
			WrapperFactory<ITypeInspector, ITypeInspector, TTypeInspector> typeInspectorFactory2 = typeInspectorFactory;
			if (typeInspectorFactory2 == null)
			{
				throw new ArgumentNullException("typeInspectorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(typeInspectorFactories.CreateTrackingRegistrationLocationSelector(typeof(TTypeInspector), (ITypeInspector wrapped, ITypeInspector inner) => typeInspectorFactory2(wrapped, inner)));
			return Self;
		}

		public TBuilder WithoutTypeInspector<TTypeInspector>() where TTypeInspector : ITypeInspector
		{
			return WithoutTypeInspector(typeof(ITypeInspector));
		}

		public TBuilder WithoutTypeInspector(Type inspectorType)
		{
			if (inspectorType == null)
			{
				throw new ArgumentNullException("inspectorType");
			}
			typeInspectorFactories.Remove(inspectorType);
			return Self;
		}

		protected IEnumerable<IYamlTypeConverter> BuildTypeConverters()
		{
			return typeConverterFactories.BuildComponentList();
		}
	}
	public delegate TComponent WrapperFactory<TComponentBase, TComponent>(TComponentBase wrapped) where TComponent : TComponentBase;
	public delegate TComponent WrapperFactory<TArgument, TComponentBase, TComponent>(TComponentBase wrapped, TArgument argument) where TComponent : TComponentBase;
	public enum DefaultValuesHandling
	{
		Preserve,
		OmitNull,
		OmitDefaults
	}
	public sealed class Deserializer : IDeserializer
	{
		private readonly IValueDeserializer valueDeserializer;

		public Deserializer()
			: this(new DeserializerBuilder().BuildValueDeserializer())
		{
		}

		private Deserializer(IValueDeserializer valueDeserializer)
		{
			this.valueDeserializer = valueDeserializer ?? throw new ArgumentNullException("valueDeserializer");
		}

		public static Deserializer FromValueDeserializer(IValueDeserializer valueDeserializer)
		{
			return new Deserializer(valueDeserializer);
		}

		public T Deserialize<T>(string input)
		{
			using StringReader input2 = new StringReader(input);
			return Deserialize<T>(input2);
		}

		public T Deserialize<T>(TextReader input)
		{
			return Deserialize<T>(new Parser(input));
		}

		public object? Deserialize(TextReader input)
		{
			return Deserialize(input, typeof(object));
		}

		public object? Deserialize(string input, Type type)
		{
			using StringReader input2 = new StringReader(input);
			return Deserialize(input2, type);
		}

		public object? Deserialize(TextReader input, Type type)
		{
			return Deserialize(new Parser(input), type);
		}

		public T Deserialize<T>(IParser parser)
		{
			return (T)Deserialize(parser, typeof(T));
		}

		public object? Deserialize(IParser parser)
		{
			return Deserialize(parser, typeof(object));
		}

		public object? Deserialize(IParser parser, Type type)
		{
			if (parser == null)
			{
				throw new ArgumentNullException("parser");
			}
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			YamlDotNet.Core.Events.StreamStart @event;
			bool flag = parser.TryConsume<YamlDotNet.Core.Events.StreamStart>(out @event);
			YamlDotNet.Core.Events.DocumentStart event2;
			bool flag2 = parser.TryConsume<YamlDotNet.Core.Events.DocumentStart>(out event2);
			object result = null;
			if (!parser.Accept<YamlDotNet.Core.Events.DocumentEnd>(out var _) && !parser.Accept<YamlDotNet.Core.Events.StreamEnd>(out var _))
			{
				using SerializerState serializerState = new SerializerState();
				result = valueDeserializer.DeserializeValue(parser, type, serializerState, valueDeserializer);
				serializerState.OnDeserialization();
			}
			if (flag2)
			{
				parser.Consume<YamlDotNet.Core.Events.DocumentEnd>();
			}
			if (flag)
			{
				parser.Consume<YamlDotNet.Core.Events.StreamEnd>();
			}
			return result;
		}
	}
	public sealed class DeserializerBuilder : BuilderSkeleton<DeserializerBuilder>
	{
		private IObjectFactory objectFactory = new DefaultObjectFactory();

		private readonly LazyComponentRegistrationList<Nothing, INodeDeserializer> nodeDeserializerFactories;

		private readonly LazyComponentRegistrationList<Nothing, INodeTypeResolver> nodeTypeResolverFactories;

		private readonly Dictionary<string, Type> tagMappings;

		private bool ignoreUnmatched;

		protected override DeserializerBuilder Self => this;

		public DeserializerBuilder()
			: base((ITypeResolver)new StaticTypeResolver())
		{
			tagMappings = new Dictionary<string, Type>
			{
				{
					"tag:yaml.org,2002:map",
					typeof(Dictionary<object, object>)
				},
				{
					"tag:yaml.org,2002:bool",
					typeof(bool)
				},
				{
					"tag:yaml.org,2002:float",
					typeof(double)
				},
				{
					"tag:yaml.org,2002:int",
					typeof(int)
				},
				{
					"tag:yaml.org,2002:str",
					typeof(string)
				},
				{
					"tag:yaml.org,2002:timestamp",
					typeof(DateTime)
				}
			};
			typeInspectorFactories.Add(typeof(CachedTypeInspector), (ITypeInspector inner) => new CachedTypeInspector(inner));
			typeInspectorFactories.Add(typeof(NamingConventionTypeInspector), (ITypeInspector inner) => (!(namingConvention is NullNamingConvention)) ? new NamingConventionTypeInspector(inner, namingConvention) : inner);
			typeInspectorFactories.Add(typeof(YamlAttributesTypeInspector), (ITypeInspector inner) => new YamlAttributesTypeInspector(inner));
			typeInspectorFactories.Add(typeof(YamlAttributeOverridesInspector), (ITypeInspector inner) => (overrides == null) ? inner : new YamlAttributeOverridesInspector(inner, overrides.Clone()));
			typeInspectorFactories.Add(typeof(ReadableAndWritablePropertiesTypeInspector), (ITypeInspector inner) => new ReadableAndWritablePropertiesTypeInspector(inner));
			nodeDeserializerFactories = new LazyComponentRegistrationList<Nothing, INodeDeserializer>
			{
				{
					typeof(YamlConvertibleNodeDeserializer),
					(Nothing _) => new YamlConvertibleNodeDeserializer(objectFactory)
				},
				{
					typeof(YamlSerializableNodeDeserializer),
					(Nothing _) => new YamlSerializableNodeDeserializer(objectFactory)
				},
				{
					typeof(TypeConverterNodeDeserializer),
					(Nothing _) => new TypeConverterNodeDeserializer(BuildTypeConverters())
				},
				{
					typeof(NullNodeDeserializer),
					(Nothing _) => new NullNodeDeserializer()
				},
				{
					typeof(ScalarNodeDeserializer),
					(Nothing _) => new ScalarNodeDeserializer()
				},
				{
					typeof(ArrayNodeDeserializer),
					(Nothing _) => new ArrayNodeDeserializer()
				},
				{
					typeof(DictionaryNodeDeserializer),
					(Nothing _) => new DictionaryNodeDeserializer(objectFactory)
				},
				{
					typeof(CollectionNodeDeserializer),
					(Nothing _) => new CollectionNodeDeserializer(objectFactory)
				},
				{
					typeof(EnumerableNodeDeserializer),
					(Nothing _) => new EnumerableNodeDeserializer()
				},
				{
					typeof(ObjectNodeDeserializer),
					(Nothing _) => new ObjectNodeDeserializer(objectFactory, BuildTypeInspector(), ignoreUnmatched)
				}
			};
			nodeTypeResolverFactories = new LazyComponentRegistrationList<Nothing, INodeTypeResolver>
			{
				{
					typeof(YamlConvertibleTypeResolver),
					(Nothing _) => new YamlConvertibleTypeResolver()
				},
				{
					typeof(YamlSerializableTypeResolver),
					(Nothing _) => new YamlSerializableTypeResolver()
				},
				{
					typeof(TagNodeTypeResolver),
					(Nothing _) => new TagNodeTypeResolver(tagMappings)
				},
				{
					typeof(PreventUnknownTagsNodeTypeResolver),
					(Nothing _) => new PreventUnknownTagsNodeTypeResolver()
				},
				{
					typeof(DefaultContainersNodeTypeResolver),
					(Nothing _) => new DefaultContainersNodeTypeResolver()
				}
			};
		}

		public DeserializerBuilder WithObjectFactory(IObjectFactory objectFactory)
		{
			this.objectFactory = objectFactory ?? throw new ArgumentNullException("objectFactory");
			return this;
		}

		public DeserializerBuilder WithObjectFactory(Func<Type, object> objectFactory)
		{
			if (objectFactory == null)
			{
				throw new ArgumentNullException("objectFactory");
			}
			return WithObjectFactory(new LambdaObjectFactory(objectFactory));
		}

		public DeserializerBuilder WithNodeDeserializer(INodeDeserializer nodeDeserializer)
		{
			return WithNodeDeserializer(nodeDeserializer, delegate(IRegistrationLocationSelectionSyntax<INodeDeserializer> w)
			{
				w.OnTop();
			});
		}

		public DeserializerBuilder WithNodeDeserializer(INodeDeserializer nodeDeserializer, Action<IRegistrationLocationSelectionSyntax<INodeDeserializer>> where)
		{
			INodeDeserializer nodeDeserializer2 = nodeDeserializer;
			if (nodeDeserializer2 == null)
			{
				throw new ArgumentNullException("nodeDeserializer");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(nodeDeserializerFactories.CreateRegistrationLocationSelector(nodeDeserializer2.GetType(), (Nothing _) => nodeDeserializer2));
			return this;
		}

		public DeserializerBuilder WithNodeDeserializer<TNodeDeserializer>(WrapperFactory<INodeDeserializer, TNodeDeserializer> nodeDeserializerFactory, Action<ITrackingRegistrationLocationSelectionSyntax<INodeDeserializer>> where) where TNodeDeserializer : INodeDeserializer
		{
			WrapperFactory<INodeDeserializer, TNodeDeserializer> nodeDeserializerFactory2 = nodeDeserializerFactory;
			if (nodeDeserializerFactory2 == null)
			{
				throw new ArgumentNullException("nodeDeserializerFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(nodeDeserializerFactories.CreateTrackingRegistrationLocationSelector(typeof(TNodeDeserializer), (INodeDeserializer wrapped, Nothing _) => nodeDeserializerFactory2(wrapped)));
			return this;
		}

		public DeserializerBuilder WithoutNodeDeserializer<TNodeDeserializer>() where TNodeDeserializer : INodeDeserializer
		{
			return WithoutNodeDeserializer(typeof(TNodeDeserializer));
		}

		public DeserializerBuilder WithoutNodeDeserializer(Type nodeDeserializerType)
		{
			if (nodeDeserializerType == null)
			{
				throw new ArgumentNullException("nodeDeserializerType");
			}
			nodeDeserializerFactories.Remove(nodeDeserializerType);
			return this;
		}

		public DeserializerBuilder WithNodeTypeResolver(INodeTypeResolver nodeTypeResolver)
		{
			return WithNodeTypeResolver(nodeTypeResolver, delegate(IRegistrationLocationSelectionSyntax<INodeTypeResolver> w)
			{
				w.OnTop();
			});
		}

		public DeserializerBuilder WithNodeTypeResolver(INodeTypeResolver nodeTypeResolver, Action<IRegistrationLocationSelectionSyntax<INodeTypeResolver>> where)
		{
			INodeTypeResolver nodeTypeResolver2 = nodeTypeResolver;
			if (nodeTypeResolver2 == null)
			{
				throw new ArgumentNullException("nodeTypeResolver");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(nodeTypeResolverFactories.CreateRegistrationLocationSelector(nodeTypeResolver2.GetType(), (Nothing _) => nodeTypeResolver2));
			return this;
		}

		public DeserializerBuilder WithNodeTypeResolver<TNodeTypeResolver>(WrapperFactory<INodeTypeResolver, TNodeTypeResolver> nodeTypeResolverFactory, Action<ITrackingRegistrationLocationSelectionSyntax<INodeTypeResolver>> where) where TNodeTypeResolver : INodeTypeResolver
		{
			WrapperFactory<INodeTypeResolver, TNodeTypeResolver> nodeTypeResolverFactory2 = nodeTypeResolverFactory;
			if (nodeTypeResolverFactory2 == null)
			{
				throw new ArgumentNullException("nodeTypeResolverFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(nodeTypeResolverFactories.CreateTrackingRegistrationLocationSelector(typeof(TNodeTypeResolver), (INodeTypeResolver wrapped, Nothing _) => nodeTypeResolverFactory2(wrapped)));
			return this;
		}

		public DeserializerBuilder WithoutNodeTypeResolver<TNodeTypeResolver>() where TNodeTypeResolver : INodeTypeResolver
		{
			return WithoutNodeTypeResolver(typeof(TNodeTypeResolver));
		}

		public DeserializerBuilder WithoutNodeTypeResolver(Type nodeTypeResolverType)
		{
			if (nodeTypeResolverType == null)
			{
				throw new ArgumentNullException("nodeTypeResolverType");
			}
			nodeTypeResolverFactories.Remove(nodeTypeResolverType);
			return this;
		}

		public override DeserializerBuilder WithTagMapping(string tag, Type type)
		{
			if (tag == null)
			{
				throw new ArgumentNullException("tag");
			}
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (tagMappings.TryGetValue(tag, out Type value))
			{
				throw new ArgumentException("Type already has a registered type '" + value.FullName + "' for tag '" + tag + "'", "tag");
			}
			tagMappings.Add(tag, type);
			return this;
		}

		public DeserializerBuilder WithoutTagMapping(string tag)
		{
			if (tag == null)
			{
				throw new ArgumentNullException("tag");
			}
			if (!tagMappings.Remove(tag))
			{
				throw new KeyNotFoundException("Tag '" + tag + "' is not registered");
			}
			return this;
		}

		public DeserializerBuilder IgnoreUnmatchedProperties()
		{
			ignoreUnmatched = true;
			return this;
		}

		public IDeserializer Build()
		{
			return Deserializer.FromValueDeserializer(BuildValueDeserializer());
		}

		public IValueDeserializer BuildValueDeserializer()
		{
			return new AliasValueDeserializer(new NodeValueDeserializer(nodeDeserializerFactories.BuildComponentList(), nodeTypeResolverFactories.BuildComponentList()));
		}
	}
	public sealed class EmissionPhaseObjectGraphVisitorArgs
	{
		private readonly IEnumerable<IObjectGraphVisitor<Nothing>> preProcessingPhaseVisitors;

		public IObjectGraphVisitor<IEmitter> InnerVisitor { get; private set; }

		public IEventEmitter EventEmitter { get; private set; }

		public ObjectSerializer NestedObjectSerializer { get; private set; }

		public IEnumerable<IYamlTypeConverter> TypeConverters { get; private set; }

		public EmissionPhaseObjectGraphVisitorArgs(IObjectGraphVisitor<IEmitter> innerVisitor, IEventEmitter eventEmitter, IEnumerable<IObjectGraphVisitor<Nothing>> preProcessingPhaseVisitors, IEnumerable<IYamlTypeConverter> typeConverters, ObjectSerializer nestedObjectSerializer)
		{
			InnerVisitor = innerVisitor ?? throw new ArgumentNullException("innerVisitor");
			EventEmitter = eventEmitter ?? throw new ArgumentNullException("eventEmitter");
			this.preProcessingPhaseVisitors = preProcessingPhaseVisitors ?? throw new ArgumentNullException("preProcessingPhaseVisitors");
			TypeConverters = typeConverters ?? throw new ArgumentNullException("typeConverters");
			NestedObjectSerializer = nestedObjectSerializer ?? throw new ArgumentNullException("nestedObjectSerializer");
		}

		public T GetPreProcessingPhaseObjectGraphVisitor<T>() where T : IObjectGraphVisitor<Nothing>
		{
			return preProcessingPhaseVisitors.OfType<T>().Single();
		}
	}
	public abstract class EventInfo
	{
		public IObjectDescriptor Source { get; }

		protected EventInfo(IObjectDescriptor source)
		{
			Source = source ?? throw new ArgumentNullException("source");
		}
	}
	public class AliasEventInfo : EventInfo
	{
		public string Alias { get; }

		public AliasEventInfo(IObjectDescriptor source, string alias)
			: base(source)
		{
			Alias = alias ?? throw new ArgumentNullException("alias");
		}
	}
	public class ObjectEventInfo : EventInfo
	{
		public string? Anchor { get; set; }

		public string? Tag { get; set; }

		protected ObjectEventInfo(IObjectDescriptor source)
			: base(source)
		{
		}
	}
	public sealed class ScalarEventInfo : ObjectEventInfo
	{
		public string RenderedValue { get; set; }

		public ScalarStyle Style { get; set; }

		public bool IsPlainImplicit { get; set; }

		public bool IsQuotedImplicit { get; set; }

		public ScalarEventInfo(IObjectDescriptor source)
			: base(source)
		{
			Style = source.ScalarStyle;
			RenderedValue = string.Empty;
		}
	}
	public sealed class MappingStartEventInfo : ObjectEventInfo
	{
		public bool IsImplicit { get; set; }

		public MappingStyle Style { get; set; }

		public MappingStartEventInfo(IObjectDescriptor source)
			: base(source)
		{
		}
	}
	public sealed class MappingEndEventInfo : EventInfo
	{
		public MappingEndEventInfo(IObjectDescriptor source)
			: base(source)
		{
		}
	}
	public sealed class SequenceStartEventInfo : ObjectEventInfo
	{
		public bool IsImplicit { get; set; }

		public SequenceStyle Style { get; set; }

		public SequenceStartEventInfo(IObjectDescriptor source)
			: base(source)
		{
		}
	}
	public sealed class SequenceEndEventInfo : EventInfo
	{
		public SequenceEndEventInfo(IObjectDescriptor source)
			: base(source)
		{
		}
	}
	public interface IAliasProvider
	{
		string? GetAlias(object target);
	}
	public interface IDeserializer
	{
		T Deserialize<T>(string input);

		T Deserialize<T>(TextReader input);

		object? Deserialize(TextReader input);

		object? Deserialize(string input, Type type);

		object? Deserialize(TextReader input, Type type);

		T Deserialize<T>(IParser parser);

		object? Deserialize(IParser parser);

		object? Deserialize(IParser parser, Type type);
	}
	public interface IEventEmitter
	{
		void Emit(AliasEventInfo eventInfo, IEmitter emitter);

		void Emit(ScalarEventInfo eventInfo, IEmitter emitter);

		void Emit(MappingStartEventInfo eventInfo, IEmitter emitter);

		void Emit(MappingEndEventInfo eventInfo, IEmitter emitter);

		void Emit(SequenceStartEventInfo eventInfo, IEmitter emitter);

		void Emit(SequenceEndEventInfo eventInfo, IEmitter emitter);
	}
	public interface INamingConvention
	{
		string Apply(string value);
	}
	public interface INodeDeserializer
	{
		bool Deserialize(IParser reader, Type expectedType, Func<IParser, Type, object?> nestedObjectDeserializer, out object? value);
	}
	public interface INodeTypeResolver
	{
		bool Resolve(NodeEvent? nodeEvent, ref Type currentType);
	}
	public interface IObjectDescriptor
	{
		object? Value { get; }

		Type Type { get; }

		Type StaticType { get; }

		ScalarStyle ScalarStyle { get; }
	}
	public static class ObjectDescriptorExtensions
	{
		public static object NonNullValue(this IObjectDescriptor objectDescriptor)
		{
			return objectDescriptor.Value ?? throw new InvalidOperationException("Attempted to use a IObjectDescriptor of type '" + objectDescriptor.Type.FullName + "' whose Value is null at a point whete it is invalid to do so. This may indicate a bug in YamlDotNet.");
		}
	}
	public interface IObjectFactory
	{
		object Create(Type type);
	}
	public interface IObjectGraphTraversalStrategy
	{
		void Traverse<TContext>(IObjectDescriptor graph, IObjectGraphVisitor<TContext> visitor, TContext context);
	}
	public interface IObjectGraphVisitor<TContext>
	{
		bool Enter(IObjectDescriptor value, TContext context);

		bool EnterMapping(IObjectDescriptor key, IObjectDescriptor value, TContext context);

		bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value, TContext context);

		void VisitScalar(IObjectDescriptor scalar, TContext context);

		void VisitMappingStart(IObjectDescriptor mapping, Type keyType, Type valueType, TContext context);

		void VisitMappingEnd(IObjectDescriptor mapping, TContext context);

		void VisitSequenceStart(IObjectDescriptor sequence, Type elementType, TContext context);

		void VisitSequenceEnd(IObjectDescriptor sequence, TContext context);
	}
	public interface IPropertyDescriptor
	{
		string Name { get; }

		bool CanWrite { get; }

		Type Type { get; }

		Type? TypeOverride { get; set; }

		int Order { get; set; }

		ScalarStyle ScalarStyle { get; set; }

		T GetCustomAttribute<T>() where T : Attribute;

		IObjectDescriptor Read(object target);

		void Write(object target, object? value);
	}
	public interface IRegistrationLocationSelectionSyntax<TBaseRegistrationType>
	{
		void InsteadOf<TRegistrationType>() where TRegistrationType : TBaseRegistrationType;

		void Before<TRegistrationType>() where TRegistrationType : TBaseRegistrationType;

		void After<TRegistrationType>() where TRegistrationType : TBaseRegistrationType;

		void OnTop();

		void OnBottom();
	}
	public interface ITrackingRegistrationLocationSelectionSyntax<TBaseRegistrationType>
	{
		void InsteadOf<TRegistrationType>() where TRegistrationType : TBaseRegistrationType;
	}
	public interface ISerializer
	{
		void Serialize(TextWriter writer, object graph);

		string Serialize(object graph);

		void Serialize(TextWriter writer, object graph, Type type);

		void Serialize(IEmitter emitter, object graph);

		void Serialize(IEmitter emitter, object graph, Type type);
	}
	public interface ITypeInspector
	{
		IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container);

		IPropertyDescriptor GetProperty(Type type, object? container, string name, [MaybeNullWhen(true)] bool ignoreUnmatched);
	}
	public interface ITypeResolver
	{
		Type Resolve(Type staticType, object? actualValue);
	}
	public interface IValueDeserializer
	{
		object? DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer);
	}
	public interface IValuePromise
	{
		event Action<object?> ValueAvailable;
	}
	public interface IValueSerializer
	{
		void SerializeValue(IEmitter emitter, object? value, Type? type);
	}
	public interface IYamlConvertible
	{
		void Read(IParser parser, Type expectedType, ObjectDeserializer nestedObjectDeserializer);

		void Write(IEmitter emitter, ObjectSerializer nestedObjectSerializer);
	}
	public delegate object? ObjectDeserializer(Type type);
	public delegate void ObjectSerializer(object? value, Type? type = null);
	[Obsolete("Please use IYamlConvertible instead")]
	public interface IYamlSerializable
	{
		void ReadYaml(IParser parser);

		void WriteYaml(IEmitter emitter);
	}
	public interface IYamlTypeConverter
	{
		bool Accepts(Type type);

		object? ReadYaml(IParser parser, Type type);

		void WriteYaml(IEmitter emitter, object? value, Type type);
	}
	internal sealed class LazyComponentRegistrationList<TArgument, TComponent> : IEnumerable<Func<TArgument, TComponent>>, IEnumerable
	{
		public sealed class LazyComponentRegistration
		{
			public readonly Type ComponentType;

			public readonly Func<TArgument, TComponent> Factory;

			public LazyComponentRegistration(Type componentType, Func<TArgument, TComponent> factory)
			{
				ComponentType = componentType;
				Factory = factory;
			}
		}

		public sealed class TrackingLazyComponentRegistration
		{
			public readonly Type ComponentType;

			public readonly Func<TComponent, TArgument, TComponent> Factory;

			public TrackingLazyComponentRegistration(Type componentType, Func<TComponent, TArgument, TComponent> factory)
			{
				ComponentType = componentType;
				Factory = factory;
			}
		}

		private class RegistrationLocationSelector : IRegistrationLocationSelectionSyntax<TComponent>
		{
			private readonly LazyComponentRegistrationList<TArgument, TComponent> registrations;

			private readonly LazyComponentRegistration newRegistration;

			public RegistrationLocationSelector(LazyComponentRegistrationList<TArgument, TComponent> registrations, LazyComponentRegistration newRegistration)
			{
				this.registrations = registrations;
				this.newRegistration = newRegistration;
			}

			void IRegistrationLocationSelectionSyntax<TComponent>.InsteadOf<TRegistrationType>()
			{
				if (newRegistration.ComponentType != typeof(TRegistrationType))
				{
					registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType);
				}
				int index = registrations.EnsureRegistrationExists<TRegistrationType>();
				registrations.entries[index] = newRegistration;
			}

			void IRegistrationLocationSelectionSyntax<TComponent>.After<TRegistrationType>()
			{
				registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType);
				int num = registrations.EnsureRegistrationExists<TRegistrationType>();
				registrations.entries.Insert(num + 1, newRegistration);
			}

			void IRegistrationLocationSelectionSyntax<TComponent>.Before<TRegistrationType>()
			{
				registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType);
				int index = registrations.EnsureRegistrationExists<TRegistrationType>();
				registrations.entries.Insert(index, newRegistration);
			}

			void IRegistrationLocationSelectionSyntax<TComponent>.OnBottom()
			{
				registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType);
				registrations.entries.Add(newRegistration);
			}

			void IRegistrationLocationSelectionSyntax<TComponent>.OnTop()
			{
				registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType);
				registrations.entries.Insert(0, newRegistration);
			}
		}

		private class TrackingRegistrationLocationSelector : ITrackingRegistrationLocationSelectionSyntax<TComponent>
		{
			private readonly LazyComponentRegistrationList<TArgument, TComponent> registrations;

			private readonly TrackingLazyComponentRegistration newRegistration;

			public TrackingRegistrationLocationSelector(LazyComponentRegistrationList<TArgument, TComponent> registrations, TrackingLazyComponentRegistration newRegistration)
			{
				this.registrations = registrations;
				this.newRegistration = newRegistration;
			}

			void ITrackingRegistrationLocationSelectionSyntax<TComponent>.InsteadOf<TRegistrationType>()
			{
				if (newRegistration.ComponentType != typeof(TRegistrationType))
				{
					registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType);
				}
				int index = registrations.EnsureRegistrationExists<TRegistrationType>();
				Func<TArgument, TComponent> innerComponentFactory = registrations.entries[index].Factory;
				registrations.entries[index] = new LazyComponentRegistration(newRegistration.ComponentType, (TArgument arg) => newRegistration.Factory(innerComponentFactory(arg), arg));
			}
		}

		private readonly List<LazyComponentRegistration> entries = new List<LazyComponentRegistration>();

		public int Count => entries.Count;

		public IEnumerable<Func<TArgument, TComponent>> InReverseOrder
		{
			get
			{
				int i = entries.Count - 1;
				while (i >= 0)
				{
					yield return entries[i].Factory;
					int num = i - 1;
					i = num;
				}
			}
		}

		public LazyComponentRegistrationList<TArgument, TComponent> Clone()
		{
			LazyComponentRegistrationList<TArgument, TComponent> lazyComponentRegistrationList = new LazyComponentRegistrationList<TArgument, TComponent>();
			foreach (LazyComponentRegistration entry in entries)
			{
				lazyComponentRegistrationList.entries.Add(entry);
			}
			return lazyComponentRegistrationList;
		}

		public void Add(Type componentType, Func<TArgument, TComponent> factory)
		{
			entries.Add(new LazyComponentRegistration(componentType, factory));
		}

		public void Remove(Type componentType)
		{
			for (int i = 0; i < entries.Count; i++)
			{
				if (entries[i].ComponentType == componentType)
				{
					entries.RemoveAt(i);
					return;
				}
			}
			throw new KeyNotFoundException("A component registration of type '" + componentType.FullName + "' was not found.");
		}

		public IRegistrationLocationSelectionSyntax<TComponent> CreateRegistrationLocationSelector(Type componentType, Func<TArgument, TComponent> factory)
		{
			return new RegistrationLocationSelector(this, new LazyComponentRegistration(componentType, factory));
		}

		public ITrackingRegistrationLocationSelectionSyntax<TComponent> CreateTrackingRegistrationLocationSelector(Type componentType, Func<TComponent, TArgument, TComponent> factory)
		{
			return new TrackingRegistrationLocationSelector(this, new TrackingLazyComponentRegistration(componentType, factory));
		}

		public IEnumerator<Func<TArgument, TComponent>> GetEnumerator()
		{
			return entries.Select((LazyComponentRegistration e) => e.Factory).GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}

		private int IndexOfRegistration(Type registrationType)
		{
			for (int i = 0; i < entries.Count; i++)
			{
				if (registrationType == entries[i].ComponentType)
				{
					return i;
				}
			}
			return -1;
		}

		private void EnsureNoDuplicateRegistrationType(Type componentType)
		{
			if (IndexOfRegistration(componentType) != -1)
			{
				throw new InvalidOperationException("A component of type '" + componentType.FullName + "' has already been registered.");
			}
		}

		private int EnsureRegistrationExists<TRegistrationType>()
		{
			int num = IndexOfRegistration(typeof(TRegistrationType));
			if (num == -1)
			{
				throw new InvalidOperationException("A component of type '" + typeof(TRegistrationType).FullName + "' has not been registered.");
			}
			return num;
		}
	}
	internal static class LazyComponentRegistrationListExtensions
	{
		public static TComponent BuildComponentChain<TComponent>(this LazyComponentRegistrationList<TComponent, TComponent> registrations, TComponent innerComponent)
		{
			return registrations.InReverseOrder.Aggregate(innerComponent, (TComponent inner, Func<TComponent, TComponent> factory) => factory(inner));
		}

		public static TComponent BuildComponentChain<TArgument, TComponent>(this LazyComponentRegistrationList<TArgument, TComponent> registrations, TComponent innerComponent, Func<TComponent, TArgument> argumentBuilder)
		{
			Func<TComponent, TArgument> argumentBuilder2 = argumentBuilder;
			return registrations.InReverseOrder.Aggregate(innerComponent, (TComponent inner, Func<TArgument, TComponent> factory) => factory(argumentBuilder2(inner)));
		}

		public static List<TComponent> BuildComponentList<TComponent>(this LazyComponentRegistrationList<Nothing, TComponent> registrations)
		{
			return registrations.Select((Func<Nothing, TComponent> factory) => factory(Nothing.Instance)).ToList();
		}

		public static List<TComponent> BuildComponentList<TArgument, TComponent>(this LazyComponentRegistrationList<TArgument, TComponent> registrations, TArgument argument)
		{
			TArgument argument2 = argument;
			return registrations.Select((Func<TArgument, TComponent> factory) => factory(argument2)).ToList();
		}
	}
	public sealed class Nothing
	{
		public static readonly Nothing Instance = new Nothing();

		private Nothing()
		{
		}
	}
	public sealed class ObjectDescriptor : IObjectDescriptor
	{
		public object? Value { get; private set; }

		public Type Type { get; private set; }

		public Type StaticType { get; private set; }

		public ScalarStyle ScalarStyle { get; private set; }

		public ObjectDescriptor(object? value, Type type, Type staticType)
			: this(value, type, staticType, ScalarStyle.Any)
		{
		}

		public ObjectDescriptor(object? value, Type type, Type staticType, ScalarStyle scalarStyle)
		{
			Value = value;
			Type = type ?? throw new ArgumentNullException("type");
			StaticType = staticType ?? throw new ArgumentNullException("staticType");
			ScalarStyle = scalarStyle;
		}
	}
	public delegate IObjectGraphTraversalStrategy ObjectGraphTraversalStrategyFactory(ITypeInspector typeInspector, ITypeResolver typeResolver, IEnumerable<IYamlTypeConverter> typeConverters, int maximumRecursion);
	public sealed class PropertyDescriptor : IPropertyDescriptor
	{
		private readonly IPropertyDescriptor baseDescriptor;

		public string Name { get; set; }

		public Type Type => baseDescriptor.Type;

		public Type? TypeOverride
		{
			get
			{
				return baseDescriptor.TypeOverride;
			}
			set
			{
				baseDescriptor.TypeOverride = value;
			}
		}

		public int Order { get; set; }

		public ScalarStyle ScalarStyle
		{
			get
			{
				return baseDescriptor.ScalarStyle;
			}
			set
			{
				baseDescriptor.ScalarStyle = value;
			}
		}

		public bool CanWrite => baseDescriptor.CanWrite;

		public PropertyDescriptor(IPropertyDescriptor baseDescriptor)
		{
			this.baseDescriptor = baseDescriptor;
			Name = baseDescriptor.Name;
		}

		public void Write(object target, object? value)
		{
			baseDescriptor.Write(target, value);
		}

		public T GetCustomAttribute<T>() where T : Attribute
		{
			return baseDescriptor.GetCustomAttribute<T>();
		}

		public IObjectDescriptor Read(object target)
		{
			return baseDescriptor.Read(target);
		}
	}
	public sealed class Serializer : ISerializer
	{
		private readonly IValueSerializer valueSerializer;

		private readonly EmitterSettings emitterSettings;

		public Serializer()
			: this(new SerializerBuilder().BuildValueSerializer(), EmitterSettings.Default)
		{
		}

		private Serializer(IValueSerializer valueSerializer, EmitterSettings emitterSettings)
		{
			this.valueSerializer = valueSerializer ?? throw new ArgumentNullException("valueSerializer");
			this.emitterSettings = emitterSettings ?? throw new ArgumentNullException("emitterSettings");
		}

		public static Serializer FromValueSerializer(IValueSerializer valueSerializer, EmitterSettings emitterSettings)
		{
			return new Serializer(valueSerializer, emitterSettings);
		}

		public void Serialize(TextWriter writer, object graph)
		{
			Serialize(new Emitter(writer, emitterSettings), graph);
		}

		public string Serialize(object graph)
		{
			using StringWriter stringWriter = new StringWriter();
			Serialize(stringWriter, graph);
			return stringWriter.ToString();
		}

		public void Serialize(TextWriter writer, object graph, Type type)
		{
			Serialize(new Emitter(writer, emitterSettings), graph, type);
		}

		public void Serialize(IEmitter emitter, object graph)
		{
			if (emitter == null)
			{
				throw new ArgumentNullException("emitter");
			}
			EmitDocument(emitter, graph, null);
		}

		public void Serialize(IEmitter emitter, object graph, Type type)
		{
			if (emitter == null)
			{
				throw new ArgumentNullException("emitter");
			}
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			EmitDocument(emitter, graph, type);
		}

		private void EmitDocument(IEmitter emitter, object graph, Type? type)
		{
			emitter.Emit(new YamlDotNet.Core.Events.StreamStart());
			emitter.Emit(new YamlDotNet.Core.Events.DocumentStart());
			valueSerializer.SerializeValue(emitter, graph, type);
			emitter.Emit(new YamlDotNet.Core.Events.DocumentEnd(isImplicit: true));
			emitter.Emit(new YamlDotNet.Core.Events.StreamEnd());
		}
	}
	public sealed class SerializerBuilder : BuilderSkeleton<SerializerBuilder>
	{
		private class ValueSerializer : IValueSerializer
		{
			private readonly IObjectGraphTraversalStrategy traversalStrategy;

			private readonly IEventEmitter eventEmitter;

			private readonly IEnumerable<IYamlTypeConverter> typeConverters;

			private readonly LazyComponentRegistrationList<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>> preProcessingPhaseObjectGraphVisitorFactories;

			private readonly LazyComponentRegistrationList<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>> emissionPhaseObjectGraphVisitorFactories;

			public ValueSerializer(IObjectGraphTraversalStrategy traversalStrategy, IEventEmitter eventEmitter, IEnumerable<IYamlTypeConverter> typeConverters, LazyComponentRegistrationList<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>> preProcessingPhaseObjectGraphVisitorFactories, LazyComponentRegistrationList<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>> emissionPhaseObjectGraphVisitorFactories)
			{
				this.traversalStrategy = traversalStrategy;
				this.eventEmitter = eventEmitter;
				this.typeConverters = typeConverters;
				this.preProcessingPhaseObjectGraphVisitorFactories = preProcessingPhaseObjectGraphVisitorFactories;
				this.emissionPhaseObjectGraphVisitorFactories = emissionPhaseObjectGraphVisitorFactories;
			}

			public void SerializeValue(IEmitter emitter, object? value, Type? type)
			{
				IEmitter emitter2 = emitter;
				Type type2 = type ?? ((value != null) ? value.GetType() : typeof(object));
				Type staticType = type ?? typeof(object);
				ObjectDescriptor graph = new ObjectDescriptor(value, type2, staticType);
				List<IObjectGraphVisitor<Nothing>> preProcessingPhaseObjectGraphVisitors = preProcessingPhaseObjectGraphVisitorFactories.BuildComponentList(typeConverters);
				foreach (IObjectGraphVisitor<Nothing> item in preProcessingPhaseObjectGraphVisitors)
				{
					traversalStrategy.Traverse(graph, item, null);
				}
				IObjectGraphVisitor<IEmitter> visitor = emissionPhaseObjectGraphVisitorFactories.BuildComponentChain<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>>(new EmittingObjectGraphVisitor(eventEmitter), (IObjectGraphVisitor<IEmitter> inner) => new EmissionPhaseObjectGraphVisitorArgs(inner, eventEmitter, preProcessingPhaseObjectGraphVisitors, typeConverters, nestedObjectSerializer));
				traversalStrategy.Traverse(graph, visitor, emitter2);
				void nestedObjectSerializer(object? v, Type? t)
				{
					SerializeValue(emitter2, v, t);
				}
			}
		}

		private ObjectGraphTraversalStrategyFactory objectGraphTraversalStrategyFactory;

		private readonly LazyComponentRegistrationList<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>> preProcessingPhaseObjectGraphVisitorFactories;

		private readonly LazyComponentRegistrationList<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>> emissionPhaseObjectGraphVisitorFactories;

		private readonly LazyComponentRegistrationList<IEventEmitter, IEventEmitter> eventEmitterFactories;

		private readonly IDictionary<Type, string> tagMappings = new Dictionary<Type, string>();

		private int maximumRecursion = 50;

		private EmitterSettings emitterSettings = EmitterSettings.Default;

		private DefaultValuesHandling defaultValuesHandlingConfiguration;

		protected override SerializerBuilder Self => this;

		public SerializerBuilder()
			: base((ITypeResolver)new DynamicTypeResolver())
		{
			typeInspectorFactories.Add(typeof(CachedTypeInspector), (ITypeInspector inner) => new CachedTypeInspector(inner));
			typeInspectorFactories.Add(typeof(NamingConventionTypeInspector), (ITypeInspector inner) => (!(namingConvention is NullNamingConvention)) ? new NamingConventionTypeInspector(inner, namingConvention) : inner);
			typeInspectorFactories.Add(typeof(YamlAttributesTypeInspector), (ITypeInspector inner) => new YamlAttributesTypeInspector(inner));
			typeInspectorFactories.Add(typeof(YamlAttributeOverridesInspector), (ITypeInspector inner) => (overrides == null) ? inner : new YamlAttributeOverridesInspector(inner, overrides.Clone()));
			preProcessingPhaseObjectGraphVisitorFactories = new LazyComponentRegistrationList<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>> { 
			{
				typeof(AnchorAssigner),
				(IEnumerable<IYamlTypeConverter> typeConverters) => new AnchorAssigner(typeConverters)
			} };
			emissionPhaseObjectGraphVisitorFactories = new LazyComponentRegistrationList<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>>
			{
				{
					typeof(CustomSerializationObjectGraphVisitor),
					(EmissionPhaseObjectGraphVisitorArgs args) => new CustomSerializationObjectGraphVisitor(args.InnerVisitor, args.TypeConverters, args.NestedObjectSerializer)
				},
				{
					typeof(AnchorAssigningObjectGraphVisitor),
					(EmissionPhaseObjectGraphVisitorArgs args) => new AnchorAssigningObjectGraphVisitor(args.InnerVisitor, args.EventEmitter, args.GetPreProcessingPhaseObjectGraphVisitor<AnchorAssigner>())
				},
				{
					typeof(DefaultValuesObjectGraphVisitor),
					(EmissionPhaseObjectGraphVisitorArgs args) => new DefaultValuesObjectGraphVisitor(defaultValuesHandlingConfiguration, args.InnerVisitor)
				}
			};
			eventEmitterFactories = new LazyComponentRegistrationList<IEventEmitter, IEventEmitter> { 
			{
				typeof(TypeAssigningEventEmitter),
				(IEventEmitter inner) => new TypeAssigningEventEmitter(inner, requireTagWhenStaticAndActualTypesAreDifferent: false, tagMappings)
			} };
			objectGraphTraversalStrategyFactory = (ITypeInspector typeInspector, ITypeResolver typeResolver, IEnumerable<IYamlTypeConverter> typeConverters, int maximumRecursion) => new FullObjectGraphTraversalStrategy(typeInspector, typeResolver, maximumRecursion, namingConvention);
		}

		public SerializerBuilder WithMaximumRecursion(int maximumRecursion)
		{
			if (maximumRecursion <= 0)
			{
				throw new ArgumentOutOfRangeException("maximumRecursion", $"The maximum recursion specified ({maximumRecursion}) is invalid. It should be a positive integer.");
			}
			this.maximumRecursion = maximumRecursion;
			return this;
		}

		public SerializerBuilder WithEventEmitter<TEventEmitter>(Func<IEventEmitter, TEventEmitter> eventEmitterFactory) where TEventEmitter : IEventEmitter
		{
			return WithEventEmitter(eventEmitterFactory, delegate(IRegistrationLocationSelectionSyntax<IEventEmitter> w)
			{
				w.OnTop();
			});
		}

		public SerializerBuilder WithEventEmitter<TEventEmitter>(Func<IEventEmitter, TEventEmitter> eventEmitterFactory, Action<IRegistrationLocationSelectionSyntax<IEventEmitter>> where) where TEventEmitter : IEventEmitter
		{
			Func<IEventEmitter, TEventEmitter> eventEmitterFactory2 = eventEmitterFactory;
			if (eventEmitterFactory2 == null)
			{
				throw new ArgumentNullException("eventEmitterFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(eventEmitterFactories.CreateRegistrationLocationSelector(typeof(TEventEmitter), (IEventEmitter inner) => eventEmitterFactory2(inner)));
			return Self;
		}

		public SerializerBuilder WithEventEmitter<TEventEmitter>(WrapperFactory<IEventEmitter, IEventEmitter, TEventEmitter> eventEmitterFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IEventEmitter>> where) where TEventEmitter : IEventEmitter
		{
			WrapperFactory<IEventEmitter, IEventEmitter, TEventEmitter> eventEmitterFactory2 = eventEmitterFactory;
			if (eventEmitterFactory2 == null)
			{
				throw new ArgumentNullException("eventEmitterFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(eventEmitterFactories.CreateTrackingRegistrationLocationSelector(typeof(TEventEmitter), (IEventEmitter wrapped, IEventEmitter inner) => eventEmitterFactory2(wrapped, inner)));
			return Self;
		}

		public SerializerBuilder WithoutEventEmitter<TEventEmitter>() where TEventEmitter : IEventEmitter
		{
			return WithoutEventEmitter(typeof(TEventEmitter));
		}

		public SerializerBuilder WithoutEventEmitter(Type eventEmitterType)
		{
			if (eventEmitterType == null)
			{
				throw new ArgumentNullException("eventEmitterType");
			}
			eventEmitterFactories.Remove(eventEmitterType);
			return this;
		}

		public override SerializerBuilder WithTagMapping(string tag, Type type)
		{
			if (tag == null)
			{
				throw new ArgumentNullException("tag");
			}
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (tagMappings.TryGetValue(type, out string value))
			{
				throw new ArgumentException("Type already has a registered tag '" + value + "' for type '" + type.FullName + "'", "type");
			}
			tagMappings.Add(type, tag);
			return this;
		}

		public SerializerBuilder WithoutTagMapping(Type type)
		{
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (!tagMappings.Remove(type))
			{
				throw new KeyNotFoundException("Tag for type '" + type.FullName + "' is not registered");
			}
			return this;
		}

		public SerializerBuilder EnsureRoundtrip()
		{
			objectGraphTraversalStrategyFactory = (ITypeInspector typeInspector, ITypeResolver typeResolver, IEnumerable<IYamlTypeConverter> typeConverters, int maximumRecursion) => new RoundtripObjectGraphTraversalStrategy(typeConverters, typeInspector, typeResolver, maximumRecursion, namingConvention);
			WithEventEmitter((IEventEmitter inner) => new TypeAssigningEventEmitter(inner, requireTagWhenStaticAndActualTypesAreDifferent: true, tagMappings), delegate(IRegistrationLocationSelectionSyntax<IEventEmitter> loc)
			{
				loc.InsteadOf<TypeAssigningEventEmitter>();
			});
			return WithTypeInspector((ITypeInspector inner) => new ReadableAndWritablePropertiesTypeInspector(inner), delegate(IRegistrationLocationSelectionSyntax<ITypeInspector> loc)
			{
				loc.OnBottom();
			});
		}

		public SerializerBuilder DisableAliases()
		{
			preProcessingPhaseObjectGraphVisitorFactories.Remove(typeof(AnchorAssigner));
			emissionPhaseObjectGraphVisitorFactories.Remove(typeof(AnchorAssigningObjectGraphVisitor));
			return this;
		}

		[Obsolete("The default behavior is now to always emit default values, thefore calling this method has no effect. This behavior is now controlled by ConfigureDefaultValuesHandling.", true)]
		public SerializerBuilder EmitDefaults()
		{
			return ConfigureDefaultValuesHandling(DefaultValuesHandling.Preserve);
		}

		public SerializerBuilder ConfigureDefaultValuesHandling(DefaultValuesHandling configuration)
		{
			defaultValuesHandlingConfiguration = configuration;
			return this;
		}

		public SerializerBuilder JsonCompatible()
		{
			emitterSettings = emitterSettings.WithMaxSimpleKeyLength(int.MaxValue);
			return WithTypeConverter(new YamlDotNet.Serialization.Converters.GuidConverter(jsonCompatible: true), delegate(IRegistrationLocationSelectionSyntax<IYamlTypeConverter> w)
			{
				w.InsteadOf<YamlDotNet.Serialization.Converters.GuidConverter>();
			}).WithEventEmitter((IEventEmitter inner) => new JsonEventEmitter(inner), delegate(IRegistrationLocationSelectionSyntax<IEventEmitter> loc)
			{
				loc.InsteadOf<TypeAssigningEventEmitter>();
			});
		}

		public SerializerBuilder WithPreProcessingPhaseObjectGraphVisitor<TObjectGraphVisitor>(TObjectGraphVisitor objectGraphVisitor) where TObjectGraphVisitor : IObjectGraphVisitor<Nothing>
		{
			return WithPreProcessingPhaseObjectGraphVisitor(objectGraphVisitor, delegate(IRegistrationLocationSelectionSyntax<IObjectGraphVisitor<Nothing>> w)
			{
				w.OnTop();
			});
		}

		public SerializerBuilder WithPreProcessingPhaseObjectGraphVisitor<TObjectGraphVisitor>(TObjectGraphVisitor objectGraphVisitor, Action<IRegistrationLocationSelectionSyntax<IObjectGraphVisitor<Nothing>>> where) where TObjectGraphVisitor : IObjectGraphVisitor<Nothing>
		{
			TObjectGraphVisitor objectGraphVisitor2 = objectGraphVisitor;
			if (objectGraphVisitor2 == null)
			{
				throw new ArgumentNullException("objectGraphVisitor");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(preProcessingPhaseObjectGraphVisitorFactories.CreateRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IEnumerable<IYamlTypeConverter> _) => objectGraphVisitor2));
			return this;
		}

		public SerializerBuilder WithPreProcessingPhaseObjectGraphVisitor<TObjectGraphVisitor>(WrapperFactory<IObjectGraphVisitor<Nothing>, TObjectGraphVisitor> objectGraphVisitorFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IObjectGraphVisitor<Nothing>>> where) where TObjectGraphVisitor : IObjectGraphVisitor<Nothing>
		{
			WrapperFactory<IObjectGraphVisitor<Nothing>, TObjectGraphVisitor> objectGraphVisitorFactory2 = objectGraphVisitorFactory;
			if (objectGraphVisitorFactory2 == null)
			{
				throw new ArgumentNullException("objectGraphVisitorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(preProcessingPhaseObjectGraphVisitorFactories.CreateTrackingRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IObjectGraphVisitor<Nothing> wrapped, IEnumerable<IYamlTypeConverter> _) => objectGraphVisitorFactory2(wrapped)));
			return this;
		}

		public SerializerBuilder WithoutPreProcessingPhaseObjectGraphVisitor<TObjectGraphVisitor>() where TObjectGraphVisitor : IObjectGraphVisitor<Nothing>
		{
			return WithoutPreProcessingPhaseObjectGraphVisitor(typeof(TObjectGraphVisitor));
		}

		public SerializerBuilder WithoutPreProcessingPhaseObjectGraphVisitor(Type objectGraphVisitorType)
		{
			if (objectGraphVisitorType == null)
			{
				throw new ArgumentNullException("objectGraphVisitorType");
			}
			preProcessingPhaseObjectGraphVisitorFactories.Remove(objectGraphVisitorType);
			return this;
		}

		public SerializerBuilder WithObjectGraphTraversalStrategyFactory(ObjectGraphTraversalStrategyFactory objectGraphTraversalStrategyFactory)
		{
			this.objectGraphTraversalStrategyFactory = objectGraphTraversalStrategyFactory;
			return this;
		}

		public SerializerBuilder WithEmissionPhaseObjectGraphVisitor<TObjectGraphVisitor>(Func<EmissionPhaseObjectGraphVisitorArgs, TObjectGraphVisitor> objectGraphVisitorFactory) where TObjectGraphVisitor : IObjectGraphVisitor<IEmitter>
		{
			return WithEmissionPhaseObjectGraphVisitor(objectGraphVisitorFactory, delegate(IRegistrationLocationSelectionSyntax<IObjectGraphVisitor<IEmitter>> w)
			{
				w.OnTop();
			});
		}

		public SerializerBuilder WithEmissionPhaseObjectGraphVisitor<TObjectGraphVisitor>(Func<EmissionPhaseObjectGraphVisitorArgs, TObjectGraphVisitor> objectGraphVisitorFactory, Action<IRegistrationLocationSelectionSyntax<IObjectGraphVisitor<IEmitter>>> where) where TObjectGraphVisitor : IObjectGraphVisitor<IEmitter>
		{
			Func<EmissionPhaseObjectGraphVisitorArgs, TObjectGraphVisitor> objectGraphVisitorFactory2 = objectGraphVisitorFactory;
			if (objectGraphVisitorFactory2 == null)
			{
				throw new ArgumentNullException("objectGraphVisitorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(emissionPhaseObjectGraphVisitorFactories.CreateRegistrationLocationSelector(typeof(TObjectGraphVisitor), (EmissionPhaseObjectGraphVisitorArgs args) => objectGraphVisitorFactory2(args)));
			return this;
		}

		public SerializerBuilder WithEmissionPhaseObjectGraphVisitor<TObjectGraphVisitor>(WrapperFactory<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>, TObjectGraphVisitor> objectGraphVisitorFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IObjectGraphVisitor<IEmitter>>> where) where TObjectGraphVisitor : IObjectGraphVisitor<IEmitter>
		{
			WrapperFactory<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>, TObjectGraphVisitor> objectGraphVisitorFactory2 = objectGraphVisitorFactory;
			if (objectGraphVisitorFactory2 == null)
			{
				throw new ArgumentNullException("objectGraphVisitorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(emissionPhaseObjectGraphVisitorFactories.CreateTrackingRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IObjectGraphVisitor<IEmitter> wrapped, EmissionPhaseObjectGraphVisitorArgs args) => objectGraphVisitorFactory2(wrapped, args)));
			return this;
		}

		public SerializerBuilder WithoutEmissionPhaseObjectGraphVisitor<TObjectGraphVisitor>() where TObjectGraphVisitor : IObjectGraphVisitor<IEmitter>
		{
			return WithoutEmissionPhaseObjectGraphVisitor(typeof(TObjectGraphVisitor));
		}

		public SerializerBuilder WithoutEmissionPhaseObjectGraphVisitor(Type objectGraphVisitorType)
		{
			if (objectGraphVisitorType == null)
			{
				throw new ArgumentNullException("objectGraphVisitorType");
			}
			emissionPhaseObjectGraphVisitorFactories.Remove(objectGraphVisitorType);
			return this;
		}

		public ISerializer Build()
		{
			return Serializer.FromValueSerializer(BuildValueSerializer(), emitterSettings);
		}

		public IValueSerializer BuildValueSerializer()
		{
			IEnumerable<IYamlTypeConverter> typeConverters = BuildTypeConverters();
			ITypeInspector typeInspector = BuildTypeInspector();
			IObjectGraphTraversalStrategy traversalStrategy = objectGraphTraversalStrategyFactory(typeInspector, typeResolver, typeConverters, maximumRecursion);
			IEventEmitter eventEmitter = eventEmitterFactories.BuildComponentChain(new WriterEventEmitter());
			return new ValueSerializer(traversalStrategy, eventEmitter, typeConverters, preProcessingPhaseObjectGraphVisitorFactories.Clone(), emissionPhaseObjectGraphVisitorFactories.Clone());
		}
	}
	public sealed class StreamFragment : IYamlConvertible
	{
		private readonly List<ParsingEvent> events = new List<ParsingEvent>();

		public IList<ParsingEvent> Events => events;

		void IYamlConvertible.Read(IParser parser, Type expectedType, ObjectDeserializer nestedObjectDeserializer)
		{
			events.Clear();
			int num = 0;
			do
			{
				if (!parser.MoveNext())
				{
					throw new InvalidOperationException("The parser has reached the end before deserialization completed.");
				}
				ParsingEvent current = parser.Current;
				events.Add(current);
				num += current.NestingIncrease;
			}
			while (num > 0);
		}

		void IYamlConvertible.Write(IEmitter emitter, ObjectSerializer nestedObjectSerializer)
		{
			foreach (ParsingEvent @event in events)
			{
				emitter.Emit(@event);
			}
		}
	}
	public sealed class TagMappings
	{
		private readonly IDictionary<string, Type> mappings;

		public TagMappings()
		{
			mappings = new Dictionary<string, Type>();
		}

		public TagMappings(IDictionary<string, Type> mappings)
		{
			this.mappings = new Dictionary<string, Type>(mappings);
		}

		public void Add(string tag, Type mapping)
		{
			mappings.Add(tag, mapping);
		}

		internal Type? GetMapping(string tag)
		{
			if (!mappings.TryGetValue(tag, out Type value))
			{
				return null;
			}
			return value;
		}
	}
	public sealed class YamlAttributeOverrides
	{
		private struct AttributeKey
		{
			public readonly Type AttributeType;

			public readonly string PropertyName;

			public AttributeKey(Type attributeType, string propertyName)
			{
				AttributeType = attributeType;
				PropertyName = propertyName;
			}

			public override bool Equals(object? obj)
			{
				if (obj is AttributeKey attributeKey && AttributeType.Equals(attributeKey.AttributeType))
				{
					return PropertyName.Equals(attributeKey.PropertyName);
				}
				return false;
			}

			public override int GetHashCode()
			{
				return YamlDotNet.Core.HashCode.CombineHashCodes(AttributeType.GetHashCode(), PropertyName.GetHashCode());
			}
		}

		private sealed class AttributeMapping
		{
			public readonly Type RegisteredType;

			public readonly Attribute Attribute;

			public AttributeMapping(Type registeredType, Attribute attribute)
			{
				RegisteredType = registeredType;
				Attribute = attribute;
			}

			public override bool Equals(object? obj)
			{
				if (obj is AttributeMapping attributeMapping && RegisteredType.Equals(attributeMapping.RegisteredType))
				{
					return Attribute.Equals(attributeMapping.Attribute);
				}
				return false;
			}

			public override int GetHashCode()
			{
				return YamlDotNet.Core.HashCode.CombineHashCodes(RegisteredType.GetHashCode(), Attribute.GetHashCode());
			}

			public int Matches(Type matchType)
			{
				int num = 0;
				Type type = matchType;
				while (type != null)
				{
					num++;
					if (type == RegisteredType)
					{
						return num;
					}
					type = type.BaseType();
				}
				if (matchType.GetInterfaces().Contains(RegisteredType))
				{
					return num;
				}
				return 0;
			}
		}

		private readonly Dictionary<AttributeKey, List<AttributeMapping>> overrides = new Dictionary<AttributeKey, List<AttributeMapping>>();

		public T? GetAttribute<T>(Type type, string member) where T : Attribute
		{
			if (overrides.TryGetValue(new AttributeKey(typeof(T), member), out List<AttributeMapping> value))
			{
				int num = 0;
				AttributeMapping attributeMapping = null;
				foreach (AttributeMapping item in value)
				{
					int num2 = item.Matches(type);
					if (num2 > num)
					{
						num = num2;
						attributeMapping = item;
					}
				}
				if (num > 0)
				{
					return (T)attributeMapping.Attribute;
				}
			}
			return null;
		}

		public void Add(Type type, string member, Attribute attribute)
		{
			AttributeMapping item = new AttributeMapping(type, attribute);
			AttributeKey key = new AttributeKey(attribute.GetType(), member);
			if (!overrides.TryGetValue(key, out List<AttributeMapping> value))
			{
				value = new List<AttributeMapping>();
				overrides.Add(key, value);
			}
			else if (value.Contains(item))
			{
				throw new InvalidOperationException($"Attribute ({attribute}) already set for Type {type.FullName}, Member {member}");
			}
			value.Add(item);
		}

		public void Add<TClass>(Expression<Func<TClass, object>> propertyAccessor, Attribute attribute)
		{
			PropertyInfo propertyInfo = propertyAccessor.AsProperty();
			Add(typeof(TClass), propertyInfo.Name, attribute);
		}

		public YamlAttributeOverrides Clone()
		{
			YamlAttributeOverrides yamlAttributeOverrides = new YamlAttributeOverrides();
			foreach (KeyValuePair<AttributeKey, List<AttributeMapping>> @override in overrides)
			{
				foreach (AttributeMapping item in @override.Value)
				{
					yamlAttributeOverrides.Add(item.RegisteredType, @override.Key.PropertyName, item.Attribute);
				}
			}
			return yamlAttributeOverrides;
		}
	}
	public sealed class YamlAttributeOverridesInspector : TypeInspectorSkeleton
	{
		public sealed class OverridePropertyDescriptor : IPropertyDescriptor
		{
			private readonly IPropertyDescriptor baseDescriptor;

			private readonly YamlAttributeOverrides overrides;

			private readonly Type classType;

			public string Name => baseDescriptor.Name;

			public bool CanWrite => baseDescriptor.CanWrite;

			public Type Type => baseDescriptor.Type;

			public Type? TypeOverride
			{
				get
				{
					return baseDescriptor.TypeOverride;
				}
				set
				{
					baseDescriptor.TypeOverride = value;
				}
			}

			public int Order
			{
				get
				{
					return baseDescriptor.Order;
				}
				set
				{
					baseDescriptor.Order = value;
				}
			}

			public ScalarStyle ScalarStyle
			{
				get
				{
					return baseDescriptor.ScalarStyle;
				}
				set
				{
					baseDescriptor.ScalarStyle = value;
				}
			}

			public OverridePropertyDescriptor(IPropertyDescriptor baseDescriptor, YamlAttributeOverrides overrides, Type classType)
			{
				this.baseDescriptor = baseDescriptor;
				this.overrides = overrides;
				this.classType = classType;
			}

			public void Write(object target, object? value)
			{
				baseDescriptor.Write(target, value);
			}

			public T GetCustomAttribute<T>() where T : Attribute
			{
				return overrides.GetAttribute<T>(classType, Name) ?? baseDescriptor.GetCustomAttribute<T>();
			}

			public IObjectDescriptor Read(object target)
			{
				return baseDescriptor.Read(target);
			}
		}

		private readonly ITypeInspector innerTypeDescriptor;

		private readonly YamlAttributeOverrides overrides;

		public YamlAttributeOverridesInspector(ITypeInspector innerTypeDescriptor, YamlAttributeOverrides overrides)
		{
			this.innerTypeDescriptor = innerTypeDescriptor;
			this.overrides = overrides;
		}

		public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container)
		{
			Type type2 = type;
			IEnumerable<IPropertyDescriptor> enumerable = innerTypeDescriptor.GetProperties(type2, container);
			if (overrides != null)
			{
				enumerable = enumerable.Select((Func<IPropertyDescriptor, IPropertyDescriptor>)((IPropertyDescriptor p) => new OverridePropertyDescriptor(p, overrides, type2)));
			}
			return enumerable;
		}
	}
	public sealed class YamlAttributesTypeInspector : TypeInspectorSkeleton
	{
		private readonly ITypeInspector innerTypeDescriptor;

		public YamlAttributesTypeInspector(ITypeInspector innerTypeDescriptor)
		{
			this.innerTypeDescriptor = innerTypeDescriptor;
		}

		public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container)
		{
			return from p in (from p in innerTypeDescriptor.GetProperties(type, container)
					where p.GetCustomAttribute<YamlIgnoreAttribute>() == null
					select p).Select((Func<IPropertyDescriptor, IPropertyDescriptor>)delegate(IPropertyDescriptor p)
				{
					PropertyDescriptor propertyDescriptor = new PropertyDescriptor(p);
					YamlMemberAttribute customAttribute = p.GetCustomAttribute<YamlMemberAttribute>();
					if (customAttribute != null)
					{
						if (customAttribute.SerializeAs != null)
						{
							propertyDescriptor.TypeOverride = customAttribute.SerializeAs;
						}
						propertyDescriptor.Order = customAttribute.Order;
						propertyDescriptor.ScalarStyle = customAttribute.ScalarStyle;
						if (customAttribute.Alias != null)
						{
							propertyDescriptor.Name = customAttribute.Alias;
						}
					}
					return propertyDescriptor;
				})
				orderby p.Order
				select p;
		}
	}
	internal static class YamlFormatter
	{
		public static readonly NumberFormatInfo NumberFormat = new NumberFormatInfo
		{
			CurrencyDecimalSeparator = ".",
			CurrencyGroupSeparator = "_",
			CurrencyGroupSizes = new int[1] { 3 },
			CurrencySymbol = string.Empty,
			CurrencyDecimalDigits = 99,
			NumberDecimalSeparator = ".",
			NumberGroupSeparator = "_",
			NumberGroupSizes = new int[1] { 3 },
			NumberDecimalDigits = 99,
			NaNSymbol = ".nan",
			PositiveInfinitySymbol = ".inf",
			NegativeInfinitySymbol = "-.inf"
		};

		public static string FormatNumber(object number)
		{
			return Convert.ToString(number, NumberFormat);
		}

		public static string FormatNumber(double number)
		{
			return number.ToString("G17", NumberFormat);
		}

		public static string FormatNumber(float number)
		{
			return number.ToString("G17", NumberFormat);
		}

		public static string FormatBoolean(object boolean)
		{
			if (!boolean.Equals(true))
			{
				return "false";
			}
			return "true";
		}

		public static string FormatDateTime(object dateTime)
		{
			return ((DateTime)dateTime).ToString("o", CultureInfo.InvariantCulture);
		}

		public static string FormatTimeSpan(object timeSpan)
		{
			return ((TimeSpan)timeSpan).ToString();
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public sealed class YamlIgnoreAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public sealed class YamlMemberAttribute : Attribute
	{
		private DefaultValuesHandling? defaultValuesHandling;

		public Type? SerializeAs { get; set; }

		public int Order { get; set; }

		public string? Alias { get; set; }

		public bool ApplyNamingConventions { get; set; }

		public ScalarStyle ScalarStyle { get; set; }

		public DefaultValuesHandling DefaultValuesHandling
		{
			get
			{
				return defaultValuesHandling.GetValueOrDefault();
			}
			set
			{
				defaultValuesHandling = value;
			}
		}

		public bool IsDefaultValuesHandlingSpecified => defaultValuesHandling.HasValue;

		public YamlMemberAttribute()
		{
			ScalarStyle = ScalarStyle.Any;
			ApplyNamingConventions = true;
		}

		public YamlMemberAttribute(Type serializeAs)
			: this()
		{
			SerializeAs = serializeAs ?? throw new ArgumentNullException("serializeAs");
		}
	}
}
namespace YamlDotNet.Serialization.ValueDeserializers
{
	public sealed class AliasValueDeserializer : IValueDeserializer
	{
		private sealed class AliasState : Dictionary<string, ValuePromise>, IPostDeserializationCallback
		{
			public void OnDeserialization()
			{
				foreach (ValuePromise value in base.Values)
				{
					if (!value.HasValue)
					{
						YamlDotNet.Core.Events.AnchorAlias alias = value.Alias;
						throw new AnchorNotFoundException(alias.Start, alias.End, "Anchor '" + alias.Value + "' not found");
					}
				}
			}
		}

		private sealed class ValuePromise : IValuePromise
		{
			private object? value;

			public readonly YamlDotNet.Core.Events.AnchorAlias? Alias;

			public bool HasValue { get; private set; }

			public object? Value
			{
				get
				{
					if (!HasValue)
					{
						throw new InvalidOperationException("Value not set");
					}
					return value;
				}
				set
				{
					if (HasValue)
					{
						throw new InvalidOperationException("Value already set");
					}
					HasValue = true;
					this.value = value;
					this.ValueAvailable?.Invoke(value);
				}
			}

			public event Action<object?>? ValueAvailable;

			public ValuePromise(YamlDotNet.Core.Events.AnchorAlias alias)
			{
				Alias = alias;
			}

			public ValuePromise(object? value)
			{
				HasValue = true;
				this.value = value;
			}
		}

		private readonly IValueDeserializer innerDeserializer;

		public AliasValueDeserializer(IValueDeserializer innerDeserializer)
		{
			this.innerDeserializer = innerDeserializer ?? throw new ArgumentNullException("innerDeserializer");
		}

		public object? DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer)
		{
			if (parser.TryConsume<YamlDotNet.Core.Events.AnchorAlias>(out var @event))
			{
				AliasState aliasState = state.Get<AliasState>();
				if (!aliasState.TryGetValue(@event.Value, out ValuePromise value))
				{
					value = new ValuePromise(@event);
					aliasState.Add(@event.Value, value);
				}
				if (!value.HasValue)
				{
					return value;
				}
				return value.Value;
			}
			string text = null;
			if (parser.Accept<NodeEvent>(out var event2) && !string.IsNullOrEmpty(event2.Anchor))
			{
				text = event2.Anchor;
			}
			object obj = innerDeserializer.DeserializeValue(parser, expectedType, state, nestedObjectDeserializer);
			if (text != null)
			{
				AliasState aliasState2 = state.Get<AliasState>();
				if (!aliasState2.TryGetValue(text, out ValuePromise value2))
				{
					aliasState2.Add(text, new ValuePromise(obj));
				}
				else if (!value2.HasValue)
				{
					value2.Value = obj;
				}
				else
				{
					aliasState2[text] = new ValuePromise(obj);
				}
			}
			return obj;
		}
	}
	public sealed class NodeValueDeserializer : IValueDeserializer
	{
		private readonly IList<INodeDeserializer> deserializers;

		private readonly IList<INodeTypeResolver> typeResolvers;

		public NodeValueDeserializer(IList<INodeDeserializer> deserializers, IList<INodeTypeResolver> typeResolvers)
		{
			this.deserializers = deserializers ?? throw new ArgumentNullException("deserializers");
			this.typeResolvers = typeResolvers ?? throw new ArgumentNullException("typeResolvers");
		}

		public object? DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer)
		{
			IValueDeserializer nestedObjectDeserializer2 = nestedObjectDeserializer;
			SerializerState state2 = state;
			parser.Accept<NodeEvent>(out var @event);
			Type typeFromEvent = GetTypeFromEvent(@event, expectedType);
			try
			{
				foreach (INodeDeserializer deserializer in deserializers)
				{
					if (deserializer.Deserialize(parser, typeFromEvent, (IParser r, Type t) => nestedObjectDeserializer2.DeserializeValue(r, t, state2, nestedObjectDeserializer2), out object value))
					{
						return YamlDotNet.Serialization.Utilities.TypeConverter.ChangeType(value, expectedType);
					}
				}
			}
			catch (YamlException)
			{
				throw;
			}
			catch (Exception innerException)
			{
				throw new YamlException(@event?.Start ?? Mark.Empty, @event?.End ?? Mark.Empty, "Exception during deserialization", innerException);
			}
			throw new YamlException(@event?.Start ?? Mark.Empty, @event?.End ?? Mark.Empty, "No node deserializer was able to deserialize the node into type " + expectedType.AssemblyQualifiedName);
		}

		private Type GetTypeFromEvent(NodeEvent? nodeEvent, Type currentType)
		{
			using (IEnumerator<INodeTypeResolver> enumerator = typeResolvers.GetEnumerator())
			{
				while (enumerator.MoveNext() && !enumerator.Current.Resolve(nodeEvent, ref currentType))
				{
				}
			}
			return currentType;
		}
	}
}
namespace YamlDotNet.Serialization.Utilities
{
	public interface IPostDeserializationCallback
	{
		void OnDeserialization();
	}
	internal sealed class ObjectAnchorCollection
	{
		private readonly IDictionary<string, object> objectsByAnchor = new Dictionary<string, object>();

		private readonly IDictionary<object, string> anchorsByObject = new Dictionary<object, string>();

		public object this[string anchor]
		{
			get
			{
				if (objectsByAnchor.TryGetValue(anchor, out object value))
				{
					return value;
				}
				throw new AnchorNotFoundException("The anchor '" + anchor + "' does not exists");
			}
		}

		public void Add(string anchor, object @object)
		{
			objectsByAnchor.Add(anchor, @object);
			if (@object != null)
			{
				anchorsByObject.Add(@object, anchor);
			}
		}

		public bool TryGetAnchor(object @object, [MaybeNullWhen(false)] out string? anchor)
		{
			return anchorsByObject.TryGetValue(@object, out anchor);
		}
	}
	internal static class ReflectionUtility
	{
		public static Type? GetImplementedGenericInterface(Type type, Type genericInterfaceType)
		{
			foreach (Type implementedInterface in GetImplementedInterfaces(type))
			{
				if (implementedInterface.IsGenericType() && implementedInterface.GetGenericTypeDefinition() == genericInterfaceType)
				{
					return implementedInterface;
				}
			}
			return null;
		}

		public static IEnumerable<Type> GetImplementedInterfaces(Type type)
		{
			if (type.IsInterface())
			{
				yield return type;
			}
			Type[] interfaces = type.GetInterfaces();
			for (int i = 0; i < interfaces.Length; i++)
			{
				yield return interfaces[i];
			}
		}
	}
	public sealed class SerializerState : IDisposable
	{
		private readonly IDictionary<Type, object> items = new Dictionary<Type, object>();

		public T Get<T>() where T : class, new()
		{
			if (!items.TryGetValue(typeof(T), out object value))
			{
				value = new T();
				items.Add(typeof(T), value);
			}
			return (T)value;
		}

		public void OnDeserialization()
		{
			foreach (IPostDeserializationCallback item in items.Values.OfType<IPostDeserializationCallback>())
			{
				item.OnDeserialization();
			}
		}

		public void Dispose()
		{
			foreach (IDisposable item in items.Values.OfType<IDisposable>())
			{
				item.Dispose();
			}
		}
	}
	internal static class StringExtensions
	{
		private static string ToCamelOrPascalCase(string str, Func<char, char> firstLetterTransform)
		{
			string text = Regex.Replace(str, "([_\\-])(?<char>[a-z])", (Match match) => match.Groups["char"].Value.ToUpperInvariant(), RegexOptions.IgnoreCase);
			return firstLetterTransform(text[0]) + text.Substring(1);
		}

		public static string ToCamelCase(this string str)
		{
			return ToCamelOrPascalCase(str, char.ToLowerInvariant);
		}

		public static string ToPascalCase(this string str)
		{
			return ToCamelOrPascalCase(str, char.ToUpperInvariant);
		}

		public static string FromCamelCase(this string str, string separator)
		{
			string separator2 = separator;
			str = char.ToLower(str[0]) + str.Substring(1);
			str = Regex.Replace(str.ToCamelCase(), "(?<char>[A-Z])", (Match match) => separator2 + match.Groups["char"].Value.ToLowerInvariant());
			return str;
		}
	}
	public static class TypeConverter
	{
		[PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
		public static void RegisterTypeConverter<TConvertible, TConverter>() where TConverter : System.ComponentModel.TypeConverter
		{
			if (!TypeDescriptor.GetAttributes(typeof(TConvertible)).OfType<TypeConverterAttribute>().Any((TypeConverterAttribute a) => a.ConverterTypeName == typeof(TConverter).AssemblyQualifiedName))
			{
				TypeDescriptor.AddAttributes(typeof(TConvertible), new TypeConverterAttribute(typeof(TConverter)));
			}
		}

		public static T ChangeType<T>(object? value)
		{
			return (T)ChangeType(value, typeof(T));
		}

		public static T ChangeType<T>(object? value, IFormatProvider provider)
		{
			return (T)ChangeType(value, typeof(T), provider);
		}

		public static T ChangeType<T>(object? value, CultureInfo culture)
		{
			return (T)ChangeType(value, typeof(T), culture);
		}

		public static object? ChangeType(object? value, Type destinationType)
		{
			return ChangeType(value, destinationType, CultureInfo.InvariantCulture);
		}

		public static object? ChangeType(object? value, Type destinationType, IFormatProvider provider)
		{
			return ChangeType(value, destinationType, new CultureInfoAdapter(CultureInfo.CurrentCulture, provider));
		}

		public static object? ChangeType(object? value, Type destinationType, CultureInfo culture)
		{
			if (value == null || value.IsDbNull())
			{
				if (!destinationType.IsValueType())
				{
					return null;
				}
				return Activator.CreateInstance(destinationType);
			}
			Type type = value.GetType();
			if (destinationType == type || destinationType.IsAssignableFrom(type))
			{
				return value;
			}
			if (destinationType.IsGenericType() && destinationType.GetGenericTypeDefinition() == typeof(Nullable<>))
			{
				Type destinationType2 = destinationType.GetGenericArguments()[0];
				object obj = ChangeType(value, destinationType2, culture);
				return Activator.CreateInstance(destinationType, obj);
			}
			if (destinationType.IsEnum())
			{
				if (!(value is string value2))
				{
					return value;
				}
				return Enum.Parse(destinationType, value2, ignoreCase: true);
			}
			if (destinationType == typeof(bool))
			{
				if ("0".Equals(value))
				{
					return false;
				}
				if ("1".Equals(value))
				{
					return true;
				}
			}
			System.ComponentModel.TypeConverter converter = TypeDescriptor.GetConverter(type);
			if (converter != null && converter.CanConvertTo(destinationType))
			{
				return converter.ConvertTo(null, culture, value, destinationType);
			}
			System.ComponentModel.TypeConverter converter2 = TypeDescriptor.GetConverter(destinationType);
			if (converter2 != null && converter2.CanConvertFrom(type))
			{
				return converter2.ConvertFrom(null, culture, value);
			}
			Type[] array = new Type[2] { type, destinationType };
			for (int i = 0; i < array.Length; i++)
			{
				foreach (MethodInfo publicStaticMethod2 in array[i].GetPublicStaticMethods())
				{
					if (!publicStaticMethod2.IsSpecialName || (!(publicStaticMethod2.Name == "op_Implicit") && !(publicStaticMethod2.Name == "op_Explicit")) || !destinationType.IsAssignableFrom(publicStaticMethod2.ReturnParameter.ParameterType))
					{
						continue;
					}
					ParameterInfo[] parameters = publicStaticMethod2.GetParameters();
					if (parameters.Length == 1 && parameters[0].ParameterType.IsAssignableFrom(type))
					{
						try
						{
							return publicStaticMethod2.Invoke(null, new object[1] { value });
						}
						catch (TargetInvocationException ex)
						{
							throw ex.Unwrap();
						}
					}
				}
			}
			if (type == typeof(string))
			{
				try
				{
					MethodInfo publicStaticMethod = destinationType.GetPublicStaticMethod("Parse", typeof(string), typeof(IFormatProvider));
					if (publicStaticMethod != null)
					{
						return publicStaticMethod.Invoke(null, new object[2] { value, culture });
					}
					publicStaticMethod = destinationType.GetPublicStaticMethod("Parse", typeof(string));
					if (publicStaticMethod != null)
					{
						return publicStaticMethod.Invoke(null, new object[1] { value });
					}
				}
				catch (TargetInvocationException ex2)
				{
					throw ex2.Unwrap();
				}
			}
			if (destinationType == typeof(TimeSpan))
			{
				return TimeSpan.Parse((string)ChangeType(value, typeof(string), CultureInfo.InvariantCulture));
			}
			return Convert.ChangeType(value, destinationType, CultureInfo.InvariantCulture);
		}
	}
}
namespace YamlDotNet.Serialization.TypeResolvers
{
	public sealed class DynamicTypeResolver : ITypeResolver
	{
		public Type Resolve(Type staticType, object? actualValue)
		{
			if (actualValue == null)
			{
				return staticType;
			}
			return actualValue.GetType();
		}
	}
	public sealed class StaticTypeResolver : ITypeResolver
	{
		public Type Resolve(Type staticType, object? actualValue)
		{
			return staticType;
		}
	}
}
namespace YamlDotNet.Serialization.TypeInspectors
{
	public sealed class CachedTypeInspector : TypeInspectorSkeleton
	{
		private readonly ITypeInspector innerTypeDescriptor;

		private readonly ConcurrentDictionary<Type, List<IPropertyDescriptor>> cache = new ConcurrentDictionary<Type, List<IPropertyDescriptor>>();

		public CachedTypeInspector(ITypeInspector innerTypeDescriptor)
		{
			this.innerTypeDescriptor = innerTypeDescriptor ?? throw new ArgumentNullException("innerTypeDescriptor");
		}

		public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container)
		{
			object container2 = container;
			return cache.GetOrAdd(type, (Type t) => innerTypeDescriptor.GetProperties(t, container2).ToList());
		}
	}
	public sealed class CompositeTypeInspector : TypeInspectorSkeleton
	{
		private readonly IEnumerable<ITypeInspector> typeInspectors;

		public CompositeTypeInspector(params ITypeInspector[] typeInspectors)
			: this((IEnumerable<ITypeInspector>)typeInspectors)
		{
		}

		public CompositeTypeInspector(IEnumerable<ITypeInspector> typeInspectors)
		{
			this.typeInspectors = typeInspectors?.ToList() ?? throw new ArgumentNullException("typeInspectors");
		}

		public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container)
		{
			Type type2 = type;
			object container2 = container;
			return typeInspectors.SelectMany((ITypeInspector i) => i.GetProperties(type2, container2));
		}
	}
	public sealed class NamingConventionTypeInspector : TypeInspectorSkeleton
	{
		private readonly ITypeInspector innerTypeDescriptor;

		private readonly INamingConvention namingConvention;

		public NamingConventionTypeInspector(ITypeInspector innerTypeDescriptor, INamingConvention namingConvention)
		{
			this.innerTypeDescriptor = innerTypeDescriptor ?? throw new ArgumentNullException("innerTypeDescriptor");
			this.namingConvention = namingConvention ?? throw new ArgumentNullException("namingConvention");
		}

		public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container)
		{
			return innerTypeDescriptor.GetProperties(type, container).Select(delegate(IPropertyDescriptor p)
			{
				YamlMemberAttribute customAttribute = p.GetCustomAttribute<YamlMemberAttribute>();
				return (customAttribute != null && !customAttribute.ApplyNamingConventions) ? p : new PropertyDescriptor(p)
				{
					Name = namingConvention.Apply(p.Name)
				};
			});
		}
	}
	public sealed class ReadableAndWritablePropertiesTypeInspector : TypeInspectorSkeleton
	{
		private readonly ITypeInspector innerTypeDescriptor;

		public ReadableAndWritablePropertiesTypeInspector(ITypeInspector innerTypeDescriptor)
		{
			this.innerTypeDescriptor = innerTypeDescriptor ?? throw new ArgumentNullException("innerTypeDescriptor");
		}

		public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container)
		{
			return from p in innerTypeDescriptor.GetProperties(type, container)
				where p.CanWrite
				select p;
		}
	}
	public sealed class ReadableFieldsTypeInspector : TypeInspectorSkeleton
	{
		private sealed class ReflectionFieldDescriptor : IPropertyDescriptor
		{
			private readonly FieldInfo fieldInfo;

			private readonly ITypeResolver typeResolver;

			public string Name => fieldInfo.Name;

			public Type Type => fieldInfo.FieldType;

			public Type? TypeOverride { get; set; }

			public int Order { get; set; }

			public bool CanWrite => !fieldInfo.IsInitOnly;

			public ScalarStyle ScalarStyle { get; set; }

			public ReflectionFieldDescriptor(FieldInfo fieldInfo, ITypeResolver typeResolver)
			{
				this.fieldInfo = fieldInfo;
				this.typeResolver = typeResolver;
				ScalarStyle = ScalarStyle.Any;
			}

			public void Write(object target, object? value)
			{
				fieldInfo.SetValue(target, value);
			}

			public T GetCustomAttribute<T>() where T : Attribute
			{
				return (T)fieldInfo.GetCustomAttributes(typeof(T), inherit: true).FirstOrDefault();
			}

			public IObjectDescriptor Read(object target)
			{
				object value = fieldInfo.GetValue(target);
				Type type = TypeOverride ?? typeResolver.Resolve(Type, value);
				return new ObjectDescriptor(value, type, Type, ScalarStyle);
			}
		}

		private readonly ITypeResolver typeResolver;

		public ReadableFieldsTypeInspector(ITypeResolver typeResolver)
		{
			this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver");
		}

		public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container)
		{
			return type.GetPublicFields().Select((Func<FieldInfo, IPropertyDescriptor>)((FieldInfo p) => new ReflectionFieldDescriptor(p, typeResolver)));
		}
	}
	public sealed class ReadablePropertiesTypeInspector : TypeInspectorSkeleton
	{
		private sealed class ReflectionPropertyDescriptor : IPropertyDescriptor
		{
			private readonly PropertyInfo propertyInfo;

			private readonly ITypeResolver typeResolver;

			public string Name => propertyInfo.Name;

			public Type Type => propertyInfo.PropertyType;

			public Type? TypeOverride { get; set; }

			public int Order { get; set; }

			public bool CanWrite => propertyInfo.CanWrite;

			public ScalarStyle ScalarStyle { get; set; }

			public ReflectionPropertyDescriptor(PropertyInfo propertyInfo, ITypeResolver typeResolver)
			{
				this.propertyInfo = propertyInfo ?? throw new ArgumentNullException("propertyInfo");
				this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver");
				ScalarStyle = ScalarStyle.Any;
			}

			public void Write(object target, object? value)
			{
				propertyInfo.SetValue(target, value, null);
			}

			public T GetCustomAttribute<T>() where T : Attribute
			{
				return (T)propertyInfo.GetAllCustomAttributes<T>().FirstOrDefault();
			}

			public IObjectDescriptor Read(object target)
			{
				object obj = propertyInfo.ReadValue(target);
				Type type = TypeOverride ?? typeResolver.Resolve(Type, obj);
				return new ObjectDescriptor(obj, type, Type, ScalarStyle);
			}
		}

		private readonly ITypeResolver typeResolver;

		public ReadablePropertiesTypeInspector(ITypeResolver typeResolver)
		{
			this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver");
		}

		private static bool IsValidProperty(PropertyInfo property)
		{
			if (property.CanRead)
			{
				return property.GetGetMethod().GetParameters().Length == 0;
			}
			return false;
		}

		public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container)
		{
			return type.GetPublicProperties().Where(IsValidProperty).Select((Func<PropertyInfo, IPropertyDescriptor>)((PropertyInfo p) => new ReflectionPropertyDescriptor(p, typeResolver)));
		}
	}
	public abstract class TypeInspectorSkeleton : ITypeInspector
	{
		public abstract IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container);

		public IPropertyDescriptor GetProperty(Type type, object? container, string name, [MaybeNullWhen(true)] bool ignoreUnmatched)
		{
			string name2 = name;
			IEnumerable<IPropertyDescriptor> enumerable = from p in GetProperties(type, container)
				where p.Name == name2
				select p;
			using IEnumerator<IPropertyDescriptor> enumerator = enumerable.GetEnumerator();
			if (!enumerator.MoveNext())
			{
				if (ignoreUnmatched)
				{
					return null;
				}
				throw new SerializationException("Property '" + name2 + "' not found on type '" + type.FullName + "'.");
			}
			IPropertyDescriptor current = enumerator.Current;
			if (enumerator.MoveNext())
			{
				throw new SerializationException("Multiple properties with the name/alias '" + name2 + "' already exists on type '" + type.FullName + "', maybe you're misusing YamlAlias or maybe you are using the wrong naming convention? The matching properties are: " + string.Join(", ", enumerable.Select((IPropertyDescriptor p) => p.Name).ToArray()));
			}
			return current;
		}
	}
}
namespace YamlDotNet.Serialization.ObjectGraphVisitors
{
	public sealed class AnchorAssigner : PreProcessingPhaseObjectGraphVisitorSkeleton, IAliasProvider
	{
		private class AnchorAssignment
		{
			public string? Anchor;
		}

		private readonly IDictionary<object, AnchorAssignment> assignments = new Dictionary<object, AnchorAssignment>();

		private uint nextId;

		public AnchorAssigner(IEnumerable<IYamlTypeConverter> typeConverters)
			: base(typeConverters)
		{
		}

		protected override bool Enter(IObjectDescriptor value)
		{
			if (value.Value != null && assignments.TryGetValue(value.Value, out AnchorAssignment value2))
			{
				if (value2.Anchor == null)
				{
					value2.Anchor = "o" + nextId.ToString(CultureInfo.InvariantCulture);
					nextId++;
				}
				return false;
			}
			return true;
		}

		protected override bool EnterMapping(IObjectDescriptor key, IObjectDescriptor value)
		{
			return true;
		}

		protected override bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value)
		{
			return true;
		}

		protected override void VisitScalar(IObjectDescriptor scalar)
		{
		}

		protected override void VisitMappingStart(IObjectDescriptor mapping, Type keyType, Type valueType)
		{
			VisitObject(mapping);
		}

		protected override void VisitMappingEnd(IObjectDescriptor mapping)
		{
		}

		protected override void VisitSequenceStart(IObjectDescriptor sequence, Type elementType)
		{
			VisitObject(sequence);
		}

		protected override void VisitSequenceEnd(IObjectDescriptor sequence)
		{
		}

		private void VisitObject(IObjectDescriptor value)
		{
			if (value.Value != null)
			{
				assignments.Add(value.Value, new AnchorAssignment());
			}
		}

		string? IAliasProvider.GetAlias(object target)
		{
			if (target != null && assignments.TryGetValue(target, out AnchorAssignment value))
			{
				return value.Anchor;
			}
			return null;
		}
	}
	public sealed class AnchorAssigningObjectGraphVisitor : ChainedObjectGraphVisitor
	{
		private readonly IEventEmitter eventEmitter;

		private readonly IAliasProvider aliasProvider;

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

		public AnchorAssigningObjectGraphVisitor(IObjectGraphVisitor<IEmitter> nextVisitor, IEventEmitter eventEmitter, IAliasProvider aliasProvider)
			: base(nextVisitor)
		{
			this.eventEmitter = eventEmitter;
			this.aliasProvider = aliasProvider;
		}

		public override bool Enter(IObjectDescriptor value, IEmitter context)
		{
			if (value.Value != null)
			{
				string alias = aliasProvider.GetAlias(value.Value);
				if (alias != null && !emittedAliases.Add(alias))
				{
					eventEmitter.Emit(new AliasEventInfo(value, alias), context);
					return false;
				}
			}
			return base.Enter(value, context);
		}

		public override void VisitMappingStart(IObjectDescriptor mapping, Type keyType, Type valueType, IEmitter context)
		{
			string alias = aliasProvider.GetAlias(mapping.NonNullValue());
			eventEmitter.Emit(new MappingStartEventInfo(mapping)
			{
				Anchor = alias
			}, context);
		}

		public override void VisitSequenceStart(IObjectDescriptor sequence, Type elementType, IEmitter context)
		{
			string alias = aliasProvider.GetAlias(sequence.NonNullValue());
			eventEmitter.Emit(new SequenceStartEventInfo(sequence)
			{
				Anchor = alias
			}, context);
		}

		public override void VisitScalar(IObjectDescriptor scalar, IEmitter context)
		{
			ScalarEventInfo scalarEventInfo = new ScalarEventInfo(scalar);
			if (scalar.Value != null)
			{
				scalarEventInfo.Anchor = aliasProvider.GetAlias(scalar.Value);
			}
			eventEmitter.Emit(scalarEventInfo, context);
		}
	}
	public abstract class ChainedObjectGraphVisitor : IObjectGraphVisitor<IEmitter>
	{
		private readonly IObjectGraphVisitor<IEmitter> nextVisitor;

		protected ChainedObjectGraphVisitor(IObjectGraphVisitor<IEmitter> nextVisitor)
		{
			this.nextVisitor = nextVisitor;
		}

		public virtual bool Enter(IObjectDescriptor value, IEmitter context)
		{
			return nextVisitor.Enter(value, context);
		}

		public virtual bool EnterMapping(IObjectDescriptor key, IObjectDescriptor value, IEmitter context)
		{
			return nextVisitor.EnterMapping(key, value, context);
		}

		public virtual bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value, IEmitter context)
		{
			return next