Decompiled source of Real Radio v1.0.1

Mods/RealRadio/AngleSharp.dll

Decompiled a day ago
using System;
using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using AngleSharp.Attributes;
using AngleSharp.Browser;
using AngleSharp.Browser.Dom;
using AngleSharp.Browser.Dom.Events;
using AngleSharp.Common;
using AngleSharp.Css;
using AngleSharp.Css.Dom;
using AngleSharp.Css.Parser;
using AngleSharp.Dom;
using AngleSharp.Dom.Events;
using AngleSharp.Html;
using AngleSharp.Html.Construction;
using AngleSharp.Html.Dom;
using AngleSharp.Html.Dom.Events;
using AngleSharp.Html.Forms;
using AngleSharp.Html.Forms.Submitters;
using AngleSharp.Html.Forms.Submitters.Json;
using AngleSharp.Html.InputTypes;
using AngleSharp.Html.LinkRels;
using AngleSharp.Html.Parser;
using AngleSharp.Html.Parser.Tokens;
using AngleSharp.Html.Parser.Tokens.Struct;
using AngleSharp.Io;
using AngleSharp.Io.Dom;
using AngleSharp.Io.Processors;
using AngleSharp.Mathml;
using AngleSharp.Mathml.Dom;
using AngleSharp.Media;
using AngleSharp.Media.Dom;
using AngleSharp.Scripting;
using AngleSharp.Svg;
using AngleSharp.Svg.Dom;
using AngleSharp.Text;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCopyright("Copyright © AngleSharp, 2013-2024")]
[assembly: ComVisible(false)]
[assembly: InternalsVisibleTo("AngleSharp.Core.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010001adf274fa2b375134e8e4558d606f1a0f96f5cd0c6b99970f7cce9887477209d7c29f814e2508d8bd2526e99e8cd273bd1158a3984f1ea74830ec5329a77c6ff201a15edeb8b36ab046abd1bce211fe8dbb076d7d806f46b15bfda44def04ead0669971e96c5f666c9eda677f28824fff7aa90d32929ed91d529a7a41699893")]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("AngleSharp")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("AngleSharp is the ultimate angle brackets parser library. It parses HTML5, CSS3, and XML to construct a DOM based on the official W3C specification.")]
[assembly: AssemblyFileVersion("1.3.0.0")]
[assembly: AssemblyInformationalVersion("1.3.0+14968235af99415266323f8a8663af287d67459c")]
[assembly: AssemblyProduct("AngleSharp")]
[assembly: AssemblyTitle("AngleSharp")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/AngleSharp/AngleSharp")]
[assembly: AssemblyVersion("1.3.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]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[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 AngleSharp
{
	public sealed class BrowsingContext : EventTarget, IBrowsingContext, IEventTarget, IDisposable
	{
		[CompilerGenerated]
		private sealed class <GetServices>d__32<T> : IEnumerable<T>, IEnumerable, IEnumerator<T>, IEnumerator, IDisposable where T : class?
		{
			private int <>1__state;

			private T <>2__current;

			private int <>l__initialThreadId;

			public BrowsingContext <>4__this;

			private int <count>5__2;

			private int <i>5__3;

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

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

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

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

			private bool MoveNext()
			{
				int num = <>1__state;
				BrowsingContext browsingContext = <>4__this;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					goto IL_00a4;
				}
				<>1__state = -1;
				<count>5__2 = browsingContext._services.Count;
				<i>5__3 = 0;
				goto IL_00b6;
				IL_00a4:
				<i>5__3++;
				goto IL_00b6;
				IL_00b6:
				if (<i>5__3 < <count>5__2)
				{
					object obj = browsingContext._services[<i>5__3];
					T val = obj as T;
					if (val == null)
					{
						if (!(obj is Func<IBrowsingContext, T> func))
						{
							goto IL_00a4;
						}
						val = func(browsingContext);
						browsingContext._services[<i>5__3] = val;
					}
					<>2__current = val;
					<>1__state = 1;
					return true;
				}
				return false;
			}

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

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

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

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

		private readonly IEnumerable<object> _originalServices;

		private readonly List<object> _services;

		private readonly Sandboxes _security;

		private readonly IBrowsingContext? _parent;

		private readonly IDocument? _creator;

		private readonly bool _isFrameContext;

		private readonly IHistory? _history;

		private readonly Dictionary<string, WeakReference<IBrowsingContext>> _children;

		private readonly List<WeakReference<IBrowsingContext>> _contextGroup;

		public IDocument? Active { get; set; }

		public IDocument? Creator => _creator;

		public IEnumerable<object> OriginalServices => _originalServices;

		public IWindow? Current => Active?.DefaultView;

		public IBrowsingContext? Parent => _parent;

		internal bool IsFrame => _isFrameContext;

		public IHistory? SessionHistory => _history;

		public Sandboxes Security => _security;

		public BrowsingContext(IConfiguration? configuration = null)
			: this((configuration ?? Configuration.Default).Services, Sandboxes.None)
		{
		}

		private BrowsingContext(Sandboxes security)
		{
			_services = new List<object>();
			_originalServices = _services;
			_security = security;
			_children = new Dictionary<string, WeakReference<IBrowsingContext>>();
			_contextGroup = new List<WeakReference<IBrowsingContext>>();
		}

		internal BrowsingContext(IEnumerable<object> services, Sandboxes security)
			: this(security)
		{
			_services.AddRange(services);
			_originalServices = services;
			_history = GetService<IHistory>();
		}

		internal BrowsingContext(IBrowsingContext parent, Sandboxes security, bool isFrameContext)
			: this(parent.OriginalServices, security)
		{
			_parent = parent;
			_creator = _parent.Active;
			_isFrameContext = isFrameContext;
		}

		public T? GetService<T>() where T : class
		{
			int count = _services.Count;
			int num = 0;
			while (num < count)
			{
				object obj = _services[num];
				T val = obj as T;
				if (val == null)
				{
					if (!(obj is Func<IBrowsingContext, T> func))
					{
						num++;
						continue;
					}
					val = func(this);
					_services[num] = val;
				}
				return val;
			}
			return null;
		}

		[IteratorStateMachine(typeof(<GetServices>d__32<>))]
		public IEnumerable<T> GetServices<T>() where T : class
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetServices>d__32<T>(-2)
			{
				<>4__this = this
			};
		}

		public IBrowsingContext CreateChild(string? name, Sandboxes security)
		{
			return CreateChild(name, security, isFrameContext: false);
		}

		internal IBrowsingContext CreateChild(string? name, Sandboxes security, bool isFrameContext)
		{
			BrowsingContext browsingContext = new BrowsingContext(this, security, isFrameContext);
			if (!isFrameContext)
			{
				if (_contextGroup == null)
				{
					return _parent.CreateChild(name, security);
				}
				_contextGroup.Add(new WeakReference<IBrowsingContext>(browsingContext));
			}
			if (name != null && name.Length > 0)
			{
				_children[name] = new WeakReference<IBrowsingContext>(browsingContext);
			}
			return browsingContext;
		}

		public IBrowsingContext? FindChild(string name)
		{
			IBrowsingContext browsingContext = null;
			BrowsingContext browsingContext2 = this;
			IBrowsingContext browsingContext3 = null;
			while (browsingContext3 == null && browsingContext2 != null)
			{
				browsingContext3 = browsingContext2.FindChildRecursive(name, browsingContext);
				browsingContext = browsingContext2;
				browsingContext2 = browsingContext2.Parent as BrowsingContext;
			}
			if (browsingContext3 == null && browsingContext is BrowsingContext browsingContext4)
			{
				List<WeakReference<IBrowsingContext>> contextGroup = browsingContext4._contextGroup;
				if (contextGroup != null)
				{
					foreach (WeakReference<IBrowsingContext> item in contextGroup)
					{
						if (item.TryGetTarget(out var target) && target is BrowsingContext browsingContext5)
						{
							browsingContext3 = browsingContext5.FindChildRecursive(name, null);
							if (browsingContext3 != null)
							{
								return browsingContext3;
							}
						}
					}
				}
			}
			return browsingContext3;
		}

		private IBrowsingContext? FindChildRecursive(string name, IBrowsingContext? excludedContext)
		{
			IBrowsingContext target = null;
			if (!string.IsNullOrEmpty(name) && _children.TryGetValue(name, out WeakReference<IBrowsingContext> value))
			{
				value.TryGetTarget(out target);
			}
			if (target == null && Active is Document document)
			{
				foreach (BrowsingContext attachedReference in document.GetAttachedReferences<BrowsingContext>())
				{
					if (!attachedReference.Equals(excludedContext))
					{
						target = attachedReference.FindChildRecursive(name, null);
						if (target != null)
						{
							break;
						}
					}
				}
			}
			return target;
		}

		public static IBrowsingContext New(IConfiguration? configuration = null)
		{
			if (configuration == null)
			{
				configuration = Configuration.Default;
			}
			return new BrowsingContext(configuration.Services, Sandboxes.None);
		}

		public static IBrowsingContext NewFrom<TService>(TService instance)
		{
			return new BrowsingContext(Configuration.Default.WithOnly(instance).Services, Sandboxes.None);
		}

		void IDisposable.Dispose()
		{
			Active?.Dispose();
			Active = null;
		}
	}
	public static class BrowsingContextExtensions
	{
		public static Task<IDocument> OpenNewAsync(this IBrowsingContext context, string? url = null, CancellationToken cancellation = default(CancellationToken))
		{
			string url2 = url;
			return context.OpenAsync(delegate(VirtualResponse m)
			{
				m.Address(url2 ?? "http://localhost/");
			}, cancellation);
		}

		public static Task<IDocument> OpenAsync(this IBrowsingContext context, IResponse response, CancellationToken cancel = default(CancellationToken))
		{
			response = response ?? throw new ArgumentNullException("response");
			if (context == null)
			{
				context = BrowsingContext.New();
			}
			Encoding defaultEncoding = context.GetDefaultEncoding();
			IDocumentFactory factory = context.GetFactory<IDocumentFactory>();
			CreateDocumentOptions options = new CreateDocumentOptions(response, defaultEncoding);
			return factory.CreateAsync(context, options, cancel);
		}

		public static Task<IDocument> OpenAsync(this IBrowsingContext context, DocumentRequest request, CancellationToken cancel = default(CancellationToken))
		{
			request = request ?? throw new ArgumentNullException("request");
			if (context == null)
			{
				context = BrowsingContext.New();
			}
			return context.NavigateToAsync(request, cancel);
		}

		public static Task<IDocument> OpenAsync(this IBrowsingContext context, Url url, CancellationToken cancel = default(CancellationToken))
		{
			url = url ?? throw new ArgumentNullException("url");
			return context.OpenAsync(DocumentRequest.Get(url, null, context?.Active?.DocumentUri), cancel);
		}

		public static async Task<IDocument> OpenAsync(this IBrowsingContext context, Action<VirtualResponse> request, CancellationToken cancel = default(CancellationToken))
		{
			request = request ?? throw new ArgumentNullException("request");
			using IResponse response = VirtualResponse.Create(request);
			return await context.OpenAsync(response, cancel).ConfigureAwait(continueOnCapturedContext: false);
		}

		public static Task<IDocument> OpenAsync(this IBrowsingContext context, string address, CancellationToken cancellation = default(CancellationToken))
		{
			address = address ?? throw new ArgumentNullException("address");
			return context.OpenAsync(Url.Create(address), cancellation);
		}

		internal static Task<IDocument> NavigateToAsync(this IBrowsingContext context, DocumentRequest request, CancellationToken cancel = default(CancellationToken))
		{
			return context.GetNavigationHandler(request.Target)?.NavigateAsync(request, cancel) ?? Task.FromResult<IDocument>(null);
		}

		public static void NavigateTo(this IBrowsingContext context, IDocument document)
		{
			context.SessionHistory?.PushState(document, document.Title, document.Url);
			context.Active = document;
		}

		public static INavigationHandler? GetNavigationHandler(this IBrowsingContext context, Url url)
		{
			Url url2 = url;
			return context.GetServices<INavigationHandler>().FirstOrDefault((INavigationHandler m) => m.SupportsProtocol(url2.Scheme));
		}

		public static Encoding GetDefaultEncoding(this IBrowsingContext context)
		{
			IEncodingProvider? provider = context.GetProvider<IEncodingProvider>();
			string language = context.GetLanguage();
			return provider?.Suggest(language) ?? Encoding.UTF8;
		}

		public static CultureInfo GetCulture(this IBrowsingContext context)
		{
			return context.GetService<CultureInfo>() ?? CultureInfo.CurrentUICulture;
		}

		public static CultureInfo GetCultureFrom(this IBrowsingContext context, string language)
		{
			try
			{
				return new CultureInfo(language);
			}
			catch (CultureNotFoundException ex)
			{
				context.TrackError(ex);
				return context.GetCulture();
			}
		}

		public static string GetLanguage(this IBrowsingContext context)
		{
			return context.GetCulture().Name;
		}

		public static TFactory GetFactory<TFactory>(this IBrowsingContext context) where TFactory : class
		{
			return context.GetServices<TFactory>().Single();
		}

		public static TProvider? GetProvider<TProvider>(this IBrowsingContext context) where TProvider : class
		{
			return context.GetServices<TProvider>().SingleOrDefault();
		}

		public static IResourceService<TResource>? GetResourceService<TResource>(this IBrowsingContext context, string type) where TResource : IResourceInfo
		{
			foreach (IResourceService<TResource> service in context.GetServices<IResourceService<TResource>>())
			{
				if (service.SupportsType(type))
				{
					return service;
				}
			}
			return null;
		}

		public static string GetCookie(this IBrowsingContext context, Url url)
		{
			return context.GetProvider<ICookieProvider>()?.GetCookie(url) ?? string.Empty;
		}

		public static void SetCookie(this IBrowsingContext context, Url url, string value)
		{
			context.GetProvider<ICookieProvider>()?.SetCookie(url, value);
		}

		public static ISpellCheckService? GetSpellCheck(this IBrowsingContext context, string language)
		{
			ISpellCheckService spellCheckService = null;
			IEnumerable<ISpellCheckService> services = context.GetServices<ISpellCheckService>();
			CultureInfo cultureFrom = context.GetCultureFrom(language);
			string twoLetterISOLanguageName = cultureFrom.TwoLetterISOLanguageName;
			foreach (ISpellCheckService item in services)
			{
				CultureInfo culture = item.Culture;
				if (culture != null)
				{
					string twoLetterISOLanguageName2 = culture.TwoLetterISOLanguageName;
					if (culture.Equals(cultureFrom))
					{
						return item;
					}
					if (spellCheckService == null && twoLetterISOLanguageName2.Is(twoLetterISOLanguageName))
					{
						spellCheckService = item;
					}
				}
			}
			return spellCheckService;
		}

		public static IStylingService? GetCssStyling(this IBrowsingContext context)
		{
			return context.GetStyling(MimeTypeNames.Css);
		}

		public static IStylingService? GetStyling(this IBrowsingContext context, string type)
		{
			foreach (IStylingService service in context.GetServices<IStylingService>())
			{
				if (service.SupportsType(type))
				{
					return service;
				}
			}
			return null;
		}

		public static bool IsScripting(this IBrowsingContext context)
		{
			return context.GetServices<IScriptingService>().Any();
		}

		public static IScriptingService? GetJsScripting(this IBrowsingContext context)
		{
			return context.GetScripting(MimeTypeNames.DefaultJavaScript);
		}

		public static IScriptingService? GetScripting(this IBrowsingContext context, string type)
		{
			foreach (IScriptingService service in context.GetServices<IScriptingService>())
			{
				if (service.SupportsType(type))
				{
					return service;
				}
			}
			return null;
		}

		public static ICommand? GetCommand(this IBrowsingContext context, string commandId)
		{
			return context.GetProvider<ICommandProvider>()?.GetCommand(commandId);
		}

		public static void TrackError(this IBrowsingContext context, Exception ex)
		{
			AngleSharp.Browser.Dom.Events.TrackEvent eventData = new AngleSharp.Browser.Dom.Events.TrackEvent("error", ex);
			context.Fire(eventData);
		}

		public static Task InteractAsync<T>(this IBrowsingContext context, string eventName, T data)
		{
			InteractivityEvent<T> interactivityEvent = new InteractivityEvent<T>(eventName, data);
			context.Fire(interactivityEvent);
			return interactivityEvent.Result ?? Task.FromResult(result: false);
		}

		public static IBrowsingContext ResolveTargetContext(this IBrowsingContext context, string? target)
		{
			bool flag = false;
			IBrowsingContext browsingContext = context;
			if (target != null && target.Length > 0)
			{
				browsingContext = context.FindChildFor(target);
				flag = browsingContext == null;
			}
			if (flag)
			{
				browsingContext = context.CreateChildFor(target);
			}
			return browsingContext;
		}

		public static IBrowsingContext CreateChildFor(this IBrowsingContext context, string? target)
		{
			Sandboxes security = Sandboxes.None;
			if (target == "_blank")
			{
				target = null;
			}
			return context.CreateChild(target, security);
		}

		public static IBrowsingContext? FindChildFor(this IBrowsingContext context, string target)
		{
			if (!string.IsNullOrEmpty(target))
			{
				switch (target)
				{
				case "_self":
					break;
				case "_parent":
					if (context is BrowsingContext browsingContext3 && browsingContext3.IsFrame)
					{
						return context.Parent;
					}
					return context;
				case "_top":
				{
					IBrowsingContext browsingContext = context;
					while (browsingContext is BrowsingContext browsingContext2 && browsingContext2.IsFrame)
					{
						browsingContext = browsingContext.Parent;
					}
					return browsingContext;
				}
				default:
					return context.FindChild(target);
				}
			}
			return context;
		}

		public static IEnumerable<Task> GetDownloads<T>(this IBrowsingContext context) where T : INode
		{
			IResourceLoader service = context.GetService<IResourceLoader>();
			if (service == null)
			{
				return Array.Empty<Task>();
			}
			return from m in service.GetDownloads()
				where m.Source is T
				select m.Task;
		}
	}
	public class Configuration : IConfiguration
	{
		private readonly IEnumerable<object> _services;

		public static IConfiguration Default => new Configuration();

		public IEnumerable<object> Services => _services;

		private static T Instance<T>(T instance)
		{
			return instance;
		}

		private static Func<IBrowsingContext, T> Creator<T>(Func<IBrowsingContext, T> creator)
		{
			return creator;
		}

		public Configuration(IEnumerable<object>? services = null)
		{
			_services = services ?? new object[17]
			{
				Instance((IElementFactory<Document, HtmlElement>)new HtmlElementFactory()),
				Instance((IElementFactory<Document, MathElement>)new MathElementFactory()),
				Instance((IElementFactory<Document, SvgElement>)new SvgElementFactory()),
				Instance((IEventFactory)new DefaultEventFactory()),
				Instance((IInputTypeFactory)new DefaultInputTypeFactory()),
				Instance((IAttributeSelectorFactory)new DefaultAttributeSelectorFactory()),
				Instance((IPseudoElementSelectorFactory)new DefaultPseudoElementSelectorFactory()),
				Instance((IPseudoClassSelectorFactory)new DefaultPseudoClassSelectorFactory()),
				Instance((ILinkRelationFactory)new DefaultLinkRelationFactory()),
				Instance((IDocumentFactory)new DefaultDocumentFactory()),
				Instance((IAttributeObserver)new DefaultAttributeObserver()),
				Instance((IMetaHandler)new EncodingMetaHandler()),
				Instance((IHtmlEncoder)new DefaultHtmlEncoder()),
				Creator((Func<IBrowsingContext, ICssSelectorParser>)((IBrowsingContext ctx) => new CssSelectorParser(ctx))),
				Creator((Func<IBrowsingContext, IHtmlParser>)((IBrowsingContext ctx) => new HtmlParser(ctx))),
				Creator((Func<IBrowsingContext, INavigationHandler>)((IBrowsingContext ctx) => new DefaultNavigationHandler(ctx))),
				Creator((Func<IBrowsingContext, IHtmlElementConstructionFactory>)((IBrowsingContext ctx) => new HtmlDomConstructionFactory(ctx)))
			};
		}
	}
	public static class ConfigurationExtensions
	{
		public static IConfiguration With(this IConfiguration configuration, object service)
		{
			configuration = configuration ?? throw new ArgumentNullException("configuration");
			service = service ?? throw new ArgumentNullException("service");
			return new Configuration(configuration.Services.Concat(service));
		}

		public static IConfiguration WithOnly<TService>(this IConfiguration configuration, TService service)
		{
			if (service == null)
			{
				throw new ArgumentNullException("service");
			}
			return configuration.Without<TService>().With(service);
		}

		public static IConfiguration WithOnly<TService>(this IConfiguration configuration, Func<IBrowsingContext, TService> creator)
		{
			creator = creator ?? throw new ArgumentNullException("creator");
			return configuration.Without<TService>().With(creator);
		}

		public static IConfiguration Without(this IConfiguration configuration, object service)
		{
			configuration = configuration ?? throw new ArgumentNullException("configuration");
			service = service ?? throw new ArgumentNullException("service");
			return new Configuration(configuration.Services.Except(service));
		}

		public static IConfiguration With(this IConfiguration configuration, IEnumerable<object> services)
		{
			configuration = configuration ?? throw new ArgumentNullException("configuration");
			services = services ?? throw new ArgumentNullException("services");
			return new Configuration(services.Concat(configuration.Services));
		}

		public static IConfiguration Without(this IConfiguration configuration, IEnumerable<object> services)
		{
			configuration = configuration ?? throw new ArgumentNullException("configuration");
			services = services ?? throw new ArgumentNullException("services");
			return new Configuration(configuration.Services.Except(services));
		}

		public static IConfiguration With<TService>(this IConfiguration configuration, Func<IBrowsingContext, TService> creator)
		{
			creator = creator ?? throw new ArgumentNullException("creator");
			return configuration.With((object)creator);
		}

		public static IConfiguration Without<TService>(this IConfiguration configuration)
		{
			configuration = configuration ?? throw new ArgumentNullException("configuration");
			IEnumerable<object> services = configuration.Services.OfType<TService>().Cast<object>();
			IEnumerable<Func<IBrowsingContext, TService>> services2 = configuration.Services.OfType<Func<IBrowsingContext, TService>>();
			return configuration.Without(services).Without(services2);
		}

		public static bool Has<TService>(this IConfiguration configuration)
		{
			configuration = configuration ?? throw new ArgumentNullException("configuration");
			if (!configuration.Services.OfType<TService>().Any())
			{
				return configuration.Services.OfType<Func<IBrowsingContext, TService>>().Any();
			}
			return true;
		}

		public static IConfiguration WithDefaultLoader(this IConfiguration configuration, LoaderOptions? setup = null)
		{
			LoaderOptions config = setup ?? new LoaderOptions();
			if (!configuration.Has<IRequester>())
			{
				configuration = configuration.With(new DefaultHttpRequester());
			}
			if (!config.IsNavigationDisabled)
			{
				configuration = configuration.With((Func<IBrowsingContext, IDocumentLoader>)((IBrowsingContext ctx) => new DefaultDocumentLoader(ctx, config.Filter)));
			}
			if (config.IsResourceLoadingEnabled)
			{
				configuration = configuration.With((Func<IBrowsingContext, IResourceLoader>)((IBrowsingContext ctx) => new DefaultResourceLoader(ctx, config.Filter)));
			}
			return configuration;
		}

		public static IConfiguration WithCulture(this IConfiguration configuration, string name)
		{
			CultureInfo culture = new CultureInfo(name);
			return configuration.WithCulture(culture);
		}

		public static IConfiguration WithCulture(this IConfiguration configuration, CultureInfo culture)
		{
			return configuration.With(culture);
		}

		public static IConfiguration WithMetaRefresh(this IConfiguration configuration, Predicate<Url>? shouldRefresh = null)
		{
			RefreshMetaHandler service = new RefreshMetaHandler(shouldRefresh);
			return configuration.With(service);
		}

		public static IConfiguration WithLocaleBasedEncoding(this IConfiguration configuration)
		{
			LocaleEncodingProvider service = new LocaleEncodingProvider();
			return configuration.With(service);
		}

		public static IConfiguration WithDefaultCookies(this IConfiguration configuration)
		{
			MemoryCookieProvider service = new MemoryCookieProvider();
			return configuration.With(service);
		}
	}
	public static class FormatExtensions
	{
		public static string ToCss(this IStyleFormattable style)
		{
			return style.ToCss(CssStyleFormatter.Instance);
		}

		public static string ToCss(this IStyleFormattable style, IStyleFormatter formatter)
		{
			StringBuilder sb = StringBuilderPool.Obtain();
			using (StringWriter writer = new StringWriter(sb))
			{
				style.ToCss(writer, formatter);
			}
			return sb.ToPool();
		}

		public static void ToCss(this IStyleFormattable style, TextWriter writer)
		{
			style.ToCss(writer, CssStyleFormatter.Instance);
		}

		public static Task ToCssAsync(this IStyleFormattable style, TextWriter writer)
		{
			return writer.WriteAsync(style.ToCss());
		}

		public static async Task ToCssAsync(this IStyleFormattable style, Stream stream)
		{
			using StreamWriter writer = new StreamWriter(stream);
			await style.ToCssAsync(writer).ConfigureAwait(continueOnCapturedContext: false);
		}

		public static string ToHtml(this IMarkupFormattable markup)
		{
			return markup.ToHtml(HtmlMarkupFormatter.Instance);
		}

		public static string ToHtml(this IMarkupFormattable markup, IMarkupFormatter formatter)
		{
			StringBuilder sb = StringBuilderPool.Obtain();
			using (StringWriter writer = new StringWriter(sb))
			{
				markup.ToHtml(writer, formatter);
			}
			return sb.ToPool();
		}

		public static void ToHtml(this IMarkupFormattable markup, TextWriter writer)
		{
			markup.ToHtml(writer, HtmlMarkupFormatter.Instance);
		}

		public static string Minify(this IMarkupFormattable markup)
		{
			return markup.ToHtml(new MinifyMarkupFormatter());
		}

		public static string Prettify(this IMarkupFormattable markup)
		{
			return markup.ToHtml(new PrettyMarkupFormatter());
		}

		public static Task ToHtmlAsync(this IMarkupFormattable markup, TextWriter writer)
		{
			return writer.WriteAsync(markup.ToHtml());
		}

		public static async Task ToHtmlAsync(this IMarkupFormattable markup, Stream stream)
		{
			using StreamWriter writer = new StreamWriter(stream);
			await markup.ToHtmlAsync(writer).ConfigureAwait(continueOnCapturedContext: false);
		}
	}
	public interface IBrowsingContext : IEventTarget, IDisposable
	{
		IWindow? Current { get; }

		IDocument? Active { get; set; }

		IHistory? SessionHistory { get; }

		Sandboxes Security { get; }

		IBrowsingContext? Parent { get; }

		IDocument? Creator { get; }

		IEnumerable<object> OriginalServices { get; }

		T? GetService<T>() where T : class;

		IEnumerable<T> GetServices<T>() where T : class;

		IBrowsingContext CreateChild(string? name, Sandboxes security);

		IBrowsingContext? FindChild(string name);
	}
	public interface IConfiguration
	{
		IEnumerable<object> Services { get; }
	}
	public interface IMarkupFormattable
	{
		void ToHtml(TextWriter writer, IMarkupFormatter formatter);
	}
	public interface IMarkupFormatter
	{
		string Text(ICharacterData text);

		string LiteralText(ICharacterData text);

		string Comment(IComment comment);

		string Processing(IProcessingInstruction processing);

		string Doctype(IDocumentType doctype);

		string OpenTag(IElement element, bool selfClosing);

		string CloseTag(IElement element, bool selfClosing);
	}
	public interface IStyleFormattable
	{
		void ToCss(TextWriter writer, IStyleFormatter formatter);
	}
	public interface IStyleFormatter
	{
		string Sheet(IEnumerable<IStyleFormattable> rules);

		string Declaration(string name, string value, bool important);

		string BlockDeclarations(IEnumerable<IStyleFormattable> declarations);

		string Rule(string name, string value);

		string Rule(string name, string prelude, string rules);

		string BlockRules(IEnumerable<IStyleFormattable> rules);

		string Comment(string data);
	}
}
namespace AngleSharp.Xhtml
{
	public class XhtmlMarkupFormatter : IMarkupFormatter
	{
		public static readonly IMarkupFormatter Instance = new XhtmlMarkupFormatter();

		private readonly bool _emptyTagsToSelfClosing;

		public bool IsSelfClosingEmptyTags => _emptyTagsToSelfClosing;

		public XhtmlMarkupFormatter()
			: this(emptyTagsToSelfClosing: true)
		{
		}

		public XhtmlMarkupFormatter(bool emptyTagsToSelfClosing)
		{
			_emptyTagsToSelfClosing = emptyTagsToSelfClosing;
		}

		public virtual string CloseTag(IElement element, bool selfClosing)
		{
			string prefix = element.Prefix;
			string localName = element.LocalName;
			string text = ((!string.IsNullOrEmpty(prefix)) ? (prefix + ":" + localName) : localName);
			if (!selfClosing && (!_emptyTagsToSelfClosing || element.HasChildNodes))
			{
				return "</" + text + ">";
			}
			return string.Empty;
		}

		public virtual string Comment(IComment comment)
		{
			return "<!--" + comment.Data + "-->";
		}

		public virtual string Doctype(IDocumentType doctype)
		{
			string publicIdentifier = doctype.PublicIdentifier;
			string systemIdentifier = doctype.SystemIdentifier;
			string text = ((string.IsNullOrEmpty(publicIdentifier) && string.IsNullOrEmpty(systemIdentifier)) ? string.Empty : (" " + (string.IsNullOrEmpty(publicIdentifier) ? ("SYSTEM \"" + systemIdentifier + "\"") : ("PUBLIC \"" + publicIdentifier + "\" \"" + systemIdentifier + "\""))));
			return "<!DOCTYPE " + doctype.Name + text + ">";
		}

		public virtual string OpenTag(IElement element, bool selfClosing)
		{
			string prefix = element.Prefix;
			StringBuilder stringBuilder = StringBuilderPool.Obtain();
			stringBuilder.Append('<');
			if (!string.IsNullOrEmpty(prefix))
			{
				stringBuilder.Append(prefix).Append(':');
			}
			stringBuilder.Append(element.LocalName);
			foreach (IAttr attribute in element.Attributes)
			{
				stringBuilder.Append(' ').Append(Attribute(attribute));
			}
			if (selfClosing || (_emptyTagsToSelfClosing && !element.HasChildNodes))
			{
				stringBuilder.Append(" /");
			}
			stringBuilder.Append('>');
			return stringBuilder.ToPool();
		}

		public virtual string Processing(IProcessingInstruction processing)
		{
			string text = processing.Target + " " + processing.Data;
			return "<?" + text + "?>";
		}

		public virtual string LiteralText(ICharacterData text)
		{
			return text.Data;
		}

		public virtual string Text(ICharacterData text)
		{
			return EscapeText(text.Data);
		}

		protected virtual string Attribute(IAttr attribute)
		{
			string namespaceUri = attribute.NamespaceUri;
			string localName = attribute.LocalName;
			string value = attribute.Value;
			StringBuilder stringBuilder = StringBuilderPool.Obtain();
			if (string.IsNullOrEmpty(namespaceUri))
			{
				stringBuilder.Append(localName);
			}
			else if (namespaceUri.Is(NamespaceNames.XmlUri))
			{
				stringBuilder.Append(NamespaceNames.XmlPrefix).Append(':').Append(localName);
			}
			else if (namespaceUri.Is(NamespaceNames.XLinkUri))
			{
				stringBuilder.Append(NamespaceNames.XLinkPrefix).Append(':').Append(localName);
			}
			else if (namespaceUri.Is(NamespaceNames.XmlNsUri))
			{
				stringBuilder.Append(XmlNamespaceLocalName(localName));
			}
			else
			{
				stringBuilder.Append(attribute.Name);
			}
			stringBuilder.Append('=').Append('"');
			for (int i = 0; i < value.Length; i++)
			{
				switch (value[i])
				{
				case '&':
					stringBuilder.Append("&amp;");
					break;
				case '\u00a0':
					stringBuilder.Append("&#160;");
					break;
				case '<':
					stringBuilder.Append("&lt;");
					break;
				case '"':
					stringBuilder.Append("&quot;");
					break;
				default:
					stringBuilder.Append(value[i]);
					break;
				}
			}
			return stringBuilder.Append('"').ToPool();
		}

		public static string EscapeText(string content)
		{
			StringBuilder stringBuilder = StringBuilderPool.Obtain();
			for (int i = 0; i < content.Length; i++)
			{
				switch (content[i])
				{
				case '&':
					stringBuilder.Append("&amp;");
					break;
				case '\u00a0':
					stringBuilder.Append("&#160;");
					break;
				case '>':
					stringBuilder.Append("&gt;");
					break;
				case '<':
					stringBuilder.Append("&lt;");
					break;
				default:
					stringBuilder.Append(content[i]);
					break;
				}
			}
			return stringBuilder.ToPool();
		}

		public static string XmlNamespaceLocalName(string localName)
		{
			if (localName.Is(NamespaceNames.XmlNsPrefix))
			{
				return localName;
			}
			return NamespaceNames.XmlNsPrefix + ':' + localName;
		}
	}
}
namespace AngleSharp.Text
{
	public sealed class CharArrayTextSource : IReadOnlyTextSource, IDisposable
	{
		private int _index;

		private string? _content;

		private readonly char[] _array;

		private readonly ReadOnlyMemory<char> _memory;

		private readonly int _length;

		public string Text => _content ?? (_content = new string(_array, 0, _length));

		public char this[int index] => _array[index];

		public int Length => _length;

		public Encoding CurrentEncoding
		{
			get
			{
				return TextEncoding.Utf8;
			}
			set
			{
			}
		}

		public int Index
		{
			get
			{
				return _index;
			}
			set
			{
				_index = value;
			}
		}

		public CharArrayTextSource(char[] array, int length)
		{
			_array = array;
			_length = length;
			_memory = array.AsMemory(0, length);
		}

		public void Dispose()
		{
		}

		public char ReadCharacter()
		{
			if (_index < _length)
			{
				return _array[_index++];
			}
			_index++;
			return '\uffff';
		}

		public string ReadCharacters(int characters)
		{
			return ReadMemory(characters).ToString();
		}

		public StringOrMemory ReadMemory(int characters)
		{
			int index = _index;
			if (index + characters <= _length)
			{
				_index += characters;
				return _memory.Slice(index, characters);
			}
			_index += characters;
			characters = Math.Min(characters, _length - index);
			return _memory.Slice(index, characters);
		}

		public Task PrefetchAsync(int length, CancellationToken cancellationToken)
		{
			return Task.CompletedTask;
		}

		public Task PrefetchAllAsync(CancellationToken cancellationToken)
		{
			return Task.CompletedTask;
		}

		public bool TryGetContentLength(out int length)
		{
			length = _length;
			return true;
		}
	}
	public static class CharExtensions
	{
		public static int FromHex(this char c)
		{
			if (!c.IsDigit())
			{
				return c - (c.IsLowercaseAscii() ? 87 : 55);
			}
			return c - 48;
		}

		public static string ToHex(this byte num)
		{
			Span<char> span = stackalloc char[2];
			int num2 = num >> 4;
			span[0] = (char)(num2 + ((num2 < 10) ? 48 : 55));
			num2 = num - 16 * num2;
			span[1] = (char)(num2 + ((num2 < 10) ? 48 : 55));
			return span.ToString();
		}

		public static string ToHex(this char character)
		{
			int num = character;
			return num.ToString("x");
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsInRange(this char c, int lower, int upper)
		{
			if (c >= lower)
			{
				return c <= upper;
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsNormalQueryCharacter(this char c)
		{
			if (c.IsInRange(33, 126) && c != '"' && c != '`' && c != '#' && c != '<')
			{
				return c != '>';
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsNormalPathCharacter(this char c)
		{
			if (c.IsInRange(32, 126) && c != '"' && c != '`' && c != '#' && c != '<' && c != '>' && c != ' ')
			{
				return c != '?';
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsUppercaseAscii(this char c)
		{
			if (c >= 'A')
			{
				return c <= 'Z';
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsLowercaseAscii(this char c)
		{
			if (c >= 'a')
			{
				return c <= 'z';
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsAlphanumericAscii(this char c)
		{
			if (!c.IsDigit() && !c.IsUppercaseAscii())
			{
				return c.IsLowercaseAscii();
			}
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsHex(this char c)
		{
			if (!c.IsDigit() && (c < 'A' || c > 'F'))
			{
				if (c >= 'a')
				{
					return c <= 'f';
				}
				return false;
			}
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsNonAscii(this char c)
		{
			if (c != '\uffff')
			{
				return c >= '\u0080';
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsNonPrintable(this char c)
		{
			if ((c < '\0' || c > '\b') && (c < '\u000e' || c > '\u001f'))
			{
				if (c >= '\u007f')
				{
					return c <= '\u009f';
				}
				return false;
			}
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsLetter(this char c)
		{
			if (!c.IsUppercaseAscii())
			{
				return c.IsLowercaseAscii();
			}
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsName(this char c)
		{
			if (!c.IsNonAscii() && !c.IsLetter() && c != '_' && c != '-')
			{
				return c.IsDigit();
			}
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsCustomElementName(this char c)
		{
			if (c != '_' && c != '-' && c != '.' && !c.IsDigit() && !c.IsLowercaseAscii() && c != '·' && !c.IsInRange(192, 214) && !c.IsInRange(216, 246) && !c.IsInRange(248, 893) && !c.IsInRange(895, 8191) && !c.IsInRange(8204, 8205) && !c.IsInRange(8255, 8256) && !c.IsInRange(8304, 8591) && !c.IsInRange(11264, 12271) && !c.IsInRange(12289, 55295) && !c.IsInRange(63744, 64975) && !c.IsInRange(65008, 65533))
			{
				return c.IsInRange(65536, 2031615);
			}
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsNameStart(this char c)
		{
			if (!c.IsNonAscii() && !c.IsUppercaseAscii() && !c.IsLowercaseAscii())
			{
				return c == '_';
			}
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsLineBreak(this char c)
		{
			if (c != '\n')
			{
				return c == '\r';
			}
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsSpaceCharacter(this char c)
		{
			if (c != ' ' && c != '\t' && c != '\n' && c != '\r')
			{
				return c == '\f';
			}
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsWhiteSpaceCharacter(this char c)
		{
			if (!c.IsInRange(9, 13) && c != ' ' && c != '\u0085' && c != '\u00a0' && c != '\u1680' && c != '\u180e' && !c.IsInRange(8192, 8202) && c != '\u2028' && c != '\u2029' && c != '\u202f' && c != '\u205f')
			{
				return c == '\u3000';
			}
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsDigit(this char c)
		{
			if (c >= '0')
			{
				return c <= '9';
			}
			return false;
		}

		public static bool IsUrlCodePoint(this char c)
		{
			if (!c.IsAlphanumericAscii() && c != '!' && c != '$' && c != '&' && c != '\'' && c != '(' && c != ')' && c != '*' && c != '+' && c != '-' && c != ',' && c != '.' && c != '/' && c != ':' && c != ';' && c != '=' && c != '?' && c != '@' && c != '_' && c != '~' && !c.IsInRange(160, 55295) && !c.IsInRange(57344, 64975) && !c.IsInRange(65008, 65533) && !c.IsInRange(65536, 131069) && !c.IsInRange(131072, 196605) && !c.IsInRange(196608, 262141) && !c.IsInRange(262144, 327677) && !c.IsInRange(327680, 393213) && !c.IsInRange(393216, 458749) && !c.IsInRange(458752, 524285) && !c.IsInRange(524288, 589821) && !c.IsInRange(589824, 655357) && !c.IsInRange(655360, 720893) && !c.IsInRange(720896, 786429) && !c.IsInRange(786432, 851965) && !c.IsInRange(851968, 917501) && !c.IsInRange(917504, 983037) && !c.IsInRange(983040, 1048573))
			{
				return c.IsInRange(1048576, 1114109);
			}
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsInvalid(this int c)
		{
			if (c != 0 && c <= 1114111)
			{
				if (c > 55296)
				{
					return c < 57343;
				}
				return false;
			}
			return true;
		}
	}
	public interface ITextSource : IReadOnlyTextSource, IDisposable
	{
		void InsertText(string content);
	}
	public interface IReadOnlyTextSource : IDisposable
	{
		string Text { get; }

		int Length { get; }

		Encoding CurrentEncoding { get; set; }

		int Index { get; set; }

		char this[int index] { get; }

		char ReadCharacter();

		string ReadCharacters(int characters);

		StringOrMemory ReadMemory(int characters);

		Task PrefetchAsync(int length, CancellationToken cancellationToken);

		Task PrefetchAllAsync(CancellationToken cancellationToken);

		bool TryGetContentLength(out int length);
	}
	public static class Punycode
	{
		private const int PunycodeBase = 36;

		private const int Tmin = 1;

		private const int Tmax = 26;

		private static readonly string acePrefix = "xn--";

		private static readonly char[] possibleDots = new char[4] { '.', '。', '.', '。' };

		public static IDictionary<char, char> Symbols = new Dictionary<char, char>
		{
			{ '。', '.' },
			{ '.', '.' },
			{ 'G', 'g' },
			{ 'o', 'o' },
			{ 'c', 'c' },
			{ 'X', 'x' },
			{ '0', '0' },
			{ '1', '1' },
			{ '2', '2' },
			{ '5', '5' },
			{ '⁰', '0' },
			{ '¹', '1' },
			{ '²', '2' },
			{ '³', '3' },
			{ '⁴', '4' },
			{ '⁵', '5' },
			{ '⁶', '6' },
			{ '⁷', '7' },
			{ '⁸', '8' },
			{ '⁹', '9' },
			{ '₀', '0' },
			{ '₁', '1' },
			{ '₂', '2' },
			{ '₃', '3' },
			{ '₄', '4' },
			{ '₅', '5' },
			{ '₆', '6' },
			{ '₇', '7' },
			{ '₈', '8' },
			{ '₉', '9' },
			{ 'ᵃ', 'a' },
			{ 'ᵇ', 'b' },
			{ 'ᶜ', 'c' },
			{ 'ᵈ', 'd' },
			{ 'ᵉ', 'e' },
			{ 'ᶠ', 'f' },
			{ 'ᵍ', 'g' },
			{ 'ʰ', 'h' },
			{ 'ⁱ', 'i' },
			{ 'ʲ', 'j' },
			{ 'ᵏ', 'k' },
			{ 'ˡ', 'l' },
			{ 'ᵐ', 'm' },
			{ 'ⁿ', 'n' },
			{ 'ᵒ', 'o' },
			{ 'ᵖ', 'p' },
			{ 'ʳ', 'r' },
			{ 'ˢ', 's' },
			{ 'ᵗ', 't' },
			{ 'ᵘ', 'u' },
			{ 'ᵛ', 'v' },
			{ 'ʷ', 'w' },
			{ 'ˣ', 'x' },
			{ 'ʸ', 'y' },
			{ 'ᶻ', 'z' },
			{ 'ᴬ', 'A' },
			{ 'ᴮ', 'B' },
			{ 'ᴰ', 'D' },
			{ 'ᴱ', 'E' },
			{ 'ᴳ', 'G' },
			{ 'ᴴ', 'H' },
			{ 'ᴵ', 'I' },
			{ 'ᴶ', 'J' },
			{ 'ᴷ', 'K' },
			{ 'ᴸ', 'L' },
			{ 'ᴹ', 'M' },
			{ 'ᴺ', 'N' },
			{ 'ᴼ', 'O' },
			{ 'ᴾ', 'P' },
			{ 'ᴿ', 'R' },
			{ 'ᵀ', 'T' },
			{ 'ᵁ', 'U' },
			{ 'ⱽ', 'V' },
			{ 'ᵂ', 'W' }
		};

		public static string Encode(string text)
		{
			if (text.Length == 0)
			{
				return text;
			}
			StringBuilder stringBuilder = new StringBuilder(text.Length);
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			while (num < text.Length)
			{
				num = text.IndexOfAny(possibleDots, num2);
				if (num < 0)
				{
					num = text.Length;
				}
				if (num == num2)
				{
					break;
				}
				stringBuilder.Append(acePrefix);
				int num4 = 0;
				int num5 = 0;
				for (num4 = num2; num4 < num; num4++)
				{
					if (text[num4] < '\u0080')
					{
						stringBuilder.Append(EncodeBasic(text[num4]));
						num5++;
					}
					else if (char.IsSurrogatePair(text, num4))
					{
						num4++;
					}
				}
				int num6 = num5;
				if (num6 == num - num2)
				{
					stringBuilder.Remove(num3, acePrefix.Length);
				}
				else
				{
					if (text.Length - num2 >= acePrefix.Length && text.Substring(num2, acePrefix.Length).Isi(acePrefix))
					{
						break;
					}
					int num7 = 0;
					if (num6 > 0)
					{
						stringBuilder.Append('-');
					}
					int num8 = 128;
					int num9 = 0;
					int num10 = 72;
					while (num5 < num - num2)
					{
						int num11 = 0;
						int num12 = 0;
						int num13 = 0;
						num12 = 134217727;
						for (num11 = num2; num11 < num; num11 += ((!IsSupplementary(num13)) ? 1 : 2))
						{
							num13 = char.ConvertToUtf32(text, num11);
							if (num13 >= num8 && num13 < num12)
							{
								num12 = num13;
							}
						}
						num9 += (num12 - num8) * (num5 - num7 + 1);
						num8 = num12;
						for (num11 = num2; num11 < num; num11 += ((!IsSupplementary(num13)) ? 1 : 2))
						{
							num13 = char.ConvertToUtf32(text, num11);
							if (num13 < num8)
							{
								num9++;
							}
							else
							{
								if (num13 != num8)
								{
									continue;
								}
								int num14 = num9;
								int num15 = 36;
								while (true)
								{
									int num16 = ((num15 <= num10) ? 1 : ((num15 >= num10 + 26) ? 26 : (num15 - num10)));
									if (num14 < num16)
									{
										break;
									}
									stringBuilder.Append(EncodeDigit(num16 + (num14 - num16) % (36 - num16)));
									num14 = (num14 - num16) / (36 - num16);
									num15 += 36;
								}
								stringBuilder.Append(EncodeDigit(num14));
								num10 = AdaptChar(num9, num5 - num7 + 1, num5 == num6);
								num9 = 0;
								num5++;
								if (IsSupplementary(num12))
								{
									num5++;
									num7++;
								}
							}
						}
						num9++;
						num8++;
					}
				}
				if (stringBuilder.Length - num3 > 63)
				{
					throw new ArgumentException();
				}
				if (num != text.Length)
				{
					stringBuilder.Append(possibleDots[0]);
				}
				num2 = num + 1;
				num3 = stringBuilder.Length;
			}
			int num17 = ((!IsDot(text[text.Length - 1])) ? 1 : 0);
			int num18 = 255 - num17;
			if (stringBuilder.Length > num18)
			{
				stringBuilder.Remove(num18, stringBuilder.Length - num18);
			}
			return stringBuilder.ToString();
		}

		private static bool IsSupplementary(int test)
		{
			return test >= 65536;
		}

		private static bool IsDot(char c)
		{
			for (int i = 0; i < possibleDots.Length; i++)
			{
				if (possibleDots[i] == c)
				{
					return true;
				}
			}
			return false;
		}

		private static char EncodeDigit(int digit)
		{
			if (digit > 25)
			{
				return (char)(digit + 22);
			}
			return (char)(digit + 97);
		}

		private static char EncodeBasic(char character)
		{
			if (char.IsUpper(character))
			{
				character = (char)(character + 32);
			}
			return character;
		}

		private static int AdaptChar(int delta, int numPoints, bool firstTime)
		{
			uint num = 0u;
			delta = (firstTime ? (delta / 700) : (delta / 2));
			delta += delta / numPoints;
			num = 0u;
			while (delta > 455)
			{
				delta /= 35;
				num += 36;
			}
			return (int)(num + 36 * delta / (delta + 38));
		}
	}
	public sealed class ReadOnlyMemoryTextSource : IReadOnlyTextSource, IDisposable
	{
		private int _index;

		private string? _content;

		private readonly ReadOnlyMemory<char> _memory;

		private readonly int _length;

		public string Text => _content ?? (_content = _memory.Span.ToString());

		public char this[int index]
		{
			get
			{
				if (_content == null)
				{
					return _memory.Span[index];
				}
				return _content[index];
			}
		}

		public int Length => _length;

		public Encoding CurrentEncoding
		{
			get
			{
				return TextEncoding.Utf8;
			}
			set
			{
			}
		}

		public int Index
		{
			get
			{
				return _index;
			}
			set
			{
				_index = value;
			}
		}

		public ReadOnlyMemoryTextSource(ReadOnlyMemory<char> memory)
		{
			_memory = memory;
			_length = memory.Length;
		}

		public ReadOnlyMemoryTextSource(string str)
		{
			_content = str;
			_memory = str.AsMemory();
			_length = _memory.Length;
		}

		public void Dispose()
		{
		}

		public char ReadCharacter()
		{
			if (_index < _length)
			{
				return _memory.Span[_index++];
			}
			_index++;
			return '\uffff';
		}

		public string ReadCharacters(int characters)
		{
			return ReadMemory(characters).ToString();
		}

		public StringOrMemory ReadMemory(int characters)
		{
			int index = _index;
			if (index + characters <= _length)
			{
				_index += characters;
				return _memory.Slice(index, characters);
			}
			_index += characters;
			characters = Math.Min(characters, _length - index);
			return _memory.Slice(index, characters);
		}

		public Task PrefetchAsync(int length, CancellationToken cancellationToken)
		{
			return Task.CompletedTask;
		}

		public Task PrefetchAllAsync(CancellationToken cancellationToken)
		{
			return Task.CompletedTask;
		}

		public bool TryGetContentLength(out int length)
		{
			length = _length;
			return true;
		}
	}
	public static class StringBuilderPool
	{
		private static readonly Stack<StringBuilder> _builder = new Stack<StringBuilder>();

		private static readonly object _lock = new object();

		private static int _count = 4;

		private static int _limit = 85000;

		private static bool _isPoolingDisabled = false;

		private const int _defaultStringBuilderSize = 1024;

		public static bool IsPoolingDisabled
		{
			get
			{
				return _isPoolingDisabled;
			}
			set
			{
				_isPoolingDisabled = value;
			}
		}

		public static int MaxCount
		{
			get
			{
				return _count;
			}
			set
			{
				_count = Math.Max(1, value);
			}
		}

		public static int SizeLimit
		{
			get
			{
				return _limit;
			}
			set
			{
				_limit = Math.Max(1024, value);
			}
		}

		public static StringBuilder Obtain()
		{
			if (_isPoolingDisabled)
			{
				return CreateStringBuilder();
			}
			lock (_lock)
			{
				if (_builder.Count == 0)
				{
					return CreateStringBuilder();
				}
				return _builder.Pop().Clear();
			}
		}

		public static string ToPool(this StringBuilder sb)
		{
			string result = sb.ToString();
			sb.ReturnToPool();
			return result;
		}

		internal static StringBuilder CreateStringBuilder()
		{
			return new StringBuilder(1024);
		}

		internal static void ReturnToPool(this StringBuilder sb)
		{
			if (_isPoolingDisabled)
			{
				return;
			}
			lock (_lock)
			{
				int count = _builder.Count;
				if (sb.Capacity <= _limit)
				{
					if (count == _count)
					{
						DropMinimum(sb);
					}
					else if (count < Math.Min(2, _count) || _builder.Peek().Capacity < sb.Capacity)
					{
						_builder.Push(sb);
					}
				}
			}
		}

		private static void DropMinimum(StringBuilder sb)
		{
			int capacity = sb.Capacity;
			StringBuilder[] instances = _builder.ToArray();
			int num = FindIndex(instances, capacity);
			if (num > -1)
			{
				RebuildPool(sb, instances, num);
			}
		}

		private static void RebuildPool(StringBuilder sb, StringBuilder[] instances, int index)
		{
			_builder.Clear();
			int num = instances.Length - 1;
			while (num > index)
			{
				_builder.Push(instances[num--]);
			}
			while (num > 0)
			{
				_builder.Push(instances[--num]);
			}
			_builder.Push(sb);
		}

		private static int FindIndex(StringBuilder[] instances, int minimum)
		{
			int result = -1;
			for (int i = 0; i < instances.Length; i++)
			{
				int capacity = instances[i].Capacity;
				if (capacity < minimum)
				{
					minimum = capacity;
					result = i;
				}
			}
			return result;
		}
	}
	public static class StringExtensions
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool Has([NotNullWhen(true)] this string? value, char chr, int index = 0)
		{
			if (value != null && value.Length > index)
			{
				return value[index] == chr;
			}
			return false;
		}

		internal static string GetCompatiblity(this QuirksMode mode)
		{
			string result = "CSS1Compat";
			string text = mode.ToString();
			if (text != null)
			{
				FieldInfo field = typeof(QuirksMode).GetField(text);
				if (field != null)
				{
					DomDescriptionAttribute customAttribute = field.GetCustomAttribute<DomDescriptionAttribute>();
					if (customAttribute != null)
					{
						result = customAttribute.Description;
					}
				}
			}
			return result;
		}

		public static StringOrMemory HtmlLower(this StringOrMemory value)
		{
			int length = value.Length;
			for (int j = 0; j < length; j++)
			{
				if (value[j].IsUppercaseAscii())
				{
					if (length < 128)
					{
						Span<char> result2 = stackalloc char[length];
						return Slow(value, j, result2);
					}
					char[] array = ArrayPool<char>.Shared.Rent(length);
					Span<char> result3 = array.AsSpan(0, length);
					string text = Slow(value, j, result3);
					ArrayPool<char>.Shared.Return(array);
					return text;
				}
			}
			return value;
			static string Slow(StringOrMemory value, int i, Span<char> result)
			{
				for (int k = 0; k < i; k++)
				{
					result[k] = value[k];
				}
				char c = value[i];
				result[i] = char.ToLowerInvariant(c);
				for (int l = i + 1; l < value.Length; l++)
				{
					c = value[l];
					if (c.IsUppercaseAscii())
					{
						c = char.ToLowerInvariant(c);
					}
					result[l] = c;
				}
				return result.ToString();
			}
		}

		public static string HtmlLower(this string value)
		{
			return new StringOrMemory(value).HtmlLower().ToString();
		}

		public static Sandboxes ParseSecuritySettings(this string value, bool allowFullscreen = false)
		{
			string[] list = value.SplitSpaces();
			Sandboxes sandboxes = Sandboxes.Navigation | Sandboxes.Plugins | Sandboxes.DocumentDomain;
			if (!list.Contains("allow-popups", StringComparison.OrdinalIgnoreCase))
			{
				sandboxes |= Sandboxes.AuxiliaryNavigation;
			}
			if (!list.Contains("allow-top-navigation", StringComparison.OrdinalIgnoreCase))
			{
				sandboxes |= Sandboxes.TopLevelNavigation;
			}
			if (!list.Contains("allow-same-origin", StringComparison.OrdinalIgnoreCase))
			{
				sandboxes |= Sandboxes.Origin;
			}
			if (!list.Contains("allow-forms", StringComparison.OrdinalIgnoreCase))
			{
				sandboxes |= Sandboxes.Forms;
			}
			if (!list.Contains("allow-pointer-lock", StringComparison.OrdinalIgnoreCase))
			{
				sandboxes |= Sandboxes.PointerLock;
			}
			if (!list.Contains("allow-scripts", StringComparison.OrdinalIgnoreCase))
			{
				sandboxes |= Sandboxes.Scripts;
				sandboxes |= Sandboxes.AutomaticFeatures;
			}
			if (!list.Contains("allow-presentation", StringComparison.OrdinalIgnoreCase))
			{
				sandboxes |= Sandboxes.Presentation;
			}
			if (!allowFullscreen)
			{
				sandboxes |= Sandboxes.Fullscreen;
			}
			return sandboxes;
		}

		public static T ToEnum<T>(this string? value, T defaultValue) where T : struct, Enum
		{
			if (!string.IsNullOrEmpty(value) && Enum.TryParse<T>(value, ignoreCase: true, out var result))
			{
				return result;
			}
			return defaultValue;
		}

		public static double ToDouble(this string? value, double defaultValue = 0.0)
		{
			if (!string.IsNullOrEmpty(value) && double.TryParse(value, NumberStyles.Any, NumberFormatInfo.InvariantInfo, out var result))
			{
				return result;
			}
			return defaultValue;
		}

		public static int ToInteger(this string? value, int defaultValue = 0)
		{
			if (!string.IsNullOrEmpty(value) && int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
			{
				return result;
			}
			return defaultValue;
		}

		public static uint ToInteger(this string? value, uint defaultValue = 0u)
		{
			if (!string.IsNullOrEmpty(value) && uint.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
			{
				return result;
			}
			return defaultValue;
		}

		public static bool ToBoolean(this string? value, bool defaultValue = false)
		{
			if (!string.IsNullOrEmpty(value) && bool.TryParse(value, out var result))
			{
				return result;
			}
			return defaultValue;
		}

		public static string ReplaceFirst(this string text, string search, string replace)
		{
			int num = text.IndexOf(search);
			if (num < 0)
			{
				return text;
			}
			return text.Substring(0, num) + replace + text.Substring(num + search.Length);
		}

		public static string CollapseAndStrip(this string str)
		{
			if (str.Length == 0)
			{
				return str;
			}
			char[] array = ArrayPool<char>.Shared.Rent(str.Length);
			bool flag = true;
			int num = 0;
			int length = str.Length;
			for (int i = 0; i < length; i++)
			{
				if (str[i].IsSpaceCharacter())
				{
					if (!flag)
					{
						flag = true;
						array[num++] = ' ';
					}
				}
				else
				{
					flag = false;
					array[num++] = str[i];
				}
			}
			if (flag && num > 0)
			{
				num--;
			}
			string result = new string(array, 0, num);
			ArrayPool<char>.Shared.Return(array);
			return result;
		}

		public static string Collapse(this string str)
		{
			StringBuilder stringBuilder = StringBuilderPool.Obtain();
			bool flag = false;
			int length = str.Length;
			for (int i = 0; i < length; i++)
			{
				if (str[i].IsSpaceCharacter())
				{
					if (!flag)
					{
						stringBuilder.Append(' ');
						flag = true;
					}
				}
				else
				{
					flag = false;
					stringBuilder.Append(str[i]);
				}
			}
			return stringBuilder.ToPool();
		}

		public static bool Contains(this string[] list, string element, StringComparison comparison = StringComparison.Ordinal)
		{
			int num = list.Length;
			for (int i = 0; i < num; i++)
			{
				if (list[i].Equals(element, comparison))
				{
					return true;
				}
			}
			return false;
		}

		public static bool IsCustomElement(this string tag)
		{
			if (tag.IndexOf('-') != -1 && !TagNames.DisallowedCustomElementNames.Contains(tag))
			{
				int length = tag.Length;
				for (int i = 0; i < length; i++)
				{
					if (!tag[i].IsCustomElementName())
					{
						return false;
					}
				}
				return true;
			}
			return false;
		}

		public static bool IsCustomElement(this StringOrMemory tag)
		{
			if (tag.Memory.Span.IndexOf('-') != -1 && !TagNames.DisallowedCustomElementNames.Contains(tag))
			{
				int length = tag.Length;
				for (int i = 0; i < length; i++)
				{
					if (!tag[i].IsCustomElementName())
					{
						return false;
					}
				}
				return true;
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool Is(this string? current, string? other)
		{
			return string.Equals(current, other, StringComparison.Ordinal);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool Is(this string? current, StringOrMemory other)
		{
			return other.Memory.Span.SequenceEqual(current.AsSpan());
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool Is(this Span<char> current, string? other)
		{
			if (other == null)
			{
				return false;
			}
			return current.SequenceEqual(other.AsSpan());
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool Is(this ReadOnlySpan<char> current, ReadOnlyMemory<char> other)
		{
			return current.SequenceEqual(other.Span);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool Is(this ReadOnlySpan<char> current, ReadOnlySpan<char> other)
		{
			return current.SequenceEqual(other);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool Isi(this string? current, string? other)
		{
			return string.Equals(current, other, StringComparison.OrdinalIgnoreCase);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool Isi(this string? current, StringOrMemory other)
		{
			return MemoryExtensions.Equals(current.AsSpan(), other.Memory.Span, StringComparison.OrdinalIgnoreCase);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool Isi(this Span<char> current, string? other)
		{
			if (other == null)
			{
				return false;
			}
			return MemoryExtensions.Equals(current, other.AsSpan(), StringComparison.OrdinalIgnoreCase);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool Isi(this Span<char> current, ReadOnlySpan<char> other)
		{
			return MemoryExtensions.Equals(current, other, StringComparison.OrdinalIgnoreCase);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool Isi(this Span<char> current, ReadOnlyMemory<char> other)
		{
			return MemoryExtensions.Equals(current, other.Span, StringComparison.OrdinalIgnoreCase);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool Isi(this ReadOnlySpan<char> current, string? other)
		{
			if (other == null)
			{
				return false;
			}
			return MemoryExtensions.Equals(current, other.AsSpan(), StringComparison.OrdinalIgnoreCase);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsOneOf(this string? element, string item1, string item2)
		{
			if (!element.Is(item1))
			{
				return element.Is(item2);
			}
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsOneOf(this string element, string item1, string item2, string item3)
		{
			if (!element.Is(item1) && !element.Is(item2))
			{
				return element.Is(item3);
			}
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsOneOf(this string element, string item1, string item2, string item3, string item4)
		{
			if (!element.Is(item1) && !element.Is(item2) && !element.Is(item3))
			{
				return element.Is(item4);
			}
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsOneOf(this string element, string item1, string item2, string item3, string item4, string item5)
		{
			if (!element.Is(item1) && !element.Is(item2) && !element.Is(item3) && !element.Is(item4))
			{
				return element.Is(item5);
			}
			return true;
		}

		public static string StripLineBreaks(this string str)
		{
			char[] array = str.ToCharArray();
			int num = 0;
			int num2 = array.Length;
			int num3 = 0;
			while (num3 < num2)
			{
				array[num3] = array[num3 + num];
				if (array[num3].IsLineBreak())
				{
					num++;
					num2--;
				}
				else
				{
					num3++;
				}
			}
			return new string(array, 0, num2);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static string StripLeadingTrailingSpaces(this string str)
		{
			int i = 0;
			int num = str.Length - 1;
			for (; i < str.Length && str[i].IsSpaceCharacter(); i++)
			{
			}
			while (num > i && str[num].IsSpaceCharacter())
			{
				num--;
			}
			return str.Substring(i, 1 + num - i);
		}

		public static string[] SplitWithoutTrimming(this string str, char c)
		{
			List<string> list = new List<string>();
			int num = 0;
			int length = str.Length;
			for (int i = 0; i < length; i++)
			{
				if (str[i] == c)
				{
					if (i > num)
					{
						list.Add(str.Substring(num, i - num));
					}
					num = i + 1;
				}
			}
			if (length > num)
			{
				list.Add(str.Substring(num, length - num));
			}
			return list.ToArray();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static string[] SplitCommas(this string str)
		{
			return str.SplitWithTrimming(',');
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool HasHyphen(this string str, string value, StringComparison comparison = StringComparison.Ordinal)
		{
			if (!string.Equals(str, value, comparison))
			{
				if (str.Length > value.Length && str.StartsWith(value, comparison))
				{
					return str[value.Length] == '-';
				}
				return false;
			}
			return true;
		}

		public static string[] SplitSpaces(this string str)
		{
			List<string> list = new List<string>();
			char[] array = ArrayPool<char>.Shared.Rent(str.Length);
			int num = 0;
			for (int i = 0; i <= str.Length; i++)
			{
				if (i == str.Length || str[i].IsSpaceCharacter())
				{
					if (num > 0)
					{
						string text = new string(array, 0, num).StripLeadingTrailingSpaces();
						if (text.Length != 0)
						{
							list.Add(text);
						}
						num = 0;
					}
				}
				else
				{
					array[num] = str[i];
					num++;
				}
			}
			ArrayPool<char>.Shared.Return(array);
			return list.ToArray();
		}

		public static string[] SplitWithTrimming(this string str, char ch)
		{
			List<string> list = new List<string>();
			char[] array = ArrayPool<char>.Shared.Rent(str.Length);
			int num = 0;
			for (int i = 0; i <= str.Length; i++)
			{
				if (i == str.Length || str[i] == ch)
				{
					if (num > 0)
					{
						string text = new string(array, 0, num).StripLeadingTrailingSpaces();
						if (text.Length != 0)
						{
							list.Add(text);
						}
						num = 0;
					}
				}
				else
				{
					array[num] = str[i];
					num++;
				}
			}
			ArrayPool<char>.Shared.Return(array);
			return list.ToArray();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int FromHex(this string s)
		{
			return int.Parse(s, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int FromDec(this string s)
		{
			return int.Parse(s, NumberStyles.Integer, CultureInfo.InvariantCulture);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static string HtmlEncode(this string value, Encoding encoding)
		{
			return value;
		}

		public static string CssString(this string value)
		{
			StringBuilder stringBuilder = StringBuilderPool.Obtain();
			stringBuilder.Append('"');
			if (!string.IsNullOrEmpty(value))
			{
				int length = value.Length;
				for (int i = 0; i < length; i++)
				{
					char c = value[i];
					switch (c)
					{
					case '\0':
						stringBuilder.ReturnToPool();
						throw new DomException(DomError.InvalidCharacter);
					case '"':
					case '\\':
						stringBuilder.Append('\\').Append(c);
						continue;
					}
					if (c.IsInRange(1, 31) || c == '{')
					{
						stringBuilder.Append('\\').Append(c.ToHex()).Append((i + 1 != length) ? " " : "");
					}
					else
					{
						stringBuilder.Append(c);
					}
				}
			}
			stringBuilder.Append('"');
			return stringBuilder.ToPool();
		}

		public static string CssFunction(this string value, string argument)
		{
			return value + "(" + argument + ")";
		}

		public static string UrlEncode(this byte[] content)
		{
			StringBuilder stringBuilder = StringBuilderPool.Obtain();
			int num = content.Length;
			for (int i = 0; i < num; i++)
			{
				char c = (char)content[i];
				switch (c)
				{
				case ' ':
					stringBuilder.Append('+');
					break;
				default:
					if (!c.IsAlphanumericAscii())
					{
						stringBuilder.Append('%').Append(content[i].ToString("X2"));
						break;
					}
					goto case '*';
				case '*':
				case '-':
				case '.':
				case '_':
				case '~':
					stringBuilder.Append(c);
					break;
				}
			}
			return stringBuilder.ToPool();
		}

		public static byte[] UrlDecode(this string value)
		{
			MemoryStream memoryStream = new MemoryStream();
			int length = value.Length;
			for (int i = 0; i < length; i++)
			{
				char c = value[i];
				switch (c)
				{
				case '+':
				{
					byte value4 = 32;
					memoryStream.WriteByte(value4);
					break;
				}
				case '%':
				{
					if (i + 2 >= length)
					{
						throw new FormatException();
					}
					byte value3 = (byte)(16 * value[++i].FromHex() + value[++i].FromHex());
					memoryStream.WriteByte(value3);
					break;
				}
				default:
				{
					byte value2 = (byte)c;
					memoryStream.WriteByte(value2);
					break;
				}
				}
			}
			return memoryStream.ToArray();
		}

		public static string NormalizeLineEndings(this string value)
		{
			if (!string.IsNullOrEmpty(value))
			{
				StringBuilder stringBuilder = StringBuilderPool.Obtain();
				bool flag = false;
				int length = value.Length;
				for (int i = 0; i < length; i++)
				{
					char c = value[i];
					bool flag2 = c == '\n';
					if (flag && !flag2)
					{
						stringBuilder.Append('\n');
					}
					else if (!flag && flag2)
					{
						stringBuilder.Append('\r');
					}
					flag = c == '\r';
					stringBuilder.Append(c);
				}
				if (flag)
				{
					stringBuilder.Append('\n');
				}
				return stringBuilder.ToPool();
			}
			return value;
		}

		public static string? ToEncodingType(this string? encType)
		{
			if (!encType.Isi(MimeTypeNames.Plain) && !encType.Isi(MimeTypeNames.MultipartForm) && !encType.Isi(MimeTypeNames.ApplicationJson))
			{
				return null;
			}
			return encType?.ToLowerInvariant();
		}

		public static string? ToFormMethod(this string? method)
		{
			if (!method.Isi(FormMethodNames.Get) && !method.Isi(FormMethodNames.Post) && !method.Isi(FormMethodNames.Dialog))
			{
				return null;
			}
			return method?.ToLowerInvariant();
		}
	}
	public sealed class StringSource
	{
		private readonly string _content;

		private readonly int _last;

		private int _index;

		private char _current;

		public char Current => _current;

		public bool IsDone => _current == '\uffff';

		public int Index => _index;

		public string Content => _content;

		public StringSource(string content)
		{
			_content = content ?? string.Empty;
			_last = _content.Length - 1;
			_index = 0;
			_current = ((_last == -1) ? '\uffff' : content[0]);
		}

		public char Next()
		{
			if (_index == _last)
			{
				_current = '\uffff';
				_index = _content.Length;
			}
			else if (_index < _content.Length)
			{
				_current = _content[++_index];
			}
			return _current;
		}

		public char Back()
		{
			if (_index > 0)
			{
				_current = _content[--_index];
			}
			return _current;
		}
	}
	public static class StringSourceExtensions
	{
		public static char SkipSpaces(this StringSource source)
		{
			char c = source.Current;
			while (c.IsSpaceCharacter())
			{
				c = source.Next();
			}
			return c;
		}

		public static char Next(this StringSource source, int n)
		{
			for (int i = 0; i < n; i++)
			{
				source.Next();
			}
			return source.Current;
		}

		public static char Back(this StringSource source, int n)
		{
			for (int i = 0; i < n; i++)
			{
				source.Back();
			}
			return source.Current;
		}

		public static char Peek(this StringSource source)
		{
			char result = source.Next();
			source.Back();
			return result;
		}
	}
	public sealed class StringTextSource : IReadOnlyTextSource, IDisposable
	{
		private readonly string _string;

		private readonly ReadOnlyMemory<char> _memory;

		private readonly int _length;

		private int _index;

		public string Text => _string;

		public char this[int index] => _string[index];

		public int Length => _length;

		public Encoding CurrentEncoding
		{
			get
			{
				return TextEncoding.Utf8;
			}
			set
			{
			}
		}

		public int Index
		{
			get
			{
				return _index;
			}
			set
			{
				_index = value;
			}
		}

		public StringTextSource(string source)
		{
			_string = source;
			_length = source.Length;
			_memory = source.AsMemory();
		}

		public void Dispose()
		{
		}

		public char ReadCharacter()
		{
			if (_index < _length)
			{
				return _string[_index++];
			}
			_index++;
			return '\uffff';
		}

		public string ReadCharacters(int characters)
		{
			return ReadMemory(characters).ToString();
		}

		public StringOrMemory ReadMemory(int characters)
		{
			int index = _index;
			if (index + characters <= _length)
			{
				_index += characters;
				return _memory.Slice(index, characters);
			}
			_index += characters;
			characters = Math.Min(characters, _length - index);
			return _memory.Slice(index, characters);
		}

		public Task PrefetchAsync(int length, CancellationToken cancellationToken)
		{
			return Task.CompletedTask;
		}

		public Task PrefetchAllAsync(CancellationToken cancellationToken)
		{
			return Task.CompletedTask;
		}

		public bool TryGetContentLength(out int length)
		{
			length = _length;
			return true;
		}
	}
	public static class Symbols
	{
		public const char EndOfFile = '\uffff';

		public const char Tilde = '~';

		public const char Pipe = '|';

		public const char Null = '\0';

		public const char Ampersand = '&';

		public const char Num = '#';

		public const char Dollar = '$';

		public const char Semicolon = ';';

		public const char Asterisk = '*';

		public const char Equality = '=';

		public const char Plus = '+';

		public const char Minus = '-';

		public const char Comma = ',';

		public const char Dot = '.';

		public const char Accent = '^';

		public const char At = '@';

		public const char LessThan = '<';

		public const char GreaterThan = '>';

		public const char SingleQuote = '\'';

		public const char DoubleQuote = '"';

		public const char CurvedQuote = '`';

		public const char QuestionMark = '?';

		public const char Tab = '\t';

		public const char LineFeed = '\n';

		public const char CarriageReturn = '\r';

		public const char FormFeed = '\f';

		public const char Space = ' ';

		public const char Solidus = '/';

		public const char NoBreakSpace = '\u00a0';

		public const char ReverseSolidus = '\\';

		public const char Colon = ':';

		public const char ExclamationMark = '!';

		public const char Replacement = '\ufffd';

		public const char Underscore = '_';

		public const char RoundBracketOpen = '(';

		public const char RoundBracketClose = ')';

		public const char SquareBracketOpen = '[';

		public const char SquareBracketClose = ']';

		public const char CurlyBracketOpen = '{';

		public const char CurlyBracketClose = '}';

		public const char Percent = '%';

		public const int MaximumCodepoint = 1114111;
	}
	public static class TextEncoding
	{
		public static readonly Encoding Utf8 = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);

		public static readonly Encoding Utf16Be = new UnicodeEncoding(bigEndian: true, byteOrderMark: false);

		public static readonly Encoding Utf16Le = new UnicodeEncoding(bigEndian: false, byteOrderMark: false);

		public static readonly Encoding Utf32Le = GetEncoding("UTF-32LE");

		public static readonly Encoding Utf32Be = GetEncoding("UTF-32BE");

		public static readonly Encoding Gb18030 = GetEncoding("GB18030");

		public static readonly Encoding Big5 = GetEncoding("big5");

		public static readonly Encoding Windows874 = GetEncoding("windows-874");

		public static readonly Encoding Windows1250 = GetEncoding("windows-1250");

		public static readonly Encoding Windows1251 = GetEncoding("windows-1251");

		public static readonly Encoding Windows1252 = GetEncoding("windows-1252");

		public static readonly Encoding Windows1253 = GetEncoding("windows-1253");

		public static readonly Encoding Windows1254 = GetEncoding("windows-1254");

		public static readonly Encoding Windows1255 = GetEncoding("windows-1255");

		public static readonly Encoding Windows1256 = GetEncoding("windows-1256");

		public static readonly Encoding Windows1257 = GetEncoding("windows-1257");

		public static readonly Encoding Windows1258 = GetEncoding("windows-1258");

		public static readonly Encoding Latin2 = GetEncoding("iso-8859-2");

		public static readonly Encoding Latin3 = GetEncoding("iso-8859-3");

		public static readonly Encoding Latin4 = GetEncoding("iso-8859-4");

		public static readonly Encoding Latin5 = GetEncoding("iso-8859-5");

		public static readonly Encoding Latin13 = GetEncoding("iso-8859-13");

		public static readonly Encoding UsAscii = GetEncoding("us-ascii");

		public static readonly Encoding Korean = GetEncoding("ks_c_5601-1987");

		private static readonly Dictionary<string, Encoding> encodings = CreateEncodings();

		public static bool IsUnicode(this Encoding encoding)
		{
			if (encoding != Utf16Be)
			{
				return encoding == Utf16Le;
			}
			return true;
		}

		public static Encoding? Parse(string content)
		{
			string charset = string.Empty;
			int num = 0;
			for (int i = num; i < content.Length - 7; i++)
			{
				if (content.Substring(i).StartsWith(AttributeNames.Charset, StringComparison.OrdinalIgnoreCase))
				{
					num = i + 7;
					break;
				}
			}
			if (num > 0 && num < content.Length)
			{
				for (int j = num; j < content.Length - 1 && content[j].IsSpaceCharacter(); j++)
				{
					num++;
				}
				if (content[num] != '=')
				{
					return Parse(content.Substring(num));
				}
				num++;
				for (int k = num; k < content.Length && content[k].IsSpaceCharacter(); k++)
				{
					num++;
				}
				if (num < content.Length)
				{
					if (content[num] == '"')
					{
						content = content.Substring(num + 1);
						int num2 = content.IndexOf('"');
						if (num2 != -1)
						{
							charset = content.Substring(0, num2);
						}
					}
					else if (content[num] == '\'')
					{
						content = content.Substring(num + 1);
						int num3 = content.IndexOf('\'');
						if (num3 != -1)
						{
							charset = content.Substring(0, num3);
						}
					}
					else
					{
						content = content.Substring(num);
						int num4 = 0;
						for (int l = 0; l < content.Length && !content[l].IsSpaceCharacter() && content[l] != ';'; l++)
						{
							num4++;
						}
						charset = content.Substring(0, num4);
					}
				}
			}
			if (!IsSupported(charset))
			{
				return null;
			}
			return Resolve(charset);
		}

		public static bool IsSupported(string charset)
		{
			return encodings.ContainsKey(charset);
		}

		public static Encoding Resolve(string? charset)
		{
			if (charset != null && encodings.TryGetValue(charset, out Encoding value))
			{
				return value;
			}
			return Utf8;
		}

		private static Encoding GetEncoding(string name, Encoding? fallback = null)
		{
			try
			{
				return Encoding.GetEncoding(name);
			}
			catch (Exception)
			{
				return fallback ?? Utf8;
			}
		}

		private static Dictionary<string, Encoding> CreateEncodings()
		{
			Dictionary<string, Encoding> obj = new Dictionary<string, Encoding>(StringComparer.OrdinalIgnoreCase)
			{
				{ "unicode-1-1-utf-8", Utf8 },
				{ "utf-8", Utf8 },
				{ "utf8", Utf8 },
				{ "utf-16be", Utf16Be },
				{ "utf-16", Utf16Le },
				{ "utf-16le", Utf16Le },
				{ "dos-874", Windows874 },
				{ "iso-8859-11", Windows874 },
				{ "iso8859-11", Windows874 },
				{ "iso885911", Windows874 },
				{ "tis-620", Windows874 },
				{ "windows-874", Windows874 },
				{ "cp1250", Windows1250 },
				{ "windows-1250", Windows1250 },
				{ "x-cp1250", Windows1250 },
				{ "cp1251", Windows1251 },
				{ "windows-1251", Windows1251 },
				{ "x-cp1251", Windows1251 },
				{ "x-user-defined", Windows1252 },
				{ "ansi_x3.4-1968", Windows1252 },
				{ "ascii", Windows1252 },
				{ "cp1252", Windows1252 },
				{ "cp819", Windows1252 },
				{ "csisolatin1", Windows1252 },
				{ "ibm819", Windows1252 },
				{ "iso-8859-1", Windows1252 },
				{ "iso-ir-100", Windows1252 },
				{ "iso8859-1", Windows1252 },
				{ "iso88591", Windows1252 },
				{ "iso_8859-1", Windows1252 },
				{ "iso_8859-1:1987", Windows1252 },
				{ "l1", Windows1252 },
				{ "latin1", Windows1252 },
				{ "us-ascii", Windows1252 },
				{ "windows-1252", Windows1252 },
				{ "x-cp1252", Windows1252 },
				{ "cp1253", Windows1253 },
				{ "windows-1253", Windows1253 },
				{ "x-cp1253", Windows1253 },
				{ "cp1254", Windows1254 },
				{ "csisolatin5", Windows1254 },
				{ "iso-8859-9", Windows1254 },
				{ "iso-ir-148", Windows1254 },
				{ "iso8859-9", Windows1254 },
				{ "iso88599", Windows1254 },
				{ "iso_8859-9", Windows1254 },
				{ "iso_8859-9:1989", Windows1254 },
				{ "l5", Windows1254 },
				{ "latin5", Windows1254 },
				{ "windows-1254", Windows1254 },
				{ "x-cp1254", Windows1254 },
				{ "cp1255", Windows1255 },
				{ "windows-1255", Windows1255 },
				{ "x-cp1255", Windows1255 },
				{ "cp1256", Windows1256 },
				{ "windows-1256", Windows1256 },
				{ "x-cp1256", Windows1256 },
				{ "cp1257", Windows1257 },
				{ "windows-1257", Windows1257 },
				{ "x-cp1257", Windows1257 },
				{ "cp1258", Windows1258 },
				{ "windows-1258", Windows1258 },
				{ "x-cp1258", Windows1258 }
			};
			Encoding encoding = GetEncoding("macintosh");
			obj.Add("csmacintosh", encoding);
			obj.Add("mac", encoding);
			obj.Add("macintosh", encoding);
			obj.Add("x-mac-roman", encoding);
			Encoding encoding2 = GetEncoding("x-mac-cyrillic");
			obj.Add("x-mac-cyrillic", encoding2);
			obj.Add("x-mac-ukrainian", encoding2);
			Encoding encoding3 = GetEncoding("cp866");
			obj.Add("866", encoding3);
			obj.Add("cp866", encoding3);
			obj.Add("csibm866", encoding3);
			obj.Add("ibm866", encoding3);
			obj.Add("csisolatin2", Latin2);
			obj.Add("iso-8859-2", Latin2);
			obj.Add("iso-ir-101", Latin2);
			obj.Add("iso8859-2", Latin2);
			obj.Add("iso88592", Latin2);
			obj.Add("iso_8859-2", Latin2);
			obj.Add("iso_8859-2:1987", Latin2);
			obj.Add("l2", Latin2);
			obj.Add("latin2", Latin2);
			obj.Add("csisolatin3", Latin3);
			obj.Add("iso-8859-3", Latin3);
			obj.Add("iso-ir-109", Latin3);
			obj.Add("iso8859-3", Latin3);
			obj.Add("iso88593", Latin3);
			obj.Add("iso_8859-3", Latin3);
			obj.Add("iso_8859-3:1988", Latin3);
			obj.Add("l3", Latin3);
			obj.Add("latin3", Latin3);
			obj.Add("csisolatin4", Latin4);
			obj.Add("iso-8859-4", Latin4);
			obj.Add("iso-ir-110", Latin4);
			obj.Add("iso8859-4", Latin4);
			obj.Add("iso88594", Latin4);
			obj.Add("iso_8859-4", Latin4);
			obj.Add("iso_8859-4:1988", Latin4);
			obj.Add("l4", Latin4);
			obj.Add("latin4", Latin4);
			obj.Add("csisolatincyrillic", Latin5);
			obj.Add("cyrillic", Latin5);
			obj.Add("iso-8859-5", Latin5);
			obj.Add("iso-ir-144", Latin5);
			obj.Add("iso8859-5", Latin5);
			obj.Add("iso88595", Latin5);
			obj.Add("iso_8859-5", Latin5);
			obj.Add("iso_8859-5:1988", Latin5);
			Encoding encoding4 = GetEncoding("iso-8859-6");
			obj.Add("arabic", encoding4);
			obj.Add("asmo-708", encoding4);
			obj.Add("csiso88596e", encoding4);
			obj.Add("csiso88596i", encoding4);
			obj.Add("csisolatinarabic", encoding4);
			obj.Add("ecma-114", encoding4);
			obj.Add("iso-8859-6", encoding4);
			obj.Add("iso-8859-6-e", encoding4);
			obj.Add("iso-8859-6-i", encoding4);
			obj.Add("iso-ir-127", encoding4);
			obj.Add("iso8859-6", encoding4);
			obj.Add("iso88596", encoding4);
			obj.Add("iso_8859-6", encoding4);
			obj.Add("iso_8859-6:1987", encoding4);
			Encoding encoding5 = GetEncoding("iso-8859-7");
			obj.Add("csisolatingreek", encoding5);
			obj.Add("ecma-118", encoding5);
			obj.Add("elot_928", encoding5);
			obj.Add("greek", encoding5);
			obj.Add("greek8", encoding5);
			obj.Add("iso-8859-7", encoding5);
			obj.Add("iso-ir-126", encoding5);
			obj.Add("iso8859-7", encoding5);
			obj.Add("iso88597", encoding5);
			obj.Add("iso_8859-7", encoding5);
			obj.Add("iso_8859-7:1987", encoding5);
			obj.Add("sun_eu_greek", encoding5);
			Encoding encoding6 = GetEncoding("iso-8859-8");
			obj.Add("csiso88598e", encoding6);
			obj.Add("csisolatinhebrew", encoding6);
			obj.Add("hebrew", encoding6);
			obj.Add("iso-8859-8", encoding6);
			obj.Add("iso-8859-8-e", encoding6);
			obj.Add("iso-ir-138", encoding6);
			obj.Add("iso8859-8", encoding6);
			obj.Add("iso88598", encoding6);
			obj.Add("iso_8859-8", encoding6);
			obj.Add("iso_8859-8:1988", encoding6);
			obj.Add("visual", encoding6);
			Encoding encoding7 = GetEncoding("iso-8859-8-i");
			obj.Add("csiso88598i", encoding7);
			obj.Add("iso-8859-8-i", encoding7);
			obj.Add("logical", encoding7);
			Encoding encoding8 = GetEncoding("iso-8859-13");
			obj.Add("iso-8859-13", encoding8);
			obj.Add("iso8859-13", encoding8);
			obj.Add("iso885913", encoding8);
			Encoding encoding9 = GetEncoding("iso-8859-15");
			obj.Add("csisolatin9", encoding9);
			obj.Add("iso-8859-15", encoding9);
			obj.Add("iso8859-15", encoding9);
			obj.Add("iso885915", encoding9);
			obj.Add("iso_8859-15", encoding9);
			obj.Add("l9", encoding9);
			Encoding encoding10 = GetEncoding("koi8-r");
			obj.Add("cskoi8r", encoding10);
			obj.Add("koi", encoding10);
			obj.Add("koi8", encoding10);
			obj.Add("koi8-r", encoding10);
			obj.Add("koi8_r", encoding10);
			obj.Add("koi8-u", GetEncoding("koi8-u"));
			Encoding encoding11 = GetEncoding("GB18030", GetEncoding("x-cp20936"));
			obj.Add("chinese", encoding11);
			obj.Add("csgb2312", encoding11);
			obj.Add("csiso58gb231280", encoding11);
			obj.Add("gb2312", encoding11);
			obj.Add("gb_2312", encoding11);
			obj.Add("gb_2312-80", encoding11);
			obj.Add("gbk", encoding11);
			obj.Add("iso-ir-58", encoding11);
			obj.Add("x-gbk", encoding11);
			obj.Add("hz-gb-2312", GetEncoding("hz-gb-2312"));
			obj.Add("gb18030", Gb18030);
			Encoding encoding12 = GetEncoding("x-cp50227");
			obj.Add("x-cp50227", encoding12);
			obj.Add("iso-22-cn", encoding12);
			obj.Add("big5", Big5);
			obj.Add("big5-hkscs", Big5);
			obj.Add("cn-big5", Big5);
			obj.Add("csbig5", Big5);
			obj.Add("x-x-big5", Big5);
			Encoding encoding13 = GetEncoding("iso-2022-jp");
			obj.Add("csiso2022jp", encoding13);
			obj.Add("iso-2022-jp", encoding13);
			Encoding encoding14 = GetEncoding("iso-2022-kr");
			obj.Add("csiso2022kr", encoding14);
			obj.Add("iso-2022-kr", encoding14);
			Encoding encoding15 = GetEncoding("iso-2022-cn");
			obj.Add("iso-2022-cn", encoding15);
			obj.Add("iso-2022-cn-ext", encoding15);
			obj.Add("shift_jis", GetEncoding("shift_jis"));
			Encoding encoding16 = GetEncoding("euc-jp");
			obj.Add("euc-jp", encoding16);
			Encoding encoding17 = GetEncoding("euc-kr");
			obj.Add("euc-kr", encoding17);
			return obj;
		}
	}
	public readonly struct TextPosition : IEquatable<TextPosition>, IComparable<TextPosition>
	{
		public static readonly TextPosition Empty;

		private readonly ushort _line;

		private readonly ushort _column;

		private readonly int _position;

		public int Line => _line;

		public int Column => _column;

		public int Position => _position;

		public int Index => _position - 1;

		public TextPosition(ushort line, ushort column, int position)
		{
			_line = line;
			_column = column;
			_position = position;
		}

		public TextPosition Shift(int columns)
		{
			return new TextPosition(_line, (ushort)(_column + columns), _position + columns);
		}

		public TextPosition After(char chr)
		{
			ushort num = _line;
			ushort num2 = _column;
			if (chr == '\n')
			{
				num++;
				num2 = 0;
			}
			return new TextPosition(num, ++num2, _position + 1);
		}

		public TextPosition After(string str)
		{
			ushort num = _line;
			ushort num2 = _column;
			for (int i = 0; i < str.Length; i++)
			{
				if (str[i] == '\n')
				{
					num++;
					num2 = 0;
				}
				num2++;
			}
			return new TextPosition(num, num2, _position + str.Length);
		}

		public override string ToString()
		{
			return $"Ln {_line}, Col {_column}, Pos {_position}";
		}

		public override int GetHashCode()
		{
			return _position ^ ((_line | _column) + _line);
		}

		public override bool Equals(object? obj)
		{
			if (obj is TextPosition other)
			{
				return Equals(other);
			}
			return false;
		}

		public bool Equals(TextPosition other)
		{
			if (_position == other._position && _column == other._column)
			{
				return _line == other._line;
			}
			return false;
		}

		public static bool operator >(TextPosition a, TextPosition b)
		{
			return a._position > b._position;
		}

		public static bool operator <(TextPosition a, TextPosition b)
		{
			return a._position < b._position;
		}

		public int CompareTo(TextPosition other)
		{
			if (!Equals(other))
			{
				if (!(this > other))
				{
					return -1;
				}
				return 1;
			}
			return 0;
		}
	}
	[DebuggerStepThrough]
	public readonly struct TextRange : IEquatable<TextRange>, IComparable<TextRange>
	{
		private readonly TextPosition _start;

		private readonly TextPosition _end;

		public TextPosition Start => _start;

		public TextPosition End => _end;

		public TextRange(TextPosition start, TextPosition end)
		{
			_start = start;
			_end = end;
		}

		public override string ToString()
		{
			return $"({_start}) -- ({_end})";
		}

		public override int GetHashCode()
		{
			return _end.GetHashCode() ^ _start.GetHashCode();
		}

		public override bool Equals(object? obj)
		{
			if (obj is TextRange other)
			{
				return Equals(other);
			}
			return false;
		}

		public bool Equals(TextRange other)
		{
			if (_start.Equals(other._start))
			{
				return _end.Equals(other._end);
			}
			return false;
		}

		public static bool operator >(TextRange a, TextRange b)
		{
			return a._start > b._end;
		}

		public static bool operator <(TextRange a, TextRange b)
		{
			return a._end < b._start;
		}

		public int CompareTo(TextRange other)
		{
			if (this > other)
			{
				return 1;
			}
			if (other > this)
			{
				return -1;
			}
			return 0;
		}
	}
	public sealed class TextSource : ITextSource, IReadOnlyTextSource, IDisposable
	{
		private readonly WritableTextSource _writableSource;

		private readonly IReadOnlyTextSource _readOnlyTextSource;

		public string Text => _readOnlyTextSource.Text;

		public int Length => _readOnlyTextSource.Length;

		public Encoding CurrentEncoding
		{
			get
			{
				return _readOnlyTextSource.CurrentEncoding;
			}
			set
			{
				if (_writableSource != null)
				{
					_writableSource.CurrentEncoding = value;
				}
			}
		}

		public int Index
		{
			get
			{
				return _readOnlyTextSource.Index;
			}
			set
			{
				_readOnlyTextSource.Index = value;
			}
		}

		public char this[int index] => _readOnlyTextSource[index];

		public TextSource(string source)
		{
			_writableSource = new WritableTextSource(source);
			_readOnlyTextSource = _writableSource;
		}

		public TextSource(Stream baseStream, Encoding encoding = null)
		{
			_writableSource = new WritableTextSource(baseStream, encoding);
			_readOnlyTextSource = _writableSource;
		}

		public TextSource(ReadOnlyMemoryTextSource source)
		{
			_writableSource = null;
			_readOnlyTextSource = source;
		}

		public TextSource(CharArrayTextSource source)
		{
			_writableSource = null;
			_readOnlyTextSource = source;
		}

		public TextSource(StringTextSource source)
		{
			_writableSource = null;
			_readOnlyTextSource = source;
		}

		public char ReadCharacter()
		{
			return _readOnlyTextSource.ReadCharacter();
		}

		public string ReadCharacters(int characters)
		{
			return _readOnlyTextSource.ReadCharacters(characters);
		}

		public StringOrMemory ReadMemory(int characters)
		{
			return _readOnlyTextSource.ReadMemory(characters);
		}

		public Task PrefetchAsync(int length, CancellationToken cancellationToken)
		{
			return _readOnlyTextSource.PrefetchAsync(length, cancellationToken);
		}

		public Task PrefetchAllAsync(CancellationToken cancellationToken)
		{
			return _readOnlyTextSource.PrefetchAllAsync(cancellationToken);
		}

		public bool TryGetContentLength(out int length)
		{
			return _readOnlyTextSource.TryGetContentLength(out length);
		}

		public void InsertText(string content)
		{
			if (_writableSource == null)
			{
				throw new InvalidOperationException("Cannot insert text into a read-only text source.");
			}
			_writableSource.InsertText(content);
		}

		public void Dispose()
		{
			_readOnlyTextSource.Dispose();
		}

		public IReadOnlyTextSource GetUnderlyingTextSource()
		{
			return _readOnlyTextSource;
		}
	}
	public class TextView
	{
		private readonly TextSource _source;

		private readonly TextRange _range;

		public TextRange Range => _range;

		public string Text
		{
			get
			{
				int num = Math.Max(_range.Start.Position - 1, 0);
				int num2 = _range.End.Position + 1 - _range.Start.Position;
				string text = _source.Text;
				if (num + num2 > text.Length)
				{
					num2 = text.Length - num;
				}
				return text.Substring(num, num2);
			}
		}

		public TextView(TextSource source, TextRange range)
		{
			_source = source;
			_range = range;
		}
	}
	internal sealed class WritableTextSource : ITextSource, IReadOnlyTextSource, IDisposable
	{
		private enum EncodingConfidence : byte
		{
			Tentative,
			Certain,
			Irrelevant
		}

		private const int BufferSize = 4096;

		private readonly Stream _baseStream;

		private readonly MemoryStream _raw;

		private readonly byte[] _buffer;

		private readonly char[] _chars;

		private StringBuilder _content;

		private EncodingConfidence _confidence;

		private bool _finished;

		private Encoding _encoding;

		private Decoder _decoder;

		private int _index;

		[MemberNotNull("_content")]
		public string Text
		{
			[MemberNotNull("_content")]
			get
			{
				return _content.ToString();
			}
		}

		public char this[int index] => Replace(_content[index]);

		public int Length => _content.Length;

		public Encoding CurrentEncoding
		{
			get
			{
				return _encoding;
			}
			set
			{
				if (_confidence != 0)
				{
					return;
				}
				if (_encoding.IsUnicode())
				{
					_confidence = EncodingConfidence.Certain;
					return;
				}
				if (value.IsUnicode())
				{
					value = TextEncoding.Utf8;
				}
				if (value == _encoding)
				{
					_confidence = EncodingConfidence.Certain;
					return;
				}
				_encoding = value;
				_decoder = value.GetDecoder();
				byte[] array = _raw.ToArray();
				char[] array2 = new char[_encoding.GetMaxCharCount(array.Length)];
				int chars = _decoder.GetChars(array, 0, array.Length, array2, 0);
				string text = new string(array2, 0, chars);
				int num = Math.Min(_index, text.Length);
				if (text.Substring(0, num).Is(_content.ToString(0, num)))
				{
					_confidence = EncodingConfidence.Certain;
					_content.Remove(num, _content.Length - num);
					_content.Append(text.Substring(num));
					return;
				}
				_index = 0;
				_content.Clear().Append(text);
				throw new NotSupportedException();
			}
		}

		public int Index
		{
			get
			{
				return _index;
			}
			set
			{
				_index = value;
			}
		}

		private WritableTextSource(Encoding encoding, bool allocateBuffers)
		{
			if (allocateBuffers)
			{
				_buffer = new byte[4096];
				_chars = new char[4097];
			}
			_raw = new MemoryStream();
			_index = 0;
			_encoding = encoding ?? TextEncoding.Utf8;
			_decoder = _encoding.GetDecoder();
		}

		public WritableTextSource(string source)
			: this(null, TextEncoding.Utf8)
		{
			_finished = true;
			_content.Append(source);
			_confidence = EncodingConfidence.Irrelevant;
		}

		public WritableTextSource(Stream baseStream, Encoding encoding = null)
			: this(encoding, baseStream != null)
		{
			_baseStream = baseStream;
			_content = StringBuilderPool.Obtain();
			_confidence = EncodingConfidence.Tentative;
		}

		public void Dispose()
		{
			if (_content != null)
			{
				_raw.Dispose();
				_content.Clear().ReturnToPool();
				_content = null;
			}
		}

		public char ReadCharacter()
		{
			if (_index < _content.Length)
			{
				return Replace(_content[_index++]);
			}
			ExpandBuffer(4096L);
			int num = _index++;
			if (num >= _content.Length)
			{
				return '\uffff';
			}
			return Replace(_content[num]);
		}

		public string ReadCharacters(int characters)
		{
			int index = _index;
			if (index + characters <= _content.Length)
			{
				_index += characters;
				return _content.ToString(index, characters);
			}
			ExpandBuffer(Math.Max(4096, characters));
			_index += characters;
			characters = Math.Min(characters, _content.Length - index);
			return _content.ToString(index, characters);
		}

		public StringOrMemory ReadMemory(int characters)
		{
			return new StringOrMemory(ReadCharacters(characters));
		}

		public Task PrefetchAsync(int length, CancellationToken cancellationToken)
		{
			return ExpandBufferAsync(length, cancellationToken);
		}

		public async Task PrefetchAllAsync(CancellationToken cancellationToken)
		{
			if (_baseStream != null && _content.Length == 0)
			{
				await DetectByteOrderMarkAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			}
			while (!_finished)
			{
				await ReadIntoBufferAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			}
		}

		public bool TryGetContentLength(out int length)
		{
			length = 0;
			return false;
		}

		public void InsertText(string content)
		{
			if (_index >= 0 && _index < _content.Length)
			{
				_content.Insert(_index, content);
			}
			else
			{
				_content.Append(content);
			}
			_index += content.Length;
		}

		private static char Replace(char c)
		{
			if (c != '\uffff')
			{
				return c;
			}
			return '\ufffd';
		}

		private async Task DetectByteOrderMarkAsync(CancellationToken cancellationToken)
		{
			int num = await _baseStream.ReadAsync(_buffer, 0, 4096).ConfigureAwait(continueOnCapturedContext: false);
			int num2 = 0;
			if (num > 2 && _buffer[0] == 239 && _buffer[1] == 187 && _buffer[2] == 191)
			{
				_encoding = TextEncoding.Utf8;
				num2 = 3;
			}
			else if (num > 3 && _buffer[0] == byte.MaxValue && _buffer[1] == 254 && _buffer[2] == 0 && _buffer[3] == 0)
			{
				_encoding = TextEncoding.Utf32Le;
				num2 = 4;
			}
			else if (num > 3 && _buffer[0] == 0 && _buffer[1] == 0 && _buffer[2] == 254 && _buffer[3] == byte.MaxValue)
			{
				_encoding = TextEncoding.Utf32Be;
				num2 = 4;
			}
			else if (num > 1 && _buffer[0] == 254 && _buffer[1] == byte.MaxValue)
			{
				_encoding = TextEncoding.Utf16Be;
				num2 = 2;
			}
			else if (num > 1 && _buffer[0] == byte.MaxValue && _buffer[1] == 254)
			{
				_encoding = TextEncoding.Utf16Le;
				num2 = 2;
			}
			else if (num > 3 && _buffer[0] == 132 && _buffer[1] == 49 && _buffer[2] == 149 && _buffer[3] == 51)
			{
				_encoding = TextEncoding.Gb18030;
				num2 = 4;
			}
			if (num2 > 0)
			{
				num -= num2;
				Array.Copy(_buffer, num2, _buffer, 0, num);
				_decoder = _encoding.GetDecoder();
				_confidence = EncodingConfidence.Certain;
			}
			AppendContentFromBuffer(num);
		}

		private async Task ExpandBufferAsync(long size, CancellationToken cancellationToken)
		{
			if (!_finished && _content.Length == 0)
			{
				await DetectByteOrderMarkAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			}
			while (!_finished && size + _index > _content.Length)
			{
				await ReadIntoBufferAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			}
		}

		private async Task ReadIntoBufferAsync(CancellationToken cancellationToken)
		{
			AppendContentFromBuffer(await _baseStream.ReadAsync(_buffer, 0, 4096, cancellationToken).ConfigureAwait(continueOnCapturedContext: false));
		}

		private void ExpandBuffer(long size)
		{
			if (!_finished && _content.Length == 0)
			{
				DetectByteOrderMarkAsync(CancellationToken.None).Wait();
			}
			while (!_finished && size + _index > _content.Length)
			{
				ReadIntoBuffer();
			}
		}

		private void ReadIntoBuffer()
		{
			int size = _baseStream.Read(_buffer, 0, 4096);
			AppendContentFromBuffer(size);
		}

		private void AppendContentFromBuffer(int size)
		{
			_finished = size == 0;
			int chars = _decoder.GetChars(_buffer, 0, size, _chars, 0);
			if (_confidence != EncodingConfidence.Certain)
			{
				_raw.Write(_buffer, 0, size);
			}
			_content.Append(_chars, 0, chars);
		}
	}
	public static class XmlExtensions
	{
		public static bool IsPubidChar(this char c)
		{
			if (!c.IsAlphanumericAscii() && c != '-' && c != '\'' && c != '+' && c != ',' && c != '.' && c != '/' && c != ':' && c != '?' && c != '=' && c != '!' && c != '*' && c != '#' && c != '@' && c != '$' && c != '_' && c != '(' && c != ')' && c != ';' && c != '%')
			{
				return c.IsSpaceCharacter();
			}
			return true;
		}

		public static bool IsXmlNameStart(this char c)
		{
			if (!c.IsLetter() && c != ':' && c != '_' && !c.IsInRange(192, 214) && !c.IsInRange(216, 246) && !c.IsInRange(248, 767) && !c.IsInRange(880, 893) &

Mods/RealRadio/AudioStreamer.MediaFoundation.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using Microsoft.CodeAnalysis;
using NAudio.MediaFoundation;
using NAudio.Wave;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("AudioStreamer.MediaFoundation")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+1cd90b6bdac1f314159cb7e67c99a8412d514dd2")]
[assembly: AssemblyProduct("AudioStreamer.MediaFoundation")]
[assembly: AssemblyTitle("AudioStreamer.MediaFoundation")]
[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 AudioStreamer.MediaFoundation
{
	public class MediaFoundationAudioStream : AudioStream
	{
		private readonly string url;

		private MediaFoundationReader? reader;

		private MediaFoundationResampler? resampler;

		private bool hasReadOnce;

		public WaveFormat? ResampleFormat { get; set; }

		public override bool Started => reader != null;

		public override bool StreamAvailable => hasReadOnce;

		public override WaveFormat WaveFormat
		{
			get
			{
				MediaFoundationResampler? obj = resampler;
				object obj2 = ((obj != null) ? ((MediaFoundationTransform)obj).WaveFormat : null);
				if (obj2 == null)
				{
					MediaFoundationReader? obj3 = reader;
					obj2 = ((obj3 != null) ? ((WaveStream)obj3).WaveFormat : null) ?? throw new InvalidOperationException("The stream has not been started.");
				}
				return (WaveFormat)obj2;
			}
		}

		public override bool CanSeek
		{
			get
			{
				if (reader == null)
				{
					throw new InvalidOperationException("The stream has not been started.");
				}
				return ((Stream)(object)reader).CanSeek;
			}
		}

		public override long Position
		{
			get
			{
				if (reader == null)
				{
					throw new InvalidOperationException("The stream has not been started.");
				}
				return ((Stream)(object)reader).Position;
			}
			set
			{
				if (reader == null)
				{
					throw new InvalidOperationException("The stream has not been started.");
				}
				((Stream)(object)reader).Position = value;
			}
		}

		public override long Length
		{
			get
			{
				if (reader == null)
				{
					throw new InvalidOperationException("The stream has not been started.");
				}
				return ((Stream)(object)reader).Length;
			}
		}

		public override TimeSpan CurrentTime
		{
			get
			{
				return ((WaveStream)(reader ?? throw new InvalidOperationException("The stream has not been started."))).CurrentTime;
			}
			set
			{
				if (reader == null)
				{
					throw new InvalidOperationException("The stream has not been started.");
				}
				if (!((Stream)(object)reader).CanSeek)
				{
					throw new InvalidOperationException("The stream does not support seeking.");
				}
				((WaveStream)reader).CurrentTime = value;
				MediaFoundationResampler? obj = resampler;
				if (obj != null)
				{
					((MediaFoundationTransform)obj).Reposition();
				}
			}
		}

		public override TimeSpan TotalTime => ((WaveStream)(reader ?? throw new InvalidOperationException("The stream has not been started."))).TotalTime;

		public MediaFoundationAudioStream(string url)
		{
			this.url = url;
			((AudioStream)this)..ctor();
		}

		private MediaFoundationReader CreateMFReader()
		{
			//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_0017: Expected O, but got Unknown
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			return new MediaFoundationReader(url, new MediaFoundationReaderSettings
			{
				RequestFloatOutput = true
			});
		}

		private MediaFoundationResampler CreateMFResampler()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			if (reader == null)
			{
				throw new InvalidOperationException("The stream has not been started.");
			}
			if (ResampleFormat == null)
			{
				throw new InvalidOperationException("The resample format has not been set.");
			}
			return new MediaFoundationResampler((IWaveProvider)(object)reader, ResampleFormat);
		}

		public override void WarmupReader()
		{
			if (reader == null)
			{
				throw new InvalidOperationException("The stream has not been started.");
			}
			Span<byte> buffer = new byte[((WaveStream)reader).BlockAlign];
			((Stream)(object)reader).Read(buffer);
			hasReadOnce = true;
		}

		protected override int ReadInternal(byte[] outBuffer, int offset, int count)
		{
			if (reader == null)
			{
				throw new InvalidOperationException("The stream has not been started.");
			}
			hasReadOnce = true;
			if (resampler != null)
			{
				return ((MediaFoundationTransform)resampler).Read(outBuffer, offset, count);
			}
			return ((Stream)(object)reader).Read(outBuffer, offset, count);
		}

		protected override void Dispose(bool disposing)
		{
			((AudioStream)this).Dispose(disposing);
			if (disposing)
			{
				((AudioStream)this).Stop();
			}
		}

		public override void Start()
		{
			if (reader == null)
			{
				reader = CreateMFReader();
				if (ResampleFormat != null)
				{
					resampler = CreateMFResampler();
				}
			}
		}

		public override void Stop()
		{
			if (reader != null)
			{
				hasReadOnce = false;
				((Stream)(object)reader).Dispose();
				MediaFoundationResampler? obj = resampler;
				if (obj != null)
				{
					((MediaFoundationTransform)obj).Dispose();
				}
				reader = null;
				resampler = null;
			}
		}
	}
}

Mods/RealRadio/AudioStreamer.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Microsoft.CodeAnalysis;
using NAudio.Wave;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("AudioStreamer")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+1cd90b6bdac1f314159cb7e67c99a8412d514dd2")]
[assembly: AssemblyProduct("AudioStreamer")]
[assembly: AssemblyTitle("AudioStreamer")]
[assembly: InternalsVisibleTo("AudioStreamer.CliTest")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace AudioStreamer
{
	public abstract class AudioStream : IDisposable, IWaveProvider, ISampleProvider
	{
		private byte[]? byteBuffer;

		public abstract bool Started { get; }

		public abstract bool StreamAvailable { get; }

		public abstract WaveFormat WaveFormat { get; }

		public bool IsDisposed { get; private set; }

		public abstract bool CanSeek { get; }

		public abstract long Position { get; set; }

		public abstract long Length { get; }

		public abstract TimeSpan CurrentTime { get; set; }

		public abstract TimeSpan TotalTime { get; }

		public abstract void Start();

		public abstract void Stop();

		public abstract void WarmupReader();

		protected abstract int ReadInternal(byte[] buffer, int offset, int count);

		public void Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (!IsDisposed)
			{
				IsDisposed = true;
			}
		}

		public int Read(byte[] buffer, int offset, int count)
		{
			if (IsDisposed)
			{
				throw new ObjectDisposedException("AudioStream");
			}
			if (!Started)
			{
				throw new InvalidOperationException("The stream has not been started.");
			}
			return ReadInternal(buffer, offset, count);
		}

		public int Read(float[] floatBuffer, int offset, int count)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			if ((int)WaveFormat.Encoding == 3)
			{
				if (byteBuffer == null)
				{
					byteBuffer = new byte[floatBuffer.Length * 4];
				}
				if (byteBuffer.Length * 4 < floatBuffer.Length)
				{
					Array.Resize(ref byteBuffer, floatBuffer.Length * 4);
				}
				int num = ReadInternal(byteBuffer, 0, count * 4);
				MemoryMarshal.Cast<byte, float>(byteBuffer.AsSpan(0, num)).CopyTo(floatBuffer.AsSpan(offset));
				return num / 4;
			}
			throw new NotImplementedException("Only IEEE float streams are supported");
		}
	}
}

Mods/RealRadio/HashUtility.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("HashUtility")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+1cd90b6bdac1f314159cb7e67c99a8412d514dd2")]
[assembly: AssemblyProduct("HashUtility")]
[assembly: AssemblyTitle("HashUtility")]
[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 HashUtility
{
	public static class StringHashing
	{
		public static uint GetStableHashCode(this string str)
		{
			uint num = 5381u;
			uint num2 = num;
			for (int i = 0; i < str.Length && str[i] != 0; i += 2)
			{
				num = ((num << 5) + num) ^ str[i];
				if (i == str.Length - 1 || str[i + 1] == '\0')
				{
					break;
				}
				num2 = ((num2 << 5) + num2) ^ str[i + 1];
			}
			return num + num2 * 1566083941;
		}
	}
}

Mods/RealRadio/Microsoft.Bcl.AsyncInterfaces.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using System.Threading.Tasks.Sources;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: AssemblyDefaultAlias("Microsoft.Bcl.AsyncInterfaces")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata("IsTrimmable", "True")]
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyDescription("Provides the IAsyncEnumerable<T> and IAsyncDisposable interfaces and helper types for .NET Standard 2.0. This package is not required starting with .NET Standard 2.1 and .NET Core 3.0.\r\n\r\nCommonly Used Types:\r\nSystem.IAsyncDisposable\r\nSystem.Collections.Generic.IAsyncEnumerable\r\nSystem.Collections.Generic.IAsyncEnumerator")]
[assembly: AssemblyFileVersion("8.0.23.53103")]
[assembly: AssemblyInformationalVersion("8.0.0+5535e31a712343a63f5d7d796cd874e563e5ac14")]
[assembly: AssemblyProduct("Microsoft® .NET")]
[assembly: AssemblyTitle("Microsoft.Bcl.AsyncInterfaces")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/dotnet/runtime")]
[assembly: AssemblyVersion("8.0.0.0")]
[assembly: TypeForwardedTo(typeof(IAsyncEnumerable<>))]
[assembly: TypeForwardedTo(typeof(IAsyncEnumerator<>))]
[assembly: TypeForwardedTo(typeof(IAsyncDisposable))]
[assembly: TypeForwardedTo(typeof(AsyncIteratorMethodBuilder))]
[assembly: TypeForwardedTo(typeof(AsyncIteratorStateMachineAttribute))]
[assembly: TypeForwardedTo(typeof(ConfiguredAsyncDisposable))]
[assembly: TypeForwardedTo(typeof(ConfiguredCancelableAsyncEnumerable<>))]
[assembly: TypeForwardedTo(typeof(EnumeratorCancellationAttribute))]
[assembly: TypeForwardedTo(typeof(ManualResetValueTaskSourceCore<>))]
[assembly: TypeForwardedTo(typeof(TaskAsyncEnumerableExtensions))]
[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 System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	internal sealed class MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	internal sealed class MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
}
namespace System.Runtime.InteropServices
{
	[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
	internal sealed class LibraryImportAttribute : Attribute
	{
		public string LibraryName { get; }

		public string EntryPoint { get; set; }

		public StringMarshalling StringMarshalling { get; set; }

		public Type StringMarshallingCustomType { get; set; }

		public bool SetLastError { get; set; }

		public LibraryImportAttribute(string libraryName)
		{
			LibraryName = libraryName;
		}
	}
	internal enum StringMarshalling
	{
		Custom,
		Utf8,
		Utf16
	}
}

Mods/RealRadio/Microsoft.Extensions.DependencyInjection.Abstractions.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using FxResources.Microsoft.Extensions.DependencyInjection.Abstractions;
using Microsoft.CodeAnalysis;
using Microsoft.Extensions.Internal;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("Microsoft.Extensions.DependencyInjection.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: AssemblyDefaultAlias("Microsoft.Extensions.DependencyInjection.Abstractions")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata("IsTrimmable", "True")]
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyDescription("Abstractions for dependency injection.\r\n\r\nCommonly Used Types:\r\nMicrosoft.Extensions.DependencyInjection.IServiceCollection")]
[assembly: AssemblyFileVersion("8.0.23.53103")]
[assembly: AssemblyInformationalVersion("8.0.0+5535e31a712343a63f5d7d796cd874e563e5ac14")]
[assembly: AssemblyProduct("Microsoft® .NET")]
[assembly: AssemblyTitle("Microsoft.Extensions.DependencyInjection.Abstractions")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/dotnet/runtime")]
[assembly: AssemblyVersion("8.0.0.0")]
[module: RefSafetyRules(11)]
[module: System.Runtime.CompilerServices.NullablePublicOnly(true)]
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 NullablePublicOnlyAttribute : Attribute
	{
		public readonly bool IncludesInternals;

		public NullablePublicOnlyAttribute(bool P_0)
		{
			IncludesInternals = 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 FxResources.Microsoft.Extensions.DependencyInjection.Abstractions
{
	internal static class SR
	{
	}
}
namespace System
{
	internal static class ThrowHelper
	{
		internal static void ThrowIfNull(object? argument, [CallerArgumentExpression("argument")] string? paramName = null)
		{
			if (argument == null)
			{
				Throw(paramName);
			}
		}

		private static void Throw(string paramName)
		{
			throw new ArgumentNullException(paramName);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static string IfNullOrWhitespace(string? argument, [CallerArgumentExpression("argument")] string paramName = "")
		{
			if (argument == null)
			{
				throw new ArgumentNullException(paramName);
			}
			if (string.IsNullOrWhiteSpace(argument))
			{
				if (argument == null)
				{
					throw new ArgumentNullException(paramName);
				}
				throw new ArgumentException(paramName, "Argument is whitespace");
			}
			return argument;
		}
	}
	internal static class SR
	{
		private static readonly bool s_usingResourceKeys = AppContext.TryGetSwitch("System.Resources.UseSystemResourceKeys", out var isEnabled) && isEnabled;

		private static ResourceManager s_resourceManager;

		internal static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(typeof(SR)));

		internal static string AmbiguousConstructorMatch => GetResourceString("AmbiguousConstructorMatch");

		internal static string CannotResolveService => GetResourceString("CannotResolveService");

		internal static string NoConstructorMatch => GetResourceString("NoConstructorMatch");

		internal static string NoServiceRegistered => GetResourceString("NoServiceRegistered");

		internal static string ServiceCollectionReadOnly => GetResourceString("ServiceCollectionReadOnly");

		internal static string TryAddIndistinguishableTypeToEnumerable => GetResourceString("TryAddIndistinguishableTypeToEnumerable");

		internal static string MultipleCtorsMarkedWithAttribute => GetResourceString("MultipleCtorsMarkedWithAttribute");

		internal static string MarkedCtorMissingArgumentTypes => GetResourceString("MarkedCtorMissingArgumentTypes");

		internal static string CannotCreateAbstractClasses => GetResourceString("CannotCreateAbstractClasses");

		internal static string MultipleCtorsFoundWithBestLength => GetResourceString("MultipleCtorsFoundWithBestLength");

		internal static string UnableToResolveService => GetResourceString("UnableToResolveService");

		internal static string CtorNotLocated => GetResourceString("CtorNotLocated");

		internal static string MultipleCtorsFound => GetResourceString("MultipleCtorsFound");

		internal static string KeyedServicesNotSupported => GetResourceString("KeyedServicesNotSupported");

		internal static string KeyedDescriptorMisuse => GetResourceString("KeyedDescriptorMisuse");

		internal static string NonKeyedDescriptorMisuse => GetResourceString("NonKeyedDescriptorMisuse");

		internal static bool UsingResourceKeys()
		{
			return s_usingResourceKeys;
		}

		private static string GetResourceString(string resourceKey)
		{
			if (UsingResourceKeys())
			{
				return resourceKey;
			}
			string result = null;
			try
			{
				result = ResourceManager.GetString(resourceKey);
			}
			catch (MissingManifestResourceException)
			{
			}
			return result;
		}

		private static string GetResourceString(string resourceKey, string defaultString)
		{
			string resourceString = GetResourceString(resourceKey);
			if (!(resourceKey == resourceString) && resourceString != null)
			{
				return resourceString;
			}
			return defaultString;
		}

		internal static string Format(string resourceFormat, object? p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(resourceFormat, p1);
		}

		internal static string Format(string resourceFormat, object? p1, object? p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(resourceFormat, p1, p2);
		}

		internal static string Format(string resourceFormat, object? p1, object? p2, object? p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(resourceFormat, p1, p2, p3);
		}

		internal static string Format(string resourceFormat, params object?[]? args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + ", " + string.Join(", ", args);
				}
				return string.Format(resourceFormat, args);
			}
			return resourceFormat;
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(provider, resourceFormat, p1);
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1, object? p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(provider, resourceFormat, p1, p2);
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1, object? p2, object? p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(provider, resourceFormat, p1, p2, p3);
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, params object?[]? args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + ", " + string.Join(", ", args);
				}
				return string.Format(provider, resourceFormat, args);
			}
			return resourceFormat;
		}
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, Inherited = false)]
	internal sealed class DynamicallyAccessedMembersAttribute : Attribute
	{
		public DynamicallyAccessedMemberTypes MemberTypes { get; }

		public DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes memberTypes)
		{
			MemberTypes = memberTypes;
		}
	}
	[Flags]
	internal enum DynamicallyAccessedMemberTypes
	{
		None = 0,
		PublicParameterlessConstructor = 1,
		PublicConstructors = 3,
		NonPublicConstructors = 4,
		PublicMethods = 8,
		NonPublicMethods = 0x10,
		PublicFields = 0x20,
		NonPublicFields = 0x40,
		PublicNestedTypes = 0x80,
		NonPublicNestedTypes = 0x100,
		PublicProperties = 0x200,
		NonPublicProperties = 0x400,
		PublicEvents = 0x800,
		NonPublicEvents = 0x1000,
		Interfaces = 0x2000,
		All = -1
	}
	[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
	internal sealed class UnconditionalSuppressMessageAttribute : Attribute
	{
		public string Category { get; }

		public string CheckId { get; }

		public string? Scope { get; set; }

		public string? Target { get; set; }

		public string? MessageId { get; set; }

		public string? Justification { get; set; }

		public UnconditionalSuppressMessageAttribute(string category, string checkId)
		{
			Category = category;
			CheckId = checkId;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Method, Inherited = false)]
	internal sealed class RequiresDynamicCodeAttribute : Attribute
	{
		public string Message { get; }

		public string? Url { get; set; }

		public RequiresDynamicCodeAttribute(string message)
		{
			Message = message;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	internal sealed class MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	internal sealed class MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
}
namespace System.Runtime.InteropServices
{
	[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
	internal sealed class LibraryImportAttribute : Attribute
	{
		public string LibraryName { get; }

		public string? EntryPoint { get; set; }

		public StringMarshalling StringMarshalling { get; set; }

		public Type? StringMarshallingCustomType { get; set; }

		public bool SetLastError { get; set; }

		public LibraryImportAttribute(string libraryName)
		{
			LibraryName = libraryName;
		}
	}
	internal enum StringMarshalling
	{
		Custom,
		Utf8,
		Utf16
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	internal sealed class CallerArgumentExpressionAttribute : Attribute
	{
		public string ParameterName { get; }

		public CallerArgumentExpressionAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
}
namespace Microsoft.Extensions.Internal
{
	internal static class ParameterDefaultValue
	{
		public static bool TryGetDefaultValue(ParameterInfo parameter, out object? defaultValue)
		{
			bool tryToGetDefaultValue;
			bool flag = CheckHasDefaultValue(parameter, out tryToGetDefaultValue);
			defaultValue = null;
			if (flag)
			{
				if (tryToGetDefaultValue)
				{
					defaultValue = parameter.DefaultValue;
				}
				bool flag2 = parameter.ParameterType.IsGenericType && parameter.ParameterType.GetGenericTypeDefinition() == typeof(Nullable<>);
				if (defaultValue == null && parameter.ParameterType.IsValueType && !flag2)
				{
					defaultValue = CreateValueType(parameter.ParameterType);
				}
				if (defaultValue != null && flag2)
				{
					Type underlyingType = Nullable.GetUnderlyingType(parameter.ParameterType);
					if (underlyingType != null && underlyingType.IsEnum)
					{
						defaultValue = Enum.ToObject(underlyingType, defaultValue);
					}
				}
			}
			return flag;
			[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2067:UnrecognizedReflectionPattern", Justification = "CreateValueType is only called on a ValueType. You can always create an instance of a ValueType.")]
			static object? CreateValueType(Type t)
			{
				return RuntimeHelpers.GetUninitializedObject(t);
			}
		}

		public static bool CheckHasDefaultValue(ParameterInfo parameter, out bool tryToGetDefaultValue)
		{
			tryToGetDefaultValue = true;
			try
			{
				return parameter.HasDefaultValue;
			}
			catch (FormatException) when (parameter.ParameterType == typeof(DateTime))
			{
				tryToGetDefaultValue = false;
				return true;
			}
		}
	}
}
namespace Microsoft.Extensions.DependencyInjection
{
	public static class ActivatorUtilities
	{
		private readonly struct FactoryParameterContext
		{
			public Type ParameterType { get; }

			public bool HasDefaultValue { get; }

			public object DefaultValue { get; }

			public int ArgumentIndex { get; }

			public object ServiceKey { get; }

			public FactoryParameterContext(Type parameterType, bool hasDefaultValue, object defaultValue, int argumentIndex, object serviceKey)
			{
				ParameterType = parameterType;
				HasDefaultValue = hasDefaultValue;
				DefaultValue = defaultValue;
				ArgumentIndex = argumentIndex;
				ServiceKey = serviceKey;
			}
		}

		private sealed class ConstructorInfoEx
		{
			public readonly ConstructorInfo Info;

			public readonly ParameterInfo[] Parameters;

			public readonly bool IsPreferred;

			private readonly object[] _parameterKeys;

			public ConstructorInfoEx(ConstructorInfo constructor)
			{
				Info = constructor;
				Parameters = constructor.GetParameters();
				IsPreferred = constructor.IsDefined(typeof(ActivatorUtilitiesConstructorAttribute), inherit: false);
				for (int i = 0; i < Parameters.Length; i++)
				{
					FromKeyedServicesAttribute fromKeyedServicesAttribute = (FromKeyedServicesAttribute)Attribute.GetCustomAttribute(Parameters[i], typeof(FromKeyedServicesAttribute), inherit: false);
					if (fromKeyedServicesAttribute != null)
					{
						if (_parameterKeys == null)
						{
							_parameterKeys = new object[Parameters.Length];
						}
						_parameterKeys[i] = fromKeyedServicesAttribute.Key;
					}
				}
			}

			public bool IsService(IServiceProviderIsService serviceProviderIsService, int parameterIndex)
			{
				ParameterInfo parameterInfo = Parameters[parameterIndex];
				object[] parameterKeys = _parameterKeys;
				object obj = ((parameterKeys != null) ? parameterKeys[parameterIndex] : null);
				if (obj != null)
				{
					if (serviceProviderIsService is IServiceProviderIsKeyedService serviceProviderIsKeyedService)
					{
						return serviceProviderIsKeyedService.IsKeyedService(parameterInfo.ParameterType, obj);
					}
					throw new InvalidOperationException(System.SR.KeyedServicesNotSupported);
				}
				return serviceProviderIsService.IsService(parameterInfo.ParameterType);
			}

			public object GetService(IServiceProvider serviceProvider, int parameterIndex)
			{
				ParameterInfo parameterInfo = Parameters[parameterIndex];
				object[] parameterKeys = _parameterKeys;
				object obj = ((parameterKeys != null) ? parameterKeys[parameterIndex] : null);
				if (obj != null)
				{
					if (serviceProvider is IKeyedServiceProvider keyedServiceProvider)
					{
						return keyedServiceProvider.GetKeyedService(parameterInfo.ParameterType, obj);
					}
					throw new InvalidOperationException(System.SR.KeyedServicesNotSupported);
				}
				return serviceProvider.GetService(parameterInfo.ParameterType);
			}
		}

		private readonly struct ConstructorMatcher
		{
			private readonly ConstructorInfoEx _constructor;

			private readonly object[] _parameterValues;

			public ConstructorMatcher(ConstructorInfoEx constructor)
			{
				_constructor = constructor;
				_parameterValues = new object[constructor.Parameters.Length];
			}

			public int Match(object[] givenParameters, IServiceProviderIsService serviceProviderIsService)
			{
				for (int i = 0; i < givenParameters.Length; i++)
				{
					Type c = givenParameters[i]?.GetType();
					bool flag = false;
					for (int j = 0; j < _constructor.Parameters.Length; j++)
					{
						if (_parameterValues[j] == null && _constructor.Parameters[j].ParameterType.IsAssignableFrom(c))
						{
							flag = true;
							_parameterValues[j] = givenParameters[i];
							break;
						}
					}
					if (!flag)
					{
						return -1;
					}
				}
				for (int k = 0; k < _constructor.Parameters.Length; k++)
				{
					if (_parameterValues[k] == null && !_constructor.IsService(serviceProviderIsService, k))
					{
						if (!ParameterDefaultValue.TryGetDefaultValue(_constructor.Parameters[k], out object defaultValue))
						{
							return -1;
						}
						_parameterValues[k] = defaultValue;
					}
				}
				return _constructor.Parameters.Length;
			}

			public object CreateInstance(IServiceProvider provider)
			{
				for (int i = 0; i < _constructor.Parameters.Length; i++)
				{
					if (_parameterValues[i] != null)
					{
						continue;
					}
					object service = _constructor.GetService(provider, i);
					if (service == null)
					{
						if (!ParameterDefaultValue.TryGetDefaultValue(_constructor.Parameters[i], out object defaultValue))
						{
							throw new InvalidOperationException(System.SR.Format(System.SR.UnableToResolveService, _constructor.Parameters[i].ParameterType, _constructor.Info.DeclaringType));
						}
						_parameterValues[i] = defaultValue;
					}
					else
					{
						_parameterValues[i] = service;
					}
				}
				return _constructor.Info.Invoke(BindingFlags.DoNotWrapExceptions, null, _parameterValues, null);
			}

			public void MapParameters(int?[] parameterMap, object[] givenParameters)
			{
				for (int i = 0; i < _constructor.Parameters.Length; i++)
				{
					if (parameterMap[i].HasValue)
					{
						_parameterValues[i] = givenParameters[parameterMap[i].Value];
					}
				}
			}
		}

		private static readonly MethodInfo GetServiceInfo = GetMethodInfo<Func<IServiceProvider, Type, Type, bool, object, object>>((IServiceProvider sp, Type t, Type r, bool c, object k) => GetService(sp, t, r, c, k));

		public static object CreateInstance(IServiceProvider provider, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type instanceType, params object[] parameters)
		{
			if (provider == null)
			{
				throw new ArgumentNullException("provider");
			}
			if (instanceType.IsAbstract)
			{
				throw new InvalidOperationException(System.SR.CannotCreateAbstractClasses);
			}
			ConstructorInfoEx[] array = CreateConstructorInfoExs(instanceType);
			IServiceProviderIsService service = provider.GetService<IServiceProviderIsService>();
			ConstructorInfoEx constructorInfoEx;
			if (service != null)
			{
				int num = -1;
				bool flag = false;
				ConstructorMatcher constructorMatcher = default(ConstructorMatcher);
				bool flag2 = false;
				for (int i = 0; i < array.Length; i++)
				{
					constructorInfoEx = array[i];
					ConstructorMatcher constructorMatcher2 = new ConstructorMatcher(constructorInfoEx);
					bool isPreferred = constructorInfoEx.IsPreferred;
					int num2 = constructorMatcher2.Match(parameters, service);
					if (isPreferred)
					{
						if (flag)
						{
							ThrowMultipleCtorsMarkedWithAttributeException();
						}
						if (num2 == -1)
						{
							ThrowMarkedCtorDoesNotTakeAllProvidedArguments();
						}
					}
					if (isPreferred || num < num2)
					{
						num = num2;
						constructorMatcher = constructorMatcher2;
						flag2 = false;
					}
					else if (num == num2)
					{
						flag2 = true;
					}
					flag = flag || isPreferred;
				}
				if (num != -1)
				{
					if (flag2)
					{
						throw new InvalidOperationException(System.SR.Format(System.SR.MultipleCtorsFoundWithBestLength, instanceType, num));
					}
					return constructorMatcher.CreateInstance(provider);
				}
			}
			Type[] array2;
			if (parameters.Length == 0)
			{
				array2 = Type.EmptyTypes;
			}
			else
			{
				array2 = new Type[parameters.Length];
				for (int j = 0; j < array2.Length; j++)
				{
					array2[j] = parameters[j]?.GetType();
				}
			}
			FindApplicableConstructor(instanceType, array2, out var matchingConstructor, out var matchingParameterMap);
			constructorInfoEx = null;
			ConstructorInfoEx[] array3 = array;
			foreach (ConstructorInfoEx constructorInfoEx2 in array3)
			{
				if ((object)constructorInfoEx2.Info == matchingConstructor)
				{
					constructorInfoEx = constructorInfoEx2;
					break;
				}
			}
			ConstructorMatcher constructorMatcher3 = new ConstructorMatcher(constructorInfoEx);
			constructorMatcher3.MapParameters(matchingParameterMap, parameters);
			return constructorMatcher3.CreateInstance(provider);
		}

		private static ConstructorInfoEx[] CreateConstructorInfoExs([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type)
		{
			ConstructorInfo[] constructors = type.GetConstructors();
			ConstructorInfoEx[] array = new ConstructorInfoEx[constructors.Length];
			for (int i = 0; i < constructors.Length; i++)
			{
				array[i] = new ConstructorInfoEx(constructors[i]);
			}
			return array;
		}

		public static ObjectFactory CreateFactory([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type instanceType, Type[] argumentTypes)
		{
			if (!RuntimeFeature.IsDynamicCodeCompiled)
			{
				return CreateFactoryReflection(instanceType, argumentTypes);
			}
			CreateFactoryInternal(instanceType, argumentTypes, out var provider, out var argumentArray, out var factoryExpressionBody);
			Expression<Func<IServiceProvider, object[], object>> expression = Expression.Lambda<Func<IServiceProvider, object[], object>>(factoryExpressionBody, new ParameterExpression[2] { provider, argumentArray });
			Func<IServiceProvider, object[], object> @object = expression.Compile();
			return @object.Invoke;
		}

		public static ObjectFactory<T> CreateFactory<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>(Type[] argumentTypes)
		{
			if (!RuntimeFeature.IsDynamicCodeCompiled)
			{
				ObjectFactory factory = CreateFactoryReflection(typeof(T), argumentTypes);
				return (IServiceProvider serviceProvider, object[] arguments) => (T)factory(serviceProvider, arguments);
			}
			CreateFactoryInternal(typeof(T), argumentTypes, out var provider, out var argumentArray, out var factoryExpressionBody);
			Expression<Func<IServiceProvider, object[], T>> expression = Expression.Lambda<Func<IServiceProvider, object[], T>>(factoryExpressionBody, new ParameterExpression[2] { provider, argumentArray });
			Func<IServiceProvider, object[], T> @object = expression.Compile();
			return @object.Invoke;
		}

		private static void CreateFactoryInternal([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type instanceType, Type[] argumentTypes, out ParameterExpression provider, out ParameterExpression argumentArray, out Expression factoryExpressionBody)
		{
			FindApplicableConstructor(instanceType, argumentTypes, out var matchingConstructor, out var matchingParameterMap);
			provider = Expression.Parameter(typeof(IServiceProvider), "provider");
			argumentArray = Expression.Parameter(typeof(object[]), "argumentArray");
			factoryExpressionBody = BuildFactoryExpression(matchingConstructor, matchingParameterMap, provider, argumentArray);
		}

		public static T CreateInstance<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>(IServiceProvider provider, params object[] parameters)
		{
			return (T)CreateInstance(provider, typeof(T), parameters);
		}

		public static T GetServiceOrCreateInstance<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>(IServiceProvider provider)
		{
			return (T)GetServiceOrCreateInstance(provider, typeof(T));
		}

		public static object GetServiceOrCreateInstance(IServiceProvider provider, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type)
		{
			return provider.GetService(type) ?? CreateInstance(provider, type);
		}

		private static MethodInfo GetMethodInfo<T>(Expression<T> expr)
		{
			MethodCallExpression methodCallExpression = (MethodCallExpression)expr.Body;
			return methodCallExpression.Method;
		}

		private static object GetService(IServiceProvider sp, Type type, Type requiredBy, bool hasDefaultValue, object key)
		{
			object obj = ((key == null) ? sp.GetService(type) : GetKeyedService(sp, type, key));
			if (obj == null && !hasDefaultValue)
			{
				ThrowHelperUnableToResolveService(type, requiredBy);
			}
			return obj;
		}

		[DoesNotReturn]
		private static void ThrowHelperUnableToResolveService(Type type, Type requiredBy)
		{
			throw new InvalidOperationException(System.SR.Format(System.SR.UnableToResolveService, type, requiredBy));
		}

		private static BlockExpression BuildFactoryExpression(ConstructorInfo constructor, int?[] parameterMap, Expression serviceProvider, Expression factoryArgumentArray)
		{
			ParameterInfo[] parameters = constructor.GetParameters();
			Expression[] array = new Expression[parameters.Length];
			for (int i = 0; i < parameters.Length; i++)
			{
				ParameterInfo parameterInfo = parameters[i];
				Type parameterType = parameterInfo.ParameterType;
				object defaultValue;
				bool flag = ParameterDefaultValue.TryGetDefaultValue(parameterInfo, out defaultValue);
				if (parameterMap[i].HasValue)
				{
					array[i] = Expression.ArrayAccess(factoryArgumentArray, Expression.Constant(parameterMap[i]));
				}
				else
				{
					FromKeyedServicesAttribute fromKeyedServicesAttribute = (FromKeyedServicesAttribute)Attribute.GetCustomAttribute(parameterInfo, typeof(FromKeyedServicesAttribute), inherit: false);
					Expression[] arguments = new Expression[5]
					{
						serviceProvider,
						Expression.Constant(parameterType, typeof(Type)),
						Expression.Constant(constructor.DeclaringType, typeof(Type)),
						Expression.Constant(flag),
						Expression.Constant(fromKeyedServicesAttribute?.Key)
					};
					array[i] = Expression.Call(GetServiceInfo, arguments);
				}
				if (flag)
				{
					ConstantExpression right = Expression.Constant(defaultValue);
					array[i] = Expression.Coalesce(array[i], right);
				}
				array[i] = Expression.Convert(array[i], parameterType);
			}
			return Expression.Block(Expression.IfThen(Expression.Equal(serviceProvider, Expression.Constant(null)), Expression.Throw(Expression.Constant(new ArgumentNullException("serviceProvider")))), Expression.New(constructor, array));
		}

		[DoesNotReturn]
		private static void ThrowHelperArgumentNullExceptionServiceProvider()
		{
			throw new ArgumentNullException("serviceProvider");
		}

		private static ObjectFactory CreateFactoryReflection([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type instanceType, Type[] argumentTypes)
		{
			FindApplicableConstructor(instanceType, argumentTypes, out var constructor, out var parameterMap);
			Type declaringType = constructor.DeclaringType;
			ParameterInfo[] constructorParameters = constructor.GetParameters();
			if (constructorParameters.Length == 0)
			{
				return (IServiceProvider serviceProvider, object[] arguments) => constructor.Invoke(BindingFlags.DoNotWrapExceptions, null, null, null);
			}
			FactoryParameterContext[] parameters = GetFactoryParameterContext();
			return (IServiceProvider serviceProvider, object[] arguments) => ReflectionFactoryCanonical(constructor, parameters, declaringType, serviceProvider, arguments);
			FactoryParameterContext[] GetFactoryParameterContext()
			{
				FactoryParameterContext[] array = new FactoryParameterContext[constructorParameters.Length];
				for (int i = 0; i < constructorParameters.Length; i++)
				{
					ParameterInfo parameterInfo = constructorParameters[i];
					FromKeyedServicesAttribute fromKeyedServicesAttribute = (FromKeyedServicesAttribute)Attribute.GetCustomAttribute(parameterInfo, typeof(FromKeyedServicesAttribute), inherit: false);
					object defaultValue;
					bool hasDefaultValue = ParameterDefaultValue.TryGetDefaultValue(parameterInfo, out defaultValue);
					array[i] = new FactoryParameterContext(parameterInfo.ParameterType, hasDefaultValue, defaultValue, parameterMap[i] ?? (-1), fromKeyedServicesAttribute?.Key);
				}
				return array;
			}
		}

		private static void FindApplicableConstructor([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type instanceType, Type[] argumentTypes, out ConstructorInfo matchingConstructor, out int?[] matchingParameterMap)
		{
			if (!TryFindPreferredConstructor(instanceType, argumentTypes, out var matchingConstructor2, out var parameterMap) && !TryFindMatchingConstructor(instanceType, argumentTypes, out matchingConstructor2, out parameterMap))
			{
				throw new InvalidOperationException(System.SR.Format(System.SR.CtorNotLocated, instanceType));
			}
			matchingConstructor = matchingConstructor2;
			matchingParameterMap = parameterMap;
		}

		private static bool TryFindMatchingConstructor([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type instanceType, Type[] argumentTypes, [NotNullWhen(true)] out ConstructorInfo matchingConstructor, [NotNullWhen(true)] out int?[] parameterMap)
		{
			matchingConstructor = null;
			parameterMap = null;
			ConstructorInfo[] constructors = instanceType.GetConstructors();
			foreach (ConstructorInfo constructorInfo in constructors)
			{
				if (TryCreateParameterMap(constructorInfo.GetParameters(), argumentTypes, out var parameterMap2))
				{
					if (matchingConstructor != null)
					{
						throw new InvalidOperationException(System.SR.Format(System.SR.MultipleCtorsFound, instanceType));
					}
					matchingConstructor = constructorInfo;
					parameterMap = parameterMap2;
				}
			}
			if (matchingConstructor != null)
			{
				return true;
			}
			return false;
		}

		private static bool TryFindPreferredConstructor([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type instanceType, Type[] argumentTypes, [NotNullWhen(true)] out ConstructorInfo matchingConstructor, [NotNullWhen(true)] out int?[] parameterMap)
		{
			bool flag = false;
			matchingConstructor = null;
			parameterMap = null;
			ConstructorInfo[] constructors = instanceType.GetConstructors();
			foreach (ConstructorInfo constructorInfo in constructors)
			{
				if (constructorInfo.IsDefined(typeof(ActivatorUtilitiesConstructorAttribute), inherit: false))
				{
					if (flag)
					{
						ThrowMultipleCtorsMarkedWithAttributeException();
					}
					if (!TryCreateParameterMap(constructorInfo.GetParameters(), argumentTypes, out var parameterMap2))
					{
						ThrowMarkedCtorDoesNotTakeAllProvidedArguments();
					}
					matchingConstructor = constructorInfo;
					parameterMap = parameterMap2;
					flag = true;
				}
			}
			if (matchingConstructor != null)
			{
				return true;
			}
			return false;
		}

		private static bool TryCreateParameterMap(ParameterInfo[] constructorParameters, Type[] argumentTypes, out int?[] parameterMap)
		{
			parameterMap = new int?[constructorParameters.Length];
			for (int i = 0; i < argumentTypes.Length; i++)
			{
				bool flag = false;
				Type c = argumentTypes[i];
				for (int j = 0; j < constructorParameters.Length; j++)
				{
					if (!parameterMap[j].HasValue && constructorParameters[j].ParameterType.IsAssignableFrom(c))
					{
						flag = true;
						parameterMap[j] = i;
						break;
					}
				}
				if (!flag)
				{
					return false;
				}
			}
			return true;
		}

		private static void ThrowMultipleCtorsMarkedWithAttributeException()
		{
			throw new InvalidOperationException(System.SR.Format(System.SR.MultipleCtorsMarkedWithAttribute, "ActivatorUtilitiesConstructorAttribute"));
		}

		private static void ThrowMarkedCtorDoesNotTakeAllProvidedArguments()
		{
			throw new InvalidOperationException(System.SR.Format(System.SR.MarkedCtorMissingArgumentTypes, "ActivatorUtilitiesConstructorAttribute"));
		}

		private static object ReflectionFactoryCanonical(ConstructorInfo constructor, FactoryParameterContext[] parameters, Type declaringType, IServiceProvider serviceProvider, object[] arguments)
		{
			if (serviceProvider == null)
			{
				ThrowHelperArgumentNullExceptionServiceProvider();
			}
			object[] array = new object[parameters.Length];
			for (int i = 0; i < parameters.Length; i++)
			{
				ref FactoryParameterContext reference = ref parameters[i];
				array[i] = ((reference.ArgumentIndex != -1) ? arguments[reference.ArgumentIndex] : GetService(serviceProvider, reference.ParameterType, declaringType, reference.HasDefaultValue, reference.ServiceKey)) ?? reference.DefaultValue;
			}
			return constructor.Invoke(BindingFlags.DoNotWrapExceptions, null, array, null);
		}

		private static object GetKeyedService(IServiceProvider provider, Type type, object serviceKey)
		{
			System.ThrowHelper.ThrowIfNull(provider, "provider");
			if (provider is IKeyedServiceProvider keyedServiceProvider)
			{
				return keyedServiceProvider.GetKeyedService(type, serviceKey);
			}
			throw new InvalidOperationException(System.SR.KeyedServicesNotSupported);
		}
	}
	[AttributeUsage(AttributeTargets.All)]
	public class ActivatorUtilitiesConstructorAttribute : Attribute
	{
	}
	[DebuggerDisplay("{ServiceProvider,nq}")]
	public readonly struct AsyncServiceScope : IServiceScope, IDisposable, IAsyncDisposable
	{
		private readonly IServiceScope _serviceScope;

		public IServiceProvider ServiceProvider => _serviceScope.ServiceProvider;

		public AsyncServiceScope(IServiceScope serviceScope)
		{
			System.ThrowHelper.ThrowIfNull(serviceScope, "serviceScope");
			_serviceScope = serviceScope;
		}

		public void Dispose()
		{
			_serviceScope.Dispose();
		}

		public ValueTask DisposeAsync()
		{
			if (_serviceScope is IAsyncDisposable asyncDisposable)
			{
				return asyncDisposable.DisposeAsync();
			}
			_serviceScope.Dispose();
			return default(ValueTask);
		}
	}
	[AttributeUsage(AttributeTargets.Parameter)]
	public class FromKeyedServicesAttribute : Attribute
	{
		public object Key { get; }

		public FromKeyedServicesAttribute(object key)
		{
			Key = key;
		}
	}
	public interface IKeyedServiceProvider : IServiceProvider
	{
		object? GetKeyedService(Type serviceType, object? serviceKey);

		object GetRequiredKeyedService(Type serviceType, object? serviceKey);
	}
	public static class KeyedService
	{
		private sealed class AnyKeyObj
		{
			public override string ToString()
			{
				return "*";
			}
		}

		public static object AnyKey { get; } = new AnyKeyObj();

	}
	public interface IServiceCollection : IList<ServiceDescriptor>, ICollection<ServiceDescriptor>, IEnumerable<ServiceDescriptor>, IEnumerable
	{
	}
	public interface IServiceProviderFactory<TContainerBuilder> where TContainerBuilder : notnull
	{
		TContainerBuilder CreateBuilder(IServiceCollection services);

		IServiceProvider CreateServiceProvider(TContainerBuilder containerBuilder);
	}
	public interface IServiceProviderIsKeyedService : IServiceProviderIsService
	{
		bool IsKeyedService(Type serviceType, object? serviceKey);
	}
	public interface IServiceProviderIsService
	{
		bool IsService(Type serviceType);
	}
	public interface IServiceScope : IDisposable
	{
		IServiceProvider ServiceProvider { get; }
	}
	public interface IServiceScopeFactory
	{
		IServiceScope CreateScope();
	}
	public interface ISupportRequiredService
	{
		object GetRequiredService(Type serviceType);
	}
	public delegate object ObjectFactory(IServiceProvider serviceProvider, object?[]? arguments);
	public delegate T ObjectFactory<T>(IServiceProvider serviceProvider, object?[]? arguments);
	[DebuggerDisplay("{DebuggerToString(),nq}")]
	[DebuggerTypeProxy(typeof(ServiceCollectionDebugView))]
	public class ServiceCollection : IServiceCollection, IList<ServiceDescriptor>, ICollection<ServiceDescriptor>, IEnumerable<ServiceDescriptor>, IEnumerable
	{
		private sealed class ServiceCollectionDebugView
		{
			private readonly ServiceCollection _services;

			[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
			public ServiceDescriptor[] Items
			{
				get
				{
					ServiceDescriptor[] array = new ServiceDescriptor[_services.Count];
					_services.CopyTo(array, 0);
					return array;
				}
			}

			public ServiceCollectionDebugView(ServiceCollection services)
			{
				_services = services;
			}
		}

		private readonly List<ServiceDescriptor> _descriptors = new List<ServiceDescriptor>();

		private bool _isReadOnly;

		public int Count => _descriptors.Count;

		public bool IsReadOnly => _isReadOnly;

		public ServiceDescriptor this[int index]
		{
			get
			{
				return _descriptors[index];
			}
			set
			{
				CheckReadOnly();
				_descriptors[index] = value;
			}
		}

		public void Clear()
		{
			CheckReadOnly();
			_descriptors.Clear();
		}

		public bool Contains(ServiceDescriptor item)
		{
			return _descriptors.Contains(item);
		}

		public void CopyTo(ServiceDescriptor[] array, int arrayIndex)
		{
			_descriptors.CopyTo(array, arrayIndex);
		}

		public bool Remove(ServiceDescriptor item)
		{
			CheckReadOnly();
			return _descriptors.Remove(item);
		}

		public IEnumerator<ServiceDescriptor> GetEnumerator()
		{
			return _descriptors.GetEnumerator();
		}

		void ICollection<ServiceDescriptor>.Add(ServiceDescriptor item)
		{
			CheckReadOnly();
			_descriptors.Add(item);
		}

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

		public int IndexOf(ServiceDescriptor item)
		{
			return _descriptors.IndexOf(item);
		}

		public void Insert(int index, ServiceDescriptor item)
		{
			CheckReadOnly();
			_descriptors.Insert(index, item);
		}

		public void RemoveAt(int index)
		{
			CheckReadOnly();
			_descriptors.RemoveAt(index);
		}

		public void MakeReadOnly()
		{
			_isReadOnly = true;
		}

		private void CheckReadOnly()
		{
			if (_isReadOnly)
			{
				ThrowReadOnlyException();
			}
		}

		private static void ThrowReadOnlyException()
		{
			throw new InvalidOperationException(System.SR.ServiceCollectionReadOnly);
		}

		private string DebuggerToString()
		{
			string text = $"Count = {_descriptors.Count}";
			if (_isReadOnly)
			{
				text += ", IsReadOnly = true";
			}
			return text;
		}
	}
	public static class ServiceCollectionServiceExtensions
	{
		public static IServiceCollection AddTransient(this IServiceCollection services, Type serviceType, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			System.ThrowHelper.ThrowIfNull(implementationType, "implementationType");
			return Add(services, serviceType, implementationType, ServiceLifetime.Transient);
		}

		public static IServiceCollection AddTransient(this IServiceCollection services, Type serviceType, Func<IServiceProvider, object> implementationFactory)
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return Add(services, serviceType, implementationFactory, ServiceLifetime.Transient);
		}

		public static IServiceCollection AddTransient<TService, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>(this IServiceCollection services) where TService : class where TImplementation : class, TService
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			return services.AddTransient(typeof(TService), typeof(TImplementation));
		}

		public static IServiceCollection AddTransient(this IServiceCollection services, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type serviceType)
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			return services.AddTransient(serviceType, serviceType);
		}

		public static IServiceCollection AddTransient<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this IServiceCollection services) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			return services.AddTransient(typeof(TService));
		}

		public static IServiceCollection AddTransient<TService>(this IServiceCollection services, Func<IServiceProvider, TService> implementationFactory) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return services.AddTransient(typeof(TService), implementationFactory);
		}

		public static IServiceCollection AddTransient<TService, TImplementation>(this IServiceCollection services, Func<IServiceProvider, TImplementation> implementationFactory) where TService : class where TImplementation : class, TService
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return services.AddTransient(typeof(TService), implementationFactory);
		}

		public static IServiceCollection AddScoped(this IServiceCollection services, Type serviceType, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			System.ThrowHelper.ThrowIfNull(implementationType, "implementationType");
			return Add(services, serviceType, implementationType, ServiceLifetime.Scoped);
		}

		public static IServiceCollection AddScoped(this IServiceCollection services, Type serviceType, Func<IServiceProvider, object> implementationFactory)
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return Add(services, serviceType, implementationFactory, ServiceLifetime.Scoped);
		}

		public static IServiceCollection AddScoped<TService, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>(this IServiceCollection services) where TService : class where TImplementation : class, TService
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			return services.AddScoped(typeof(TService), typeof(TImplementation));
		}

		public static IServiceCollection AddScoped(this IServiceCollection services, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type serviceType)
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			return services.AddScoped(serviceType, serviceType);
		}

		public static IServiceCollection AddScoped<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this IServiceCollection services) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			return services.AddScoped(typeof(TService));
		}

		public static IServiceCollection AddScoped<TService>(this IServiceCollection services, Func<IServiceProvider, TService> implementationFactory) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return services.AddScoped(typeof(TService), implementationFactory);
		}

		public static IServiceCollection AddScoped<TService, TImplementation>(this IServiceCollection services, Func<IServiceProvider, TImplementation> implementationFactory) where TService : class where TImplementation : class, TService
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return services.AddScoped(typeof(TService), implementationFactory);
		}

		public static IServiceCollection AddSingleton(this IServiceCollection services, Type serviceType, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			System.ThrowHelper.ThrowIfNull(implementationType, "implementationType");
			return Add(services, serviceType, implementationType, ServiceLifetime.Singleton);
		}

		public static IServiceCollection AddSingleton(this IServiceCollection services, Type serviceType, Func<IServiceProvider, object> implementationFactory)
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return Add(services, serviceType, implementationFactory, ServiceLifetime.Singleton);
		}

		public static IServiceCollection AddSingleton<TService, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>(this IServiceCollection services) where TService : class where TImplementation : class, TService
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			return services.AddSingleton(typeof(TService), typeof(TImplementation));
		}

		public static IServiceCollection AddSingleton(this IServiceCollection services, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type serviceType)
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			return services.AddSingleton(serviceType, serviceType);
		}

		public static IServiceCollection AddSingleton<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this IServiceCollection services) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			return services.AddSingleton(typeof(TService));
		}

		public static IServiceCollection AddSingleton<TService>(this IServiceCollection services, Func<IServiceProvider, TService> implementationFactory) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return services.AddSingleton(typeof(TService), implementationFactory);
		}

		public static IServiceCollection AddSingleton<TService, TImplementation>(this IServiceCollection services, Func<IServiceProvider, TImplementation> implementationFactory) where TService : class where TImplementation : class, TService
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return services.AddSingleton(typeof(TService), implementationFactory);
		}

		public static IServiceCollection AddSingleton(this IServiceCollection services, Type serviceType, object implementationInstance)
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			System.ThrowHelper.ThrowIfNull(implementationInstance, "implementationInstance");
			ServiceDescriptor item = new ServiceDescriptor(serviceType, implementationInstance);
			services.Add(item);
			return services;
		}

		public static IServiceCollection AddSingleton<TService>(this IServiceCollection services, TService implementationInstance) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(implementationInstance, "implementationInstance");
			return services.AddSingleton(typeof(TService), implementationInstance);
		}

		private static IServiceCollection Add(IServiceCollection collection, Type serviceType, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType, ServiceLifetime lifetime)
		{
			ServiceDescriptor item = new ServiceDescriptor(serviceType, implementationType, lifetime);
			collection.Add(item);
			return collection;
		}

		private static IServiceCollection Add(IServiceCollection collection, Type serviceType, Func<IServiceProvider, object> implementationFactory, ServiceLifetime lifetime)
		{
			ServiceDescriptor item = new ServiceDescriptor(serviceType, implementationFactory, lifetime);
			collection.Add(item);
			return collection;
		}

		public static IServiceCollection AddKeyedTransient(this IServiceCollection services, Type serviceType, object? serviceKey, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			System.ThrowHelper.ThrowIfNull(implementationType, "implementationType");
			return AddKeyed(services, serviceType, serviceKey, implementationType, ServiceLifetime.Transient);
		}

		public static IServiceCollection AddKeyedTransient(this IServiceCollection services, Type serviceType, object? serviceKey, Func<IServiceProvider, object?, object> implementationFactory)
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return AddKeyed(services, serviceType, serviceKey, implementationFactory, ServiceLifetime.Transient);
		}

		public static IServiceCollection AddKeyedTransient<TService, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>(this IServiceCollection services, object? serviceKey) where TService : class where TImplementation : class, TService
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			return services.AddKeyedTransient(typeof(TService), serviceKey, typeof(TImplementation));
		}

		public static IServiceCollection AddKeyedTransient(this IServiceCollection services, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type serviceType, object? serviceKey)
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			return services.AddKeyedTransient(serviceType, serviceKey, serviceType);
		}

		public static IServiceCollection AddKeyedTransient<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this IServiceCollection services, object? serviceKey) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			return services.AddKeyedTransient(typeof(TService), serviceKey);
		}

		public static IServiceCollection AddKeyedTransient<TService>(this IServiceCollection services, object? serviceKey, Func<IServiceProvider, object?, TService> implementationFactory) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return services.AddKeyedTransient(typeof(TService), serviceKey, implementationFactory);
		}

		public static IServiceCollection AddKeyedTransient<TService, TImplementation>(this IServiceCollection services, object? serviceKey, Func<IServiceProvider, object?, TImplementation> implementationFactory) where TService : class where TImplementation : class, TService
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return services.AddKeyedTransient(typeof(TService), serviceKey, implementationFactory);
		}

		public static IServiceCollection AddKeyedScoped(this IServiceCollection services, Type serviceType, object? serviceKey, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			System.ThrowHelper.ThrowIfNull(implementationType, "implementationType");
			return AddKeyed(services, serviceType, serviceKey, implementationType, ServiceLifetime.Scoped);
		}

		public static IServiceCollection AddKeyedScoped(this IServiceCollection services, Type serviceType, object? serviceKey, Func<IServiceProvider, object?, object> implementationFactory)
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return AddKeyed(services, serviceType, serviceKey, implementationFactory, ServiceLifetime.Scoped);
		}

		public static IServiceCollection AddKeyedScoped<TService, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>(this IServiceCollection services, object? serviceKey) where TService : class where TImplementation : class, TService
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			return services.AddKeyedScoped(typeof(TService), serviceKey, typeof(TImplementation));
		}

		public static IServiceCollection AddKeyedScoped(this IServiceCollection services, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type serviceType, object? serviceKey)
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			return services.AddKeyedScoped(serviceType, serviceKey, serviceType);
		}

		public static IServiceCollection AddKeyedScoped<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this IServiceCollection services, object? serviceKey) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			return services.AddKeyedScoped(typeof(TService), serviceKey);
		}

		public static IServiceCollection AddKeyedScoped<TService>(this IServiceCollection services, object? serviceKey, Func<IServiceProvider, object?, TService> implementationFactory) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return services.AddKeyedScoped(typeof(TService), serviceKey, implementationFactory);
		}

		public static IServiceCollection AddKeyedScoped<TService, TImplementation>(this IServiceCollection services, object? serviceKey, Func<IServiceProvider, object?, TImplementation> implementationFactory) where TService : class where TImplementation : class, TService
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return services.AddKeyedScoped(typeof(TService), serviceKey, implementationFactory);
		}

		public static IServiceCollection AddKeyedSingleton(this IServiceCollection services, Type serviceType, object? serviceKey, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			System.ThrowHelper.ThrowIfNull(implementationType, "implementationType");
			return AddKeyed(services, serviceType, serviceKey, implementationType, ServiceLifetime.Singleton);
		}

		public static IServiceCollection AddKeyedSingleton(this IServiceCollection services, Type serviceType, object? serviceKey, Func<IServiceProvider, object?, object> implementationFactory)
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return AddKeyed(services, serviceType, serviceKey, implementationFactory, ServiceLifetime.Singleton);
		}

		public static IServiceCollection AddKeyedSingleton<TService, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>(this IServiceCollection services, object? serviceKey) where TService : class where TImplementation : class, TService
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			return services.AddKeyedSingleton(typeof(TService), serviceKey, typeof(TImplementation));
		}

		public static IServiceCollection AddKeyedSingleton(this IServiceCollection services, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type serviceType, object? serviceKey)
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			return services.AddKeyedSingleton(serviceType, serviceKey, serviceType);
		}

		public static IServiceCollection AddKeyedSingleton<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this IServiceCollection services, object? serviceKey) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			return services.AddKeyedSingleton(typeof(TService), serviceKey, typeof(TService));
		}

		public static IServiceCollection AddKeyedSingleton<TService>(this IServiceCollection services, object? serviceKey, Func<IServiceProvider, object?, TService> implementationFactory) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return services.AddKeyedSingleton(typeof(TService), serviceKey, implementationFactory);
		}

		public static IServiceCollection AddKeyedSingleton<TService, TImplementation>(this IServiceCollection services, object? serviceKey, Func<IServiceProvider, object?, TImplementation> implementationFactory) where TService : class where TImplementation : class, TService
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return services.AddKeyedSingleton(typeof(TService), serviceKey, implementationFactory);
		}

		public static IServiceCollection AddKeyedSingleton(this IServiceCollection services, Type serviceType, object? serviceKey, object implementationInstance)
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			System.ThrowHelper.ThrowIfNull(implementationInstance, "implementationInstance");
			ServiceDescriptor item = new ServiceDescriptor(serviceType, serviceKey, implementationInstance);
			services.Add(item);
			return services;
		}

		public static IServiceCollection AddKeyedSingleton<TService>(this IServiceCollection services, object? serviceKey, TService implementationInstance) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(implementationInstance, "implementationInstance");
			return services.AddKeyedSingleton(typeof(TService), serviceKey, implementationInstance);
		}

		private static IServiceCollection AddKeyed(IServiceCollection collection, Type serviceType, object serviceKey, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType, ServiceLifetime lifetime)
		{
			ServiceDescriptor item = new ServiceDescriptor(serviceType, serviceKey, implementationType, lifetime);
			collection.Add(item);
			return collection;
		}

		private static IServiceCollection AddKeyed(IServiceCollection collection, Type serviceType, object serviceKey, Func<IServiceProvider, object, object> implementationFactory, ServiceLifetime lifetime)
		{
			ServiceDescriptor item = new ServiceDescriptor(serviceType, serviceKey, implementationFactory, lifetime);
			collection.Add(item);
			return collection;
		}
	}
	[DebuggerDisplay("{DebuggerToString(),nq}")]
	public class ServiceDescriptor
	{
		[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]
		private Type _implementationType;

		private object _implementationInstance;

		private object _implementationFactory;

		public ServiceLifetime Lifetime { get; }

		public object? ServiceKey { get; }

		public Type ServiceType { get; }

		[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]
		public Type? ImplementationType
		{
			get
			{
				if (IsKeyedService)
				{
					ThrowKeyedDescriptor();
				}
				return _implementationType;
			}
		}

		[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]
		public Type? KeyedImplementationType
		{
			get
			{
				if (!IsKeyedService)
				{
					ThrowNonKeyedDescriptor();
				}
				return _implementationType;
			}
		}

		public object? ImplementationInstance
		{
			get
			{
				if (IsKeyedService)
				{
					ThrowKeyedDescriptor();
				}
				return _implementationInstance;
			}
		}

		public object? KeyedImplementationInstance
		{
			get
			{
				if (!IsKeyedService)
				{
					ThrowNonKeyedDescriptor();
				}
				return _implementationInstance;
			}
		}

		public Func<IServiceProvider, object>? ImplementationFactory
		{
			get
			{
				if (IsKeyedService)
				{
					ThrowKeyedDescriptor();
				}
				return (Func<IServiceProvider, object>)_implementationFactory;
			}
		}

		public Func<IServiceProvider, object?, object>? KeyedImplementationFactory
		{
			get
			{
				if (!IsKeyedService)
				{
					ThrowNonKeyedDescriptor();
				}
				return (Func<IServiceProvider, object, object>)_implementationFactory;
			}
		}

		public bool IsKeyedService => ServiceKey != null;

		public ServiceDescriptor(Type serviceType, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType, ServiceLifetime lifetime)
			: this(serviceType, null, implementationType, lifetime)
		{
		}

		public ServiceDescriptor(Type serviceType, object? serviceKey, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType, ServiceLifetime lifetime)
			: this(serviceType, serviceKey, lifetime)
		{
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			System.ThrowHelper.ThrowIfNull(implementationType, "implementationType");
			_implementationType = implementationType;
		}

		public ServiceDescriptor(Type serviceType, object instance)
			: this(serviceType, null, instance)
		{
		}

		public ServiceDescriptor(Type serviceType, object? serviceKey, object instance)
			: this(serviceType, serviceKey, ServiceLifetime.Singleton)
		{
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			System.ThrowHelper.ThrowIfNull(instance, "instance");
			_implementationInstance = instance;
		}

		public ServiceDescriptor(Type serviceType, Func<IServiceProvider, object> factory, ServiceLifetime lifetime)
			: this(serviceType, (object)null, lifetime)
		{
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			System.ThrowHelper.ThrowIfNull(factory, "factory");
			_implementationFactory = factory;
		}

		public ServiceDescriptor(Type serviceType, object? serviceKey, Func<IServiceProvider, object?, object> factory, ServiceLifetime lifetime)
		{
			Func<IServiceProvider, object, object> factory2 = factory;
			this..ctor(serviceType, serviceKey, lifetime);
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			System.ThrowHelper.ThrowIfNull(factory2, "factory");
			if (serviceKey == null)
			{
				Func<IServiceProvider, object> implementationFactory = (IServiceProvider sp) => factory2(sp, null);
				_implementationFactory = implementationFactory;
			}
			else
			{
				_implementationFactory = factory2;
			}
		}

		private ServiceDescriptor(Type serviceType, object serviceKey, ServiceLifetime lifetime)
		{
			Lifetime = lifetime;
			ServiceType = serviceType;
			ServiceKey = serviceKey;
		}

		public override string ToString()
		{
			string text = string.Format("{0}: {1} {2}: {3} ", "ServiceType", ServiceType, "Lifetime", Lifetime);
			if (IsKeyedService)
			{
				text += string.Format("{0}: {1} ", "ServiceKey", ServiceKey);
				if (KeyedImplementationType != null)
				{
					return text + string.Format("{0}: {1}", "KeyedImplementationType", KeyedImplementationType);
				}
				if (KeyedImplementationFactory != null)
				{
					return text + string.Format("{0}: {1}", "KeyedImplementationFactory", KeyedImplementationFactory.Method);
				}
				return text + string.Format("{0}: {1}", "KeyedImplementationInstance", KeyedImplementationInstance);
			}
			if (ImplementationType != null)
			{
				return text + string.Format("{0}: {1}", "ImplementationType", ImplementationType);
			}
			if (ImplementationFactory != null)
			{
				return text + string.Format("{0}: {1}", "ImplementationFactory", ImplementationFactory.Method);
			}
			return text + string.Format("{0}: {1}", "ImplementationInstance", ImplementationInstance);
		}

		internal Type GetImplementationType()
		{
			if (ServiceKey == null)
			{
				if (ImplementationType != null)
				{
					return ImplementationType;
				}
				if (ImplementationInstance != null)
				{
					return ImplementationInstance.GetType();
				}
				if (ImplementationFactory != null)
				{
					Type[] genericTypeArguments = ImplementationFactory.GetType().GenericTypeArguments;
					return genericTypeArguments[1];
				}
			}
			else
			{
				if (KeyedImplementationType != null)
				{
					return KeyedImplementationType;
				}
				if (KeyedImplementationInstance != null)
				{
					return KeyedImplementationInstance.GetType();
				}
				if (KeyedImplementationFactory != null)
				{
					Type[] genericTypeArguments2 = KeyedImplementationFactory.GetType().GenericTypeArguments;
					return genericTypeArguments2[2];
				}
			}
			return null;
		}

		public static ServiceDescriptor Transient<TService, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>() where TService : class where TImplementation : class, TService
		{
			return DescribeKeyed<TService, TImplementation>((object)null, ServiceLifetime.Transient);
		}

		public static ServiceDescriptor KeyedTransient<TService, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>(object? serviceKey) where TService : class where TImplementation : class, TService
		{
			return DescribeKeyed<TService, TImplementation>(serviceKey, ServiceLifetime.Transient);
		}

		public static ServiceDescriptor Transient(Type service, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
		{
			System.ThrowHelper.ThrowIfNull(service, "service");
			System.ThrowHelper.ThrowIfNull(implementationType, "implementationType");
			return Describe(service, implementationType, ServiceLifetime.Transient);
		}

		public static ServiceDescriptor KeyedTransient(Type service, object? serviceKey, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
		{
			System.ThrowHelper.ThrowIfNull(service, "service");
			System.ThrowHelper.ThrowIfNull(implementationType, "implementationType");
			return DescribeKeyed(service, serviceKey, implementationType, ServiceLifetime.Transient);
		}

		public static ServiceDescriptor Transient<TService, TImplementation>(Func<IServiceProvider, TImplementation> implementationFactory) where TService : class where TImplementation : class, TService
		{
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return Describe(typeof(TService), implementationFactory, ServiceLifetime.Transient);
		}

		public static ServiceDescriptor KeyedTransient<TService, TImplementation>(object? serviceKey, Func<IServiceProvider, object?, TImplementation> implementationFactory) where TService : class where TImplementation : class, TService
		{
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return DescribeKeyed(typeof(TService), serviceKey, implementationFactory, ServiceLifetime.Transient);
		}

		public static ServiceDescriptor Transient<TService>(Func<IServiceProvider, TService> implementationFactory) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return Describe(typeof(TService), implementationFactory, ServiceLifetime.Transient);
		}

		public static ServiceDescriptor KeyedTransient<TService>(object? serviceKey, Func<IServiceProvider, object?, TService> implementationFactory) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return DescribeKeyed(typeof(TService), serviceKey, implementationFactory, ServiceLifetime.Transient);
		}

		public static ServiceDescriptor Transient(Type service, Func<IServiceProvider, object> implementationFactory)
		{
			System.ThrowHelper.ThrowIfNull(service, "service");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return Describe(service, implementationFactory, ServiceLifetime.Transient);
		}

		public static ServiceDescriptor KeyedTransient(Type service, object? serviceKey, Func<IServiceProvider, object?, object> implementationFactory)
		{
			System.ThrowHelper.ThrowIfNull(service, "service");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return DescribeKeyed(service, serviceKey, implementationFactory, ServiceLifetime.Transient);
		}

		public static ServiceDescriptor Scoped<TService, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>() where TService : class where TImplementation : class, TService
		{
			return DescribeKeyed<TService, TImplementation>((object)null, ServiceLifetime.Scoped);
		}

		public static ServiceDescriptor KeyedScoped<TService, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>(object? serviceKey) where TService : class where TImplementation : class, TService
		{
			return DescribeKeyed<TService, TImplementation>(serviceKey, ServiceLifetime.Scoped);
		}

		public static ServiceDescriptor Scoped(Type service, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
		{
			return Describe(service, implementationType, ServiceLifetime.Scoped);
		}

		public static ServiceDescriptor KeyedScoped(Type service, object? serviceKey, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
		{
			return DescribeKeyed(service, serviceKey, implementationType, ServiceLifetime.Scoped);
		}

		public static ServiceDescriptor Scoped<TService, TImplementation>(Func<IServiceProvider, TImplementation> implementationFactory) where TService : class where TImplementation : class, TService
		{
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return Describe(typeof(TService), implementationFactory, ServiceLifetime.Scoped);
		}

		public static ServiceDescriptor KeyedScoped<TService, TImplementation>(object? serviceKey, Func<IServiceProvider, object?, TImplementation> implementationFactory) where TService : class where TImplementation : class, TService
		{
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return DescribeKeyed(typeof(TService), serviceKey, implementationFactory, ServiceLifetime.Scoped);
		}

		public static ServiceDescriptor Scoped<TService>(Func<IServiceProvider, TService> implementationFactory) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return Describe(typeof(TService), implementationFactory, ServiceLifetime.Scoped);
		}

		public static ServiceDescriptor KeyedScoped<TService>(object? serviceKey, Func<IServiceProvider, object?, TService> implementationFactory) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return DescribeKeyed(typeof(TService), serviceKey, implementationFactory, ServiceLifetime.Scoped);
		}

		public static ServiceDescriptor Scoped(Type service, Func<IServiceProvider, object> implementationFactory)
		{
			System.ThrowHelper.ThrowIfNull(service, "service");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return Describe(service, implementationFactory, ServiceLifetime.Scoped);
		}

		public static ServiceDescriptor KeyedScoped(Type service, object? serviceKey, Func<IServiceProvider, object?, object> implementationFactory)
		{
			System.ThrowHelper.ThrowIfNull(service, "service");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return DescribeKeyed(service, serviceKey, implementationFactory, ServiceLifetime.Scoped);
		}

		public static ServiceDescriptor Singleton<TService, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>() where TService : class where TImplementation : class, TService
		{
			return DescribeKeyed<TService, TImplementation>((object)null, ServiceLifetime.Singleton);
		}

		public static ServiceDescriptor KeyedSingleton<TService, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>(object? serviceKey) where TService : class where TImplementation : class, TService
		{
			return DescribeKeyed<TService, TImplementation>(serviceKey, ServiceLifetime.Singleton);
		}

		public static ServiceDescriptor Singleton(Type service, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
		{
			System.ThrowHelper.ThrowIfNull(service, "service");
			System.ThrowHelper.ThrowIfNull(implementationType, "implementationType");
			return Describe(service, implementationType, ServiceLifetime.Singleton);
		}

		public static ServiceDescriptor KeyedSingleton(Type service, object? serviceKey, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
		{
			System.ThrowHelper.ThrowIfNull(service, "service");
			System.ThrowHelper.ThrowIfNull(implementationType, "implementationType");
			return DescribeKeyed(service, serviceKey, implementationType, ServiceLifetime.Singleton);
		}

		public static ServiceDescriptor Singleton<TService, TImplementation>(Func<IServiceProvider, TImplementation> implementationFactory) where TService : class where TImplementation : class, TService
		{
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return Describe(typeof(TService), implementationFactory, ServiceLifetime.Singleton);
		}

		public static ServiceDescriptor KeyedSingleton<TService, TImplementation>(object? serviceKey, Func<IServiceProvider, object?, TImplementation> implementationFactory) where TService : class where TImplementation : class, TService
		{
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return DescribeKeyed(typeof(TService), serviceKey, implementationFactory, ServiceLifetime.Singleton);
		}

		public static ServiceDescriptor Singleton<TService>(Func<IServiceProvider, TService> implementationFactory) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return Describe(typeof(TService), implementationFactory, ServiceLifetime.Singleton);
		}

		public static ServiceDescriptor KeyedSingleton<TService>(object? serviceKey, Func<IServiceProvider, object?, TService> implementationFactory) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return DescribeKeyed(typeof(TService), serviceKey, implementationFactory, ServiceLifetime.Singleton);
		}

		public static ServiceDescriptor Singleton(Type serviceType, Func<IServiceProvider, object> implementationFactory)
		{
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return Describe(serviceType, implementationFactory, ServiceLifetime.Singleton);
		}

		public static ServiceDescriptor KeyedSingleton(Type serviceType, object? serviceKey, Func<IServiceProvider, object?, object> implementationFactory)
		{
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			return DescribeKeyed(serviceType, serviceKey, implementationFactory, ServiceLifetime.Singleton);
		}

		public static ServiceDescriptor Singleton<TService>(TService implementationInstance) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(implementationInstance, "implementationInstance");
			return Singleton(typeof(TService), implementationInstance);
		}

		public static ServiceDescriptor KeyedSingleton<TService>(object? serviceKey, TService implementationInstance) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(implementationInstance, "implementationInstance");
			return KeyedSingleton(typeof(TService), serviceKey, implementationInstance);
		}

		public static ServiceDescriptor Singleton(Type serviceType, object implementationInstance)
		{
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			System.ThrowHelper.ThrowIfNull(implementationInstance, "implementationInstance");
			return new ServiceDescriptor(serviceType, implementationInstance);
		}

		public static ServiceDescriptor KeyedSingleton(Type serviceType, object? serviceKey, object implementationInstance)
		{
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			System.ThrowHelper.ThrowIfNull(implementationInstance, "implementationInstance");
			return new ServiceDescriptor(serviceType, serviceKey, implementationInstance);
		}

		private static ServiceDescriptor DescribeKeyed<TService, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>(object serviceKey, ServiceLifetime lifetime) where TService : class where TImplementation : class, TService
		{
			return DescribeKeyed(typeof(TService), serviceKey, typeof(TImplementation), lifetime);
		}

		public static ServiceDescriptor Describe(Type serviceType, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType, ServiceLifetime lifetime)
		{
			return new ServiceDescriptor(serviceType, implementationType, lifetime);
		}

		public static ServiceDescriptor DescribeKeyed(Type serviceType, object? serviceKey, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType, ServiceLifetime lifetime)
		{
			return new ServiceDescriptor(serviceType, serviceKey, implementationType, lifetime);
		}

		public static ServiceDescriptor Describe(Type serviceType, Func<IServiceProvider, object> implementationFactory, ServiceLifetime lifetime)
		{
			return new ServiceDescriptor(serviceType, implementationFactory, lifetime);
		}

		public static ServiceDescriptor DescribeKeyed(Type serviceType, object? serviceKey, Func<IServiceProvider, object?, object> implementationFactory, ServiceLifetime lifetime)
		{
			return new ServiceDescriptor(serviceType, serviceKey, implementationFactory, lifetime);
		}

		private string DebuggerToString()
		{
			string text = $"Lifetime = {Lifetime}, ServiceType = \"{ServiceType.FullName}\"";
			if (IsKeyedService)
			{
				text += $", ServiceKey = \"{ServiceKey}\"";
				if (KeyedImplementationType != null)
				{
					return text + ", KeyedImplementationType = \"" + KeyedImplementationType.FullName + "\"";
				}
				if (KeyedImplementationFactory != null)
				{
					return text + $", KeyedImplementationFactory = {KeyedImplementationFactory.Method}";
				}
				return text + $", KeyedImplementationInstance = {KeyedImplementationInstance}";
			}
			if (ImplementationType != null)
			{
				return text + ", ImplementationType = \"" + ImplementationType.FullName + "\"";
			}
			if (ImplementationFactory != null)
			{
				return text + $", ImplementationFactory = {ImplementationFactory.Method}";
			}
			return text + $", ImplementationInstance = {ImplementationInstance}";
		}

		private static void ThrowKeyedDescriptor()
		{
			throw new InvalidOperationException(System.SR.KeyedDescriptorMisuse);
		}

		private static void ThrowNonKeyedDescriptor()
		{
			throw new InvalidOperationException(System.SR.NonKeyedDescriptorMisuse);
		}
	}
	[AttributeUsage(AttributeTargets.Parameter)]
	public class ServiceKeyAttribute : Attribute
	{
	}
	public enum ServiceLifetime
	{
		Singleton,
		Scoped,
		Transient
	}
	public static class ServiceProviderKeyedServiceExtensions
	{
		public static T? GetKeyedService<T>(this IServiceProvider provider, object? serviceKey)
		{
			System.ThrowHelper.ThrowIfNull(provider, "provider");
			if (provider is IKeyedServiceProvider keyedServiceProvider)
			{
				return (T)keyedServiceProvider.GetKeyedService(typeof(T), serviceKey);
			}
			throw new InvalidOperationException(System.SR.KeyedServicesNotSupported);
		}

		public static object GetRequiredKeyedService(this IServiceProvider provider, Type serviceType, object? serviceKey)
		{
			System.ThrowHelper.ThrowIfNull(provider, "provider");
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			if (provider is IKeyedServiceProvider keyedServiceProvider)
			{
				return keyedServiceProvider.GetRequiredKeyedService(serviceType, serviceKey);
			}
			throw new InvalidOperationException(System.SR.KeyedServicesNotSupported);
		}

		public static T GetRequiredKeyedService<T>(this IServiceProvider provider, object? serviceKey) where T : notnull
		{
			System.ThrowHelper.ThrowIfNull(provider, "provider");
			return (T)provider.GetRequiredKeyedService(typeof(T), serviceKey);
		}

		public static IEnumerable<T> GetKeyedServices<T>(this IServiceProvider provider, object? serviceKey)
		{
			System.ThrowHelper.ThrowIfNull(provider, "provider");
			return provider.GetRequiredKeyedService<IEnumerable<T>>(serviceKey);
		}

		[RequiresDynamicCode("The native code for an IEnumerable<serviceType> might not be available at runtime.")]
		public static IEnumerable<object?> GetKeyedServices(this IServiceProvider provider, Type serviceType, object? serviceKey)
		{
			System.ThrowHelper.ThrowIfNull(provider, "provider");
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			Type serviceType2 = typeof(IEnumerable<>).MakeGenericType(serviceType);
			return (IEnumerable<object>)provider.GetRequiredKeyedService(serviceType2, serviceKey);
		}
	}
	public static class ServiceProviderServiceExtensions
	{
		public static T? GetService<T>(this IServiceProvider provider)
		{
			System.ThrowHelper.ThrowIfNull(provider, "provider");
			return (T)provider.GetService(typeof(T));
		}

		public static object GetRequiredService(this IServiceProvider provider, Type serviceType)
		{
			System.ThrowHelper.ThrowIfNull(provider, "provider");
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			if (provider is ISupportRequiredService supportRequiredService)
			{
				return supportRequiredService.GetRequiredService(serviceType);
			}
			object service = provider.GetService(serviceType);
			if (service == null)
			{
				throw new InvalidOperationException(System.SR.Format(System.SR.NoServiceRegistered, serviceType));
			}
			return service;
		}

		public static T GetRequiredService<T>(this IServiceProvider provider) where T : notnull
		{
			System.ThrowHelper.ThrowIfNull(provider, "provider");
			return (T)provider.GetRequiredService(typeof(T));
		}

		public static IEnumerable<T> GetServices<T>(this IServiceProvider provider)
		{
			System.ThrowHelper.ThrowIfNull(provider, "provider");
			return provider.GetRequiredService<IEnumerable<T>>();
		}

		[RequiresDynamicCode("The native code for an IEnumerable<serviceType> might not be available at runtime.")]
		public static IEnumerable<object?> GetServices(this IServiceProvider provider, Type serviceType)
		{
			System.ThrowHelper.ThrowIfNull(provider, "provider");
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			Type serviceType2 = typeof(IEnumerable<>).MakeGenericType(serviceType);
			return (IEnumerable<object>)provider.GetRequiredService(serviceType2);
		}

		public static IServiceScope CreateScope(this IServiceProvider provider)
		{
			return provider.GetRequiredService<IServiceScopeFactory>().CreateScope();
		}

		public static AsyncServiceScope CreateAsyncScope(this IServiceProvider provider)
		{
			return new AsyncServiceScope(provider.CreateScope());
		}

		public static AsyncServiceScope CreateAsyncScope(this IServiceScopeFactory serviceScopeFactory)
		{
			return new AsyncServiceScope(serviceScopeFactory.CreateScope());
		}
	}
}
namespace Microsoft.Extensions.DependencyInjection.Extensions
{
	public static class ServiceCollectionDescriptorExtensions
	{
		public static IServiceCollection Add(this IServiceCollection collection, ServiceDescriptor descriptor)
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			System.ThrowHelper.ThrowIfNull(descriptor, "descriptor");
			collection.Add(descriptor);
			return collection;
		}

		public static IServiceCollection Add(this IServiceCollection collection, IEnumerable<ServiceDescriptor> descriptors)
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			System.ThrowHelper.ThrowIfNull(descriptors, "descriptors");
			foreach (ServiceDescriptor descriptor in descriptors)
			{
				collection.Add(descriptor);
			}
			return collection;
		}

		public static void TryAdd(this IServiceCollection collection, ServiceDescriptor descriptor)
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			System.ThrowHelper.ThrowIfNull(descriptor, "descriptor");
			int count = collection.Count;
			for (int i = 0; i < count; i++)
			{
				if (collection[i].ServiceType == descriptor.ServiceType && collection[i].ServiceKey == descriptor.ServiceKey)
				{
					return;
				}
			}
			collection.Add(descriptor);
		}

		public static void TryAdd(this IServiceCollection collection, IEnumerable<ServiceDescriptor> descriptors)
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			System.ThrowHelper.ThrowIfNull(descriptors, "descriptors");
			foreach (ServiceDescriptor descriptor in descriptors)
			{
				collection.TryAdd(descriptor);
			}
		}

		public static void TryAddTransient(this IServiceCollection collection, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type service)
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			System.ThrowHelper.ThrowIfNull(service, "service");
			ServiceDescriptor descriptor = ServiceDescriptor.Transient(service, service);
			collection.TryAdd(descriptor);
		}

		public static void TryAddTransient(this IServiceCollection collection, Type service, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			System.ThrowHelper.ThrowIfNull(service, "service");
			System.ThrowHelper.ThrowIfNull(implementationType, "implementationType");
			ServiceDescriptor descriptor = ServiceDescriptor.Transient(service, implementationType);
			collection.TryAdd(descriptor);
		}

		public static void TryAddTransient(this IServiceCollection collection, Type service, Func<IServiceProvider, object> implementationFactory)
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			System.ThrowHelper.ThrowIfNull(service, "service");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			ServiceDescriptor descriptor = ServiceDescriptor.Transient(service, implementationFactory);
			collection.TryAdd(descriptor);
		}

		public static void TryAddTransient<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this IServiceCollection collection) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			collection.TryAddTransient(typeof(TService), typeof(TService));
		}

		public static void TryAddTransient<TService, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>(this IServiceCollection collection) where TService : class where TImplementation : class, TService
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			collection.TryAddTransient(typeof(TService), typeof(TImplementation));
		}

		public static void TryAddTransient<TService>(this IServiceCollection services, Func<IServiceProvider, TService> implementationFactory) where TService : class
		{
			services.TryAdd(ServiceDescriptor.Transient(implementationFactory));
		}

		public static void TryAddScoped(this IServiceCollection collection, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type service)
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			System.ThrowHelper.ThrowIfNull(service, "service");
			ServiceDescriptor descriptor = ServiceDescriptor.Scoped(service, service);
			collection.TryAdd(descriptor);
		}

		public static void TryAddScoped(this IServiceCollection collection, Type service, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			System.ThrowHelper.ThrowIfNull(service, "service");
			System.ThrowHelper.ThrowIfNull(implementationType, "implementationType");
			ServiceDescriptor descriptor = ServiceDescriptor.Scoped(service, implementationType);
			collection.TryAdd(descriptor);
		}

		public static void TryAddScoped(this IServiceCollection collection, Type service, Func<IServiceProvider, object> implementationFactory)
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			System.ThrowHelper.ThrowIfNull(service, "service");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			ServiceDescriptor descriptor = ServiceDescriptor.Scoped(service, implementationFactory);
			collection.TryAdd(descriptor);
		}

		public static void TryAddScoped<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this IServiceCollection collection) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			collection.TryAddScoped(typeof(TService), typeof(TService));
		}

		public static void TryAddScoped<TService, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>(this IServiceCollection collection) where TService : class where TImplementation : class, TService
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			collection.TryAddScoped(typeof(TService), typeof(TImplementation));
		}

		public static void TryAddScoped<TService>(this IServiceCollection services, Func<IServiceProvider, TService> implementationFactory) where TService : class
		{
			services.TryAdd(ServiceDescriptor.Scoped(implementationFactory));
		}

		public static void TryAddSingleton(this IServiceCollection collection, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type service)
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			System.ThrowHelper.ThrowIfNull(service, "service");
			ServiceDescriptor descriptor = ServiceDescriptor.Singleton(service, service);
			collection.TryAdd(descriptor);
		}

		public static void TryAddSingleton(this IServiceCollection collection, Type service, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			System.ThrowHelper.ThrowIfNull(service, "service");
			System.ThrowHelper.ThrowIfNull(implementationType, "implementationType");
			ServiceDescriptor descriptor = ServiceDescriptor.Singleton(service, implementationType);
			collection.TryAdd(descriptor);
		}

		public static void TryAddSingleton(this IServiceCollection collection, Type service, Func<IServiceProvider, object> implementationFactory)
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			System.ThrowHelper.ThrowIfNull(service, "service");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			ServiceDescriptor descriptor = ServiceDescriptor.Singleton(service, implementationFactory);
			collection.TryAdd(descriptor);
		}

		public static void TryAddSingleton<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this IServiceCollection collection) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			collection.TryAddSingleton(typeof(TService), typeof(TService));
		}

		public static void TryAddSingleton<TService, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>(this IServiceCollection collection) where TService : class where TImplementation : class, TService
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			collection.TryAddSingleton(typeof(TService), typeof(TImplementation));
		}

		public static void TryAddSingleton<TService>(this IServiceCollection collection, TService instance) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			System.ThrowHelper.ThrowIfNull(instance, "instance");
			ServiceDescriptor descriptor = ServiceDescriptor.Singleton(typeof(TService), instance);
			collection.TryAdd(descriptor);
		}

		public static void TryAddSingleton<TService>(this IServiceCollection services, Func<IServiceProvider, TService> implementationFactory) where TService : class
		{
			services.TryAdd(ServiceDescriptor.Singleton(implementationFactory));
		}

		public static void TryAddEnumerable(this IServiceCollection services, ServiceDescriptor descriptor)
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(descriptor, "descriptor");
			Type implementationType = descriptor.GetImplementationType();
			if (implementationType == typeof(object) || implementationType == descriptor.ServiceType)
			{
				throw new ArgumentException(System.SR.Format(System.SR.TryAddIndistinguishableTypeToEnumerable, implementationType, descriptor.ServiceType), "descriptor");
			}
			int count = services.Count;
			for (int i = 0; i < count; i++)
			{
				ServiceDescriptor serviceDescriptor = services[i];
				if (serviceDescriptor.ServiceType == descriptor.ServiceType && serviceDescriptor.GetImplementationType() == implementationType && serviceDescriptor.ServiceKey == descriptor.ServiceKey)
				{
					return;
				}
			}
			services.Add(descriptor);
		}

		public static void TryAddEnumerable(this IServiceCollection services, IEnumerable<ServiceDescriptor> descriptors)
		{
			System.ThrowHelper.ThrowIfNull(services, "services");
			System.ThrowHelper.ThrowIfNull(descriptors, "descriptors");
			foreach (ServiceDescriptor descriptor in descriptors)
			{
				services.TryAddEnumerable(descriptor);
			}
		}

		public static IServiceCollection Replace(this IServiceCollection collection, ServiceDescriptor descriptor)
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			System.ThrowHelper.ThrowIfNull(descriptor, "descriptor");
			int count = collection.Count;
			for (int i = 0; i < count; i++)
			{
				if (collection[i].ServiceType == descriptor.ServiceType && collection[i].ServiceKey == descriptor.ServiceKey)
				{
					collection.RemoveAt(i);
					break;
				}
			}
			collection.Add(descriptor);
			return collection;
		}

		public static IServiceCollection RemoveAll<T>(this IServiceCollection collection)
		{
			return collection.RemoveAll(typeof(T));
		}

		public static IServiceCollection RemoveAll(this IServiceCollection collection, Type serviceType)
		{
			System.ThrowHelper.ThrowIfNull(serviceType, "serviceType");
			for (int num = collection.Count - 1; num >= 0; num--)
			{
				ServiceDescriptor serviceDescriptor = collection[num];
				if (serviceDescriptor.ServiceType == serviceType && serviceDescriptor.ServiceKey == null)
				{
					collection.RemoveAt(num);
				}
			}
			return collection;
		}

		public static void TryAddKeyedTransient(this IServiceCollection collection, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type service, object? serviceKey)
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			System.ThrowHelper.ThrowIfNull(service, "service");
			ServiceDescriptor descriptor = ServiceDescriptor.KeyedTransient(service, serviceKey, service);
			collection.TryAdd(descriptor);
		}

		public static void TryAddKeyedTransient(this IServiceCollection collection, Type service, object? serviceKey, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			System.ThrowHelper.ThrowIfNull(service, "service");
			System.ThrowHelper.ThrowIfNull(implementationType, "implementationType");
			ServiceDescriptor descriptor = ServiceDescriptor.KeyedTransient(service, serviceKey, implementationType);
			collection.TryAdd(descriptor);
		}

		public static void TryAddKeyedTransient(this IServiceCollection collection, Type service, object? serviceKey, Func<IServiceProvider, object?, object> implementationFactory)
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			System.ThrowHelper.ThrowIfNull(service, "service");
			System.ThrowHelper.ThrowIfNull(implementationFactory, "implementationFactory");
			ServiceDescriptor descriptor = ServiceDescriptor.KeyedTransient(service, serviceKey, implementationFactory);
			collection.TryAdd(descriptor);
		}

		public static void TryAddKeyedTransient<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TService>(this IServiceCollection collection, object? serviceKey) where TService : class
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			collection.TryAddKeyedTransient(typeof(TService), serviceKey, typeof(TService));
		}

		public static void TryAddKeyedTransient<TService, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>(this IServiceCollection collection, object? serviceKey) where TService : class where TImplementation : class, TService
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			collection.TryAddKeyedTransient(typeof(TService), serviceKey, typeof(TImplementation));
		}

		public static void TryAddKeyedTransient<TService>(this IServiceCollection services, object? serviceKey, Func<IServiceProvider, object?, TService> implementationFactory) where TService : class
		{
			services.TryAdd(ServiceDescriptor.KeyedTransient(serviceKey, implementationFactory));
		}

		public static void TryAddKeyedScoped(this IServiceCollection collection, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type service, object? serviceKey)
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			System.ThrowHelper.ThrowIfNull(service, "service");
			ServiceDescriptor descriptor = ServiceDescriptor.KeyedScoped(service, serviceKey, service);
			collection.TryAdd(descriptor);
		}

		public static void TryAddKeyedScoped(this IServiceCollection collection, Type service, object? serviceKey, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType)
		{
			System.ThrowHelper.ThrowIfNull(collection, "collection");
			System.ThrowHelper.ThrowIfNull(service, "service");
			System.ThrowHelper.ThrowIfNull(implementationType, "implementationType");
			ServiceDescriptor descriptor = ServiceDescriptor.KeyedScoped(service,

Mods/RealRadio/Microsoft.Extensions.Logging.Abstractions.dll

Decompiled a day ago
using System;
using System.Buffers;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using FxResources.Microsoft.Extensions.Logging.Abstractions;
using Microsoft.CodeAnalysis;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Internal;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("Microsoft.Extensions.Logging.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: AssemblyDefaultAlias("Microsoft.Extensions.Logging.Abstractions")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata("IsTrimmable", "True")]
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyDescription("Logging abstractions for Microsoft.Extensions.Logging.\r\n\r\nCommonly Used Types:\r\nMicrosoft.Extensions.Logging.ILogger\r\nMicrosoft.Extensions.Logging.ILoggerFactory\r\nMicrosoft.Extensions.Logging.ILogger<TCategoryName>\r\nMicrosoft.Extensions.Logging.LogLevel\r\nMicrosoft.Extensions.Logging.Logger<T>\r\nMicrosoft.Extensions.Logging.LoggerMessage\r\nMicrosoft.Extensions.Logging.Abstractions.NullLogger")]
[assembly: AssemblyFileVersion("8.0.23.53103")]
[assembly: AssemblyInformationalVersion("8.0.0+5535e31a712343a63f5d7d796cd874e563e5ac14")]
[assembly: AssemblyProduct("Microsoft® .NET")]
[assembly: AssemblyTitle("Microsoft.Extensions.Logging.Abstractions")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/dotnet/runtime")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("8.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: System.Runtime.CompilerServices.NullablePublicOnly(true)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsByRefLikeAttribute : Attribute
	{
	}
	[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 NullablePublicOnlyAttribute : Attribute
	{
		public readonly bool IncludesInternals;

		public NullablePublicOnlyAttribute(bool P_0)
		{
			IncludesInternals = 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 FxResources.Microsoft.Extensions.Logging.Abstractions
{
	internal static class SR
	{
	}
}
namespace System
{
	internal static class ThrowHelper
	{
		internal static void ThrowIfNull(object? argument, [CallerArgumentExpression("argument")] string? paramName = null)
		{
			if (argument == null)
			{
				Throw(paramName);
			}
		}

		private static void Throw(string paramName)
		{
			throw new ArgumentNullException(paramName);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static string IfNullOrWhitespace(string? argument, [CallerArgumentExpression("argument")] string paramName = "")
		{
			if (argument == null)
			{
				throw new ArgumentNullException(paramName);
			}
			if (string.IsNullOrWhiteSpace(argument))
			{
				if (argument == null)
				{
					throw new ArgumentNullException(paramName);
				}
				throw new ArgumentException(paramName, "Argument is whitespace");
			}
			return argument;
		}
	}
	internal static class SR
	{
		private static readonly bool s_usingResourceKeys = AppContext.TryGetSwitch("System.Resources.UseSystemResourceKeys", out var isEnabled) && isEnabled;

		private static ResourceManager s_resourceManager;

		internal static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(typeof(SR)));

		internal static string UnexpectedNumberOfNamedParameters => GetResourceString("UnexpectedNumberOfNamedParameters");

		internal static bool UsingResourceKeys()
		{
			return s_usingResourceKeys;
		}

		private static string GetResourceString(string resourceKey)
		{
			if (UsingResourceKeys())
			{
				return resourceKey;
			}
			string result = null;
			try
			{
				result = ResourceManager.GetString(resourceKey);
			}
			catch (MissingManifestResourceException)
			{
			}
			return result;
		}

		private static string GetResourceString(string resourceKey, string defaultString)
		{
			string resourceString = GetResourceString(resourceKey);
			if (!(resourceKey == resourceString) && resourceString != null)
			{
				return resourceString;
			}
			return defaultString;
		}

		internal static string Format(string resourceFormat, object? p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(resourceFormat, p1);
		}

		internal static string Format(string resourceFormat, object? p1, object? p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(resourceFormat, p1, p2);
		}

		internal static string Format(string resourceFormat, object? p1, object? p2, object? p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(resourceFormat, p1, p2, p3);
		}

		internal static string Format(string resourceFormat, params object?[]? args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + ", " + string.Join(", ", args);
				}
				return string.Format(resourceFormat, args);
			}
			return resourceFormat;
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(provider, resourceFormat, p1);
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1, object? p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(provider, resourceFormat, p1, p2);
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1, object? p2, object? p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(provider, resourceFormat, p1, p2, p3);
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, params object?[]? args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + ", " + string.Join(", ", args);
				}
				return string.Format(provider, resourceFormat, args);
			}
			return resourceFormat;
		}
	}
}
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.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class MaybeNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class NotNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal sealed class MaybeNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

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

		public NotNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[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.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.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	internal sealed class MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	internal sealed class MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
}
namespace System.Runtime.InteropServices
{
	[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
	internal sealed class LibraryImportAttribute : Attribute
	{
		public string LibraryName { get; }

		public string? EntryPoint { get; set; }

		public StringMarshalling StringMarshalling { get; set; }

		public Type? StringMarshallingCustomType { get; set; }

		public bool SetLastError { get; set; }

		public LibraryImportAttribute(string libraryName)
		{
			LibraryName = libraryName;
		}
	}
	internal enum StringMarshalling
	{
		Custom,
		Utf8,
		Utf16
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	internal sealed class CallerArgumentExpressionAttribute : Attribute
	{
		public string ParameterName { get; }

		public CallerArgumentExpressionAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
}
namespace System.Text
{
	internal ref struct ValueStringBuilder
	{
		private char[] _arrayToReturnToPool;

		private Span<char> _chars;

		private int _pos;

		public int Length
		{
			get
			{
				return _pos;
			}
			set
			{
				_pos = value;
			}
		}

		public int Capacity => _chars.Length;

		public ref char this[int index] => ref _chars[index];

		public Span<char> RawChars => _chars;

		public ValueStringBuilder(Span<char> initialBuffer)
		{
			_arrayToReturnToPool = null;
			_chars = initialBuffer;
			_pos = 0;
		}

		public ValueStringBuilder(int initialCapacity)
		{
			_arrayToReturnToPool = ArrayPool<char>.Shared.Rent(initialCapacity);
			_chars = _arrayToReturnToPool;
			_pos = 0;
		}

		public void EnsureCapacity(int capacity)
		{
			if ((uint)capacity > (uint)_chars.Length)
			{
				Grow(capacity - _pos);
			}
		}

		public ref char GetPinnableReference()
		{
			return ref MemoryMarshal.GetReference(_chars);
		}

		public ref char GetPinnableReference(bool terminate)
		{
			if (terminate)
			{
				EnsureCapacity(Length + 1);
				_chars[Length] = '\0';
			}
			return ref MemoryMarshal.GetReference(_chars);
		}

		public override string ToString()
		{
			string result = _chars.Slice(0, _pos).ToString();
			Dispose();
			return result;
		}

		public ReadOnlySpan<char> AsSpan(bool terminate)
		{
			if (terminate)
			{
				EnsureCapacity(Length + 1);
				_chars[Length] = '\0';
			}
			return _chars.Slice(0, _pos);
		}

		public ReadOnlySpan<char> AsSpan()
		{
			return _chars.Slice(0, _pos);
		}

		public ReadOnlySpan<char> AsSpan(int start)
		{
			return _chars.Slice(start, _pos - start);
		}

		public ReadOnlySpan<char> AsSpan(int start, int length)
		{
			return _chars.Slice(start, length);
		}

		public bool TryCopyTo(Span<char> destination, out int charsWritten)
		{
			if (_chars.Slice(0, _pos).TryCopyTo(destination))
			{
				charsWritten = _pos;
				Dispose();
				return true;
			}
			charsWritten = 0;
			Dispose();
			return false;
		}

		public void Insert(int index, char value, int count)
		{
			if (_pos > _chars.Length - count)
			{
				Grow(count);
			}
			int length = _pos - index;
			_chars.Slice(index, length).CopyTo(_chars.Slice(index + count));
			_chars.Slice(index, count).Fill(value);
			_pos += count;
		}

		public void Insert(int index, string? s)
		{
			if (s != null)
			{
				int length = s.Length;
				if (_pos > _chars.Length - length)
				{
					Grow(length);
				}
				int length2 = _pos - index;
				_chars.Slice(index, length2).CopyTo(_chars.Slice(index + length));
				s.AsSpan().CopyTo(_chars.Slice(index));
				_pos += length;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Append(char c)
		{
			int pos = _pos;
			Span<char> chars = _chars;
			if ((uint)pos < (uint)chars.Length)
			{
				chars[pos] = c;
				_pos = pos + 1;
			}
			else
			{
				GrowAndAppend(c);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Append(string? s)
		{
			if (s != null)
			{
				int pos = _pos;
				if (s.Length == 1 && (uint)pos < (uint)_chars.Length)
				{
					_chars[pos] = s[0];
					_pos = pos + 1;
				}
				else
				{
					AppendSlow(s);
				}
			}
		}

		private void AppendSlow(string s)
		{
			int pos = _pos;
			if (pos > _chars.Length - s.Length)
			{
				Grow(s.Length);
			}
			s.AsSpan().CopyTo(_chars.Slice(pos));
			_pos += s.Length;
		}

		public void Append(char c, int count)
		{
			if (_pos > _chars.Length - count)
			{
				Grow(count);
			}
			Span<char> span = _chars.Slice(_pos, count);
			for (int i = 0; i < span.Length; i++)
			{
				span[i] = c;
			}
			_pos += count;
		}

		public unsafe void Append(char* value, int length)
		{
			int pos = _pos;
			if (pos > _chars.Length - length)
			{
				Grow(length);
			}
			Span<char> span = _chars.Slice(_pos, length);
			for (int i = 0; i < span.Length; i++)
			{
				span[i] = *(value++);
			}
			_pos += length;
		}

		public void Append(ReadOnlySpan<char> value)
		{
			int pos = _pos;
			if (pos > _chars.Length - value.Length)
			{
				Grow(value.Length);
			}
			value.CopyTo(_chars.Slice(_pos));
			_pos += value.Length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span<char> AppendSpan(int length)
		{
			int pos = _pos;
			if (pos > _chars.Length - length)
			{
				Grow(length);
			}
			_pos = pos + length;
			return _chars.Slice(pos, length);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private void GrowAndAppend(char c)
		{
			Grow(1);
			Append(c);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private void Grow(int additionalCapacityBeyondPos)
		{
			int minimumLength = (int)Math.Max((uint)(_pos + additionalCapacityBeyondPos), Math.Min((uint)(_chars.Length * 2), 2147483591u));
			char[] array = ArrayPool<char>.Shared.Rent(minimumLength);
			_chars.Slice(0, _pos).CopyTo(array);
			char[] arrayToReturnToPool = _arrayToReturnToPool;
			_chars = (_arrayToReturnToPool = array);
			if (arrayToReturnToPool != null)
			{
				ArrayPool<char>.Shared.Return(arrayToReturnToPool);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Dispose()
		{
			char[] arrayToReturnToPool = _arrayToReturnToPool;
			this = default(System.Text.ValueStringBuilder);
			if (arrayToReturnToPool != null)
			{
				ArrayPool<char>.Shared.Return(arrayToReturnToPool);
			}
		}
	}
}
namespace Microsoft.Extensions.Internal
{
	internal static class TypeNameHelper
	{
		private readonly struct DisplayNameOptions
		{
			public bool FullName { get; }

			public bool IncludeGenericParameters { get; }

			public bool IncludeGenericParameterNames { get; }

			public char NestedTypeDelimiter { get; }

			public DisplayNameOptions(bool fullName, bool includeGenericParameterNames, bool includeGenericParameters, char nestedTypeDelimiter)
			{
				FullName = fullName;
				IncludeGenericParameters = includeGenericParameters;
				IncludeGenericParameterNames = includeGenericParameterNames;
				NestedTypeDelimiter = nestedTypeDelimiter;
			}
		}

		private const char DefaultNestedTypeDelimiter = '+';

		private static readonly Dictionary<Type, string> _builtInTypeNames = new Dictionary<Type, string>
		{
			{
				typeof(void),
				"void"
			},
			{
				typeof(bool),
				"bool"
			},
			{
				typeof(byte),
				"byte"
			},
			{
				typeof(char),
				"char"
			},
			{
				typeof(decimal),
				"decimal"
			},
			{
				typeof(double),
				"double"
			},
			{
				typeof(float),
				"float"
			},
			{
				typeof(int),
				"int"
			},
			{
				typeof(long),
				"long"
			},
			{
				typeof(object),
				"object"
			},
			{
				typeof(sbyte),
				"sbyte"
			},
			{
				typeof(short),
				"short"
			},
			{
				typeof(string),
				"string"
			},
			{
				typeof(uint),
				"uint"
			},
			{
				typeof(ulong),
				"ulong"
			},
			{
				typeof(ushort),
				"ushort"
			}
		};

		[return: NotNullIfNotNull("item")]
		public static string? GetTypeDisplayName(object? item, bool fullName = true)
		{
			if (item != null)
			{
				return GetTypeDisplayName(item.GetType(), fullName);
			}
			return null;
		}

		public static string GetTypeDisplayName(Type type, bool fullName = true, bool includeGenericParameterNames = false, bool includeGenericParameters = true, char nestedTypeDelimiter = '+')
		{
			StringBuilder builder = null;
			DisplayNameOptions options = new DisplayNameOptions(fullName, includeGenericParameterNames, includeGenericParameters, nestedTypeDelimiter);
			string text = ProcessType(ref builder, type, in options);
			return text ?? builder?.ToString() ?? string.Empty;
		}

		private static string ProcessType(ref StringBuilder builder, Type type, in DisplayNameOptions options)
		{
			string value;
			if (type.IsGenericType)
			{
				Type[] genericArguments = type.GetGenericArguments();
				if (builder == null)
				{
					builder = new StringBuilder();
				}
				ProcessGenericType(builder, type, genericArguments, genericArguments.Length, in options);
			}
			else if (type.IsArray)
			{
				if (builder == null)
				{
					builder = new StringBuilder();
				}
				ProcessArrayType(builder, type, in options);
			}
			else if (_builtInTypeNames.TryGetValue(type, out value))
			{
				if (builder == null)
				{
					return value;
				}
				builder.Append(value);
			}
			else if (type.IsGenericParameter)
			{
				if (options.IncludeGenericParameterNames)
				{
					if (builder == null)
					{
						return type.Name;
					}
					builder.Append(type.Name);
				}
			}
			else
			{
				string text = (options.FullName ? type.FullName : type.Name);
				if (builder == null)
				{
					if (options.NestedTypeDelimiter != '+')
					{
						return text.Replace('+', options.NestedTypeDelimiter);
					}
					return text;
				}
				builder.Append(text);
				if (options.NestedTypeDelimiter != '+')
				{
					builder.Replace('+', options.NestedTypeDelimiter, builder.Length - text.Length, text.Length);
				}
			}
			return null;
		}

		private static void ProcessArrayType(StringBuilder builder, Type type, in DisplayNameOptions options)
		{
			Type type2 = type;
			while (type2.IsArray)
			{
				type2 = type2.GetElementType();
			}
			ProcessType(ref builder, type2, in options);
			while (type.IsArray)
			{
				builder.Append('[');
				builder.Append(',', type.GetArrayRank() - 1);
				builder.Append(']');
				type = type.GetElementType();
			}
		}

		private static void ProcessGenericType(StringBuilder builder, Type type, Type[] genericArguments, int length, in DisplayNameOptions options)
		{
			int num = 0;
			if (type.IsNested)
			{
				num = type.DeclaringType.GetGenericArguments().Length;
			}
			if (options.FullName)
			{
				if (type.IsNested)
				{
					ProcessGenericType(builder, type.DeclaringType, genericArguments, num, in options);
					builder.Append(options.NestedTypeDelimiter);
				}
				else if (!string.IsNullOrEmpty(type.Namespace))
				{
					builder.Append(type.Namespace);
					builder.Append('.');
				}
			}
			int num2 = type.Name.IndexOf('`');
			if (num2 <= 0)
			{
				builder.Append(type.Name);
				return;
			}
			builder.Append(type.Name, 0, num2);
			if (!options.IncludeGenericParameters)
			{
				return;
			}
			builder.Append('<');
			for (int i = num; i < length; i++)
			{
				ProcessType(ref builder, genericArguments[i], in options);
				if (i + 1 != length)
				{
					builder.Append(',');
					if (options.IncludeGenericParameterNames || !genericArguments[i + 1].IsGenericParameter)
					{
						builder.Append(' ');
					}
				}
			}
			builder.Append('>');
		}
	}
}
namespace Microsoft.Extensions.Logging
{
	public readonly struct EventId : IEquatable<EventId>
	{
		public int Id { get; }

		public string? Name { get; }

		public static implicit operator EventId(int i)
		{
			return new EventId(i);
		}

		public static bool operator ==(EventId left, EventId right)
		{
			return left.Equals(right);
		}

		public static bool operator !=(EventId left, EventId right)
		{
			return !left.Equals(right);
		}

		public EventId(int id, string? name = null)
		{
			Id = id;
			Name = name;
		}

		public override string ToString()
		{
			return Name ?? Id.ToString();
		}

		public bool Equals(EventId other)
		{
			return Id == other.Id;
		}

		public override bool Equals([NotNullWhen(true)] object? obj)
		{
			if (obj == null)
			{
				return false;
			}
			if (obj is EventId other)
			{
				return Equals(other);
			}
			return false;
		}

		public override int GetHashCode()
		{
			return Id;
		}
	}
	internal readonly struct FormattedLogValues : IReadOnlyList<KeyValuePair<string, object?>>, IEnumerable<KeyValuePair<string, object?>>, IEnumerable, IReadOnlyCollection<KeyValuePair<string, object?>>
	{
		internal const int MaxCachedFormatters = 1024;

		private const string NullFormat = "[null]";

		private static int s_count;

		private static readonly ConcurrentDictionary<string, LogValuesFormatter> s_formatters = new ConcurrentDictionary<string, LogValuesFormatter>();

		private readonly LogValuesFormatter _formatter;

		private readonly object[] _values;

		private readonly string _originalMessage;

		internal LogValuesFormatter? Formatter => _formatter;

		public KeyValuePair<string, object?> this[int index]
		{
			get
			{
				if (index < 0 || index >= Count)
				{
					throw new IndexOutOfRangeException("index");
				}
				if (index == Count - 1)
				{
					return new KeyValuePair<string, object>("{OriginalFormat}", _originalMessage);
				}
				return _formatter.GetValue(_values, index);
			}
		}

		public int Count
		{
			get
			{
				if (_formatter == null)
				{
					return 1;
				}
				return _formatter.ValueNames.Count + 1;
			}
		}

		public FormattedLogValues(string? format, params object?[]? values)
		{
			if (values != null && values.Length != 0 && format != null)
			{
				if (s_count >= 1024)
				{
					if (!s_formatters.TryGetValue(format, out _formatter))
					{
						_formatter = new LogValuesFormatter(format);
					}
				}
				else
				{
					_formatter = s_formatters.GetOrAdd(format, delegate(string f)
					{
						Interlocked.Increment(ref s_count);
						return new LogValuesFormatter(f);
					});
				}
			}
			else
			{
				_formatter = null;
			}
			_originalMessage = format ?? "[null]";
			_values = values;
		}

		public IEnumerator<KeyValuePair<string, object?>> GetEnumerator()
		{
			int i = 0;
			while (i < Count)
			{
				yield return this[i];
				int num = i + 1;
				i = num;
			}
		}

		public override string ToString()
		{
			if (_formatter == null)
			{
				return _originalMessage;
			}
			return _formatter.Format(_values);
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}
	}
	public interface IExternalScopeProvider
	{
		void ForEachScope<TState>(Action<object?, TState> callback, TState state);

		IDisposable Push(object? state);
	}
	public interface ILogger
	{
		void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter);

		bool IsEnabled(LogLevel logLevel);

		IDisposable? BeginScope<TState>(TState state) where TState : notnull;
	}
	public interface ILoggerFactory : IDisposable
	{
		ILogger CreateLogger(string categoryName);

		void AddProvider(ILoggerProvider provider);
	}
	public interface ILoggerProvider : IDisposable
	{
		ILogger CreateLogger(string categoryName);
	}
	public interface ILogger<out TCategoryName> : ILogger
	{
	}
	public interface ILoggingBuilder
	{
		IServiceCollection Services { get; }
	}
	public interface ISupportExternalScope
	{
		void SetScopeProvider(IExternalScopeProvider scopeProvider);
	}
	public class LogDefineOptions
	{
		public bool SkipEnabledCheck { get; set; }
	}
	public static class LoggerExtensions
	{
		private static readonly Func<FormattedLogValues, Exception, string> _messageFormatter = MessageFormatter;

		public static void LogDebug(this ILogger logger, EventId eventId, Exception? exception, string? message, params object?[] args)
		{
			logger.Log(LogLevel.Debug, eventId, exception, message, args);
		}

		public static void LogDebug(this ILogger logger, EventId eventId, string? message, params object?[] args)
		{
			logger.Log(LogLevel.Debug, eventId, message, args);
		}

		public static void LogDebug(this ILogger logger, Exception? exception, string? message, params object?[] args)
		{
			logger.Log(LogLevel.Debug, exception, message, args);
		}

		public static void LogDebug(this ILogger logger, string? message, params object?[] args)
		{
			logger.Log(LogLevel.Debug, message, args);
		}

		public static void LogTrace(this ILogger logger, EventId eventId, Exception? exception, string? message, params object?[] args)
		{
			logger.Log(LogLevel.Trace, eventId, exception, message, args);
		}

		public static void LogTrace(this ILogger logger, EventId eventId, string? message, params object?[] args)
		{
			logger.Log(LogLevel.Trace, eventId, message, args);
		}

		public static void LogTrace(this ILogger logger, Exception? exception, string? message, params object?[] args)
		{
			logger.Log(LogLevel.Trace, exception, message, args);
		}

		public static void LogTrace(this ILogger logger, string? message, params object?[] args)
		{
			logger.Log(LogLevel.Trace, message, args);
		}

		public static void LogInformation(this ILogger logger, EventId eventId, Exception? exception, string? message, params object?[] args)
		{
			logger.Log(LogLevel.Information, eventId, exception, message, args);
		}

		public static void LogInformation(this ILogger logger, EventId eventId, string? message, params object?[] args)
		{
			logger.Log(LogLevel.Information, eventId, message, args);
		}

		public static void LogInformation(this ILogger logger, Exception? exception, string? message, params object?[] args)
		{
			logger.Log(LogLevel.Information, exception, message, args);
		}

		public static void LogInformation(this ILogger logger, string? message, params object?[] args)
		{
			logger.Log(LogLevel.Information, message, args);
		}

		public static void LogWarning(this ILogger logger, EventId eventId, Exception? exception, string? message, params object?[] args)
		{
			logger.Log(LogLevel.Warning, eventId, exception, message, args);
		}

		public static void LogWarning(this ILogger logger, EventId eventId, string? message, params object?[] args)
		{
			logger.Log(LogLevel.Warning, eventId, message, args);
		}

		public static void LogWarning(this ILogger logger, Exception? exception, string? message, params object?[] args)
		{
			logger.Log(LogLevel.Warning, exception, message, args);
		}

		public static void LogWarning(this ILogger logger, string? message, params object?[] args)
		{
			logger.Log(LogLevel.Warning, message, args);
		}

		public static void LogError(this ILogger logger, EventId eventId, Exception? exception, string? message, params object?[] args)
		{
			logger.Log(LogLevel.Error, eventId, exception, message, args);
		}

		public static void LogError(this ILogger logger, EventId eventId, string? message, params object?[] args)
		{
			logger.Log(LogLevel.Error, eventId, message, args);
		}

		public static void LogError(this ILogger logger, Exception? exception, string? message, params object?[] args)
		{
			logger.Log(LogLevel.Error, exception, message, args);
		}

		public static void LogError(this ILogger logger, string? message, params object?[] args)
		{
			logger.Log(LogLevel.Error, message, args);
		}

		public static void LogCritical(this ILogger logger, EventId eventId, Exception? exception, string? message, params object?[] args)
		{
			logger.Log(LogLevel.Critical, eventId, exception, message, args);
		}

		public static void LogCritical(this ILogger logger, EventId eventId, string? message, params object?[] args)
		{
			logger.Log(LogLevel.Critical, eventId, message, args);
		}

		public static void LogCritical(this ILogger logger, Exception? exception, string? message, params object?[] args)
		{
			logger.Log(LogLevel.Critical, exception, message, args);
		}

		public static void LogCritical(this ILogger logger, string? message, params object?[] args)
		{
			logger.Log(LogLevel.Critical, message, args);
		}

		public static void Log(this ILogger logger, LogLevel logLevel, string? message, params object?[] args)
		{
			logger.Log(logLevel, 0, null, message, args);
		}

		public static void Log(this ILogger logger, LogLevel logLevel, EventId eventId, string? message, params object?[] args)
		{
			logger.Log(logLevel, eventId, null, message, args);
		}

		public static void Log(this ILogger logger, LogLevel logLevel, Exception? exception, string? message, params object?[] args)
		{
			logger.Log(logLevel, 0, exception, message, args);
		}

		public static void Log(this ILogger logger, LogLevel logLevel, EventId eventId, Exception? exception, string? message, params object?[] args)
		{
			System.ThrowHelper.ThrowIfNull(logger, "logger");
			logger.Log(logLevel, eventId, new FormattedLogValues(message, args), exception, _messageFormatter);
		}

		public static IDisposable? BeginScope(this ILogger logger, string messageFormat, params object?[] args)
		{
			System.ThrowHelper.ThrowIfNull(logger, "logger");
			return logger.BeginScope(new FormattedLogValues(messageFormat, args));
		}

		private static string MessageFormatter(FormattedLogValues state, Exception error)
		{
			return state.ToString();
		}
	}
	public class LoggerExternalScopeProvider : IExternalScopeProvider
	{
		private sealed class Scope : IDisposable
		{
			private readonly LoggerExternalScopeProvider _provider;

			private bool _isDisposed;

			public Scope Parent { get; }

			public object State { get; }

			internal Scope(LoggerExternalScopeProvider provider, object state, Scope parent)
			{
				_provider = provider;
				State = state;
				Parent = parent;
			}

			public override string ToString()
			{
				return State?.ToString();
			}

			public void Dispose()
			{
				if (!_isDisposed)
				{
					_provider._currentScope.Value = Parent;
					_isDisposed = true;
				}
			}
		}

		private readonly AsyncLocal<Scope> _currentScope = new AsyncLocal<Scope>();

		public void ForEachScope<TState>(Action<object?, TState> callback, TState state)
		{
			Action<object, TState> callback2 = callback;
			TState state2 = state;
			Report(_currentScope.Value);
			void Report(Scope? current)
			{
				if (current != null)
				{
					Report(current.Parent);
					callback2(current.State, state2);
				}
			}
		}

		public IDisposable Push(object? state)
		{
			Scope value = _currentScope.Value;
			Scope scope = new Scope(this, state, value);
			_currentScope.Value = scope;
			return scope;
		}
	}
	public static class LoggerFactoryExtensions
	{
		public static ILogger<T> CreateLogger<T>(this ILoggerFactory factory)
		{
			System.ThrowHelper.ThrowIfNull(factory, "factory");
			return new Logger<T>(factory);
		}

		public static ILogger CreateLogger(this ILoggerFactory factory, Type type)
		{
			System.ThrowHelper.ThrowIfNull(factory, "factory");
			System.ThrowHelper.ThrowIfNull(type, "type");
			return factory.CreateLogger(TypeNameHelper.GetTypeDisplayName(type, fullName: true, includeGenericParameterNames: false, includeGenericParameters: false, '.'));
		}
	}
	public static class LoggerMessage
	{
		private readonly struct LogValues : IReadOnlyList<KeyValuePair<string, object>>, IEnumerable<KeyValuePair<string, object>>, IEnumerable, IReadOnlyCollection<KeyValuePair<string, object>>
		{
			public static readonly Func<LogValues, Exception, string> Callback = (LogValues state, Exception exception) => state.ToString();

			private readonly LogValuesFormatter _formatter;

			public KeyValuePair<string, object> this[int index]
			{
				get
				{
					if (index == 0)
					{
						return new KeyValuePair<string, object>("{OriginalFormat}", _formatter.OriginalFormat);
					}
					throw new IndexOutOfRangeException("index");
				}
			}

			public int Count => 1;

			public LogValues(LogValuesFormatter formatter)
			{
				_formatter = formatter;
			}

			public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
			{
				yield return this[0];
			}

			public override string ToString()
			{
				return _formatter.Format();
			}

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

		private readonly struct LogValues<T0> : IReadOnlyList<KeyValuePair<string, object>>, IEnumerable<KeyValuePair<string, object>>, IEnumerable, IReadOnlyCollection<KeyValuePair<string, object>>
		{
			public static readonly Func<LogValues<T0>, Exception, string> Callback = (LogValues<T0> state, Exception exception) => state.ToString();

			private readonly LogValuesFormatter _formatter;

			private readonly T0 _value0;

			public KeyValuePair<string, object> this[int index] => index switch
			{
				0 => new KeyValuePair<string, object>(_formatter.ValueNames[0], _value0), 
				1 => new KeyValuePair<string, object>("{OriginalFormat}", _formatter.OriginalFormat), 
				_ => throw new IndexOutOfRangeException("index"), 
			};

			public int Count => 2;

			public LogValues(LogValuesFormatter formatter, T0 value0)
			{
				_formatter = formatter;
				_value0 = value0;
			}

			public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
			{
				int i = 0;
				while (i < Count)
				{
					yield return this[i];
					int num = i + 1;
					i = num;
				}
			}

			public override string ToString()
			{
				return _formatter.Format(_value0);
			}

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

		private readonly struct LogValues<T0, T1> : IReadOnlyList<KeyValuePair<string, object>>, IEnumerable<KeyValuePair<string, object>>, IEnumerable, IReadOnlyCollection<KeyValuePair<string, object>>
		{
			public static readonly Func<LogValues<T0, T1>, Exception, string> Callback = (LogValues<T0, T1> state, Exception exception) => state.ToString();

			private readonly LogValuesFormatter _formatter;

			private readonly T0 _value0;

			private readonly T1 _value1;

			public KeyValuePair<string, object> this[int index] => index switch
			{
				0 => new KeyValuePair<string, object>(_formatter.ValueNames[0], _value0), 
				1 => new KeyValuePair<string, object>(_formatter.ValueNames[1], _value1), 
				2 => new KeyValuePair<string, object>("{OriginalFormat}", _formatter.OriginalFormat), 
				_ => throw new IndexOutOfRangeException("index"), 
			};

			public int Count => 3;

			public LogValues(LogValuesFormatter formatter, T0 value0, T1 value1)
			{
				_formatter = formatter;
				_value0 = value0;
				_value1 = value1;
			}

			public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
			{
				int i = 0;
				while (i < Count)
				{
					yield return this[i];
					int num = i + 1;
					i = num;
				}
			}

			public override string ToString()
			{
				return _formatter.Format(_value0, _value1);
			}

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

		private readonly struct LogValues<T0, T1, T2> : IReadOnlyList<KeyValuePair<string, object>>, IEnumerable<KeyValuePair<string, object>>, IEnumerable, IReadOnlyCollection<KeyValuePair<string, object>>
		{
			public static readonly Func<LogValues<T0, T1, T2>, Exception, string> Callback = (LogValues<T0, T1, T2> state, Exception exception) => state.ToString();

			private readonly LogValuesFormatter _formatter;

			private readonly T0 _value0;

			private readonly T1 _value1;

			private readonly T2 _value2;

			public int Count => 4;

			public KeyValuePair<string, object> this[int index] => index switch
			{
				0 => new KeyValuePair<string, object>(_formatter.ValueNames[0], _value0), 
				1 => new KeyValuePair<string, object>(_formatter.ValueNames[1], _value1), 
				2 => new KeyValuePair<string, object>(_formatter.ValueNames[2], _value2), 
				3 => new KeyValuePair<string, object>("{OriginalFormat}", _formatter.OriginalFormat), 
				_ => throw new IndexOutOfRangeException("index"), 
			};

			public LogValues(LogValuesFormatter formatter, T0 value0, T1 value1, T2 value2)
			{
				_formatter = formatter;
				_value0 = value0;
				_value1 = value1;
				_value2 = value2;
			}

			public override string ToString()
			{
				return _formatter.Format(_value0, _value1, _value2);
			}

			public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
			{
				int i = 0;
				while (i < Count)
				{
					yield return this[i];
					int num = i + 1;
					i = num;
				}
			}

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

		private readonly struct LogValues<T0, T1, T2, T3> : IReadOnlyList<KeyValuePair<string, object>>, IEnumerable<KeyValuePair<string, object>>, IEnumerable, IReadOnlyCollection<KeyValuePair<string, object>>
		{
			public static readonly Func<LogValues<T0, T1, T2, T3>, Exception, string> Callback = (LogValues<T0, T1, T2, T3> state, Exception exception) => state.ToString();

			private readonly LogValuesFormatter _formatter;

			private readonly T0 _value0;

			private readonly T1 _value1;

			private readonly T2 _value2;

			private readonly T3 _value3;

			public int Count => 5;

			public KeyValuePair<string, object> this[int index] => index switch
			{
				0 => new KeyValuePair<string, object>(_formatter.ValueNames[0], _value0), 
				1 => new KeyValuePair<string, object>(_formatter.ValueNames[1], _value1), 
				2 => new KeyValuePair<string, object>(_formatter.ValueNames[2], _value2), 
				3 => new KeyValuePair<string, object>(_formatter.ValueNames[3], _value3), 
				4 => new KeyValuePair<string, object>("{OriginalFormat}", _formatter.OriginalFormat), 
				_ => throw new IndexOutOfRangeException("index"), 
			};

			public LogValues(LogValuesFormatter formatter, T0 value0, T1 value1, T2 value2, T3 value3)
			{
				_formatter = formatter;
				_value0 = value0;
				_value1 = value1;
				_value2 = value2;
				_value3 = value3;
			}

			private object[] ToArray()
			{
				return new object[4] { _value0, _value1, _value2, _value3 };
			}

			public override string ToString()
			{
				return _formatter.FormatWithOverwrite(ToArray());
			}

			public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
			{
				int i = 0;
				while (i < Count)
				{
					yield return this[i];
					int num = i + 1;
					i = num;
				}
			}

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

		private readonly struct LogValues<T0, T1, T2, T3, T4> : IReadOnlyList<KeyValuePair<string, object>>, IEnumerable<KeyValuePair<string, object>>, IEnumerable, IReadOnlyCollection<KeyValuePair<string, object>>
		{
			public static readonly Func<LogValues<T0, T1, T2, T3, T4>, Exception, string> Callback = (LogValues<T0, T1, T2, T3, T4> state, Exception exception) => state.ToString();

			private readonly LogValuesFormatter _formatter;

			private readonly T0 _value0;

			private readonly T1 _value1;

			private readonly T2 _value2;

			private readonly T3 _value3;

			private readonly T4 _value4;

			public int Count => 6;

			public KeyValuePair<string, object> this[int index] => index switch
			{
				0 => new KeyValuePair<string, object>(_formatter.ValueNames[0], _value0), 
				1 => new KeyValuePair<string, object>(_formatter.ValueNames[1], _value1), 
				2 => new KeyValuePair<string, object>(_formatter.ValueNames[2], _value2), 
				3 => new KeyValuePair<string, object>(_formatter.ValueNames[3], _value3), 
				4 => new KeyValuePair<string, object>(_formatter.ValueNames[4], _value4), 
				5 => new KeyValuePair<string, object>("{OriginalFormat}", _formatter.OriginalFormat), 
				_ => throw new IndexOutOfRangeException("index"), 
			};

			public LogValues(LogValuesFormatter formatter, T0 value0, T1 value1, T2 value2, T3 value3, T4 value4)
			{
				_formatter = formatter;
				_value0 = value0;
				_value1 = value1;
				_value2 = value2;
				_value3 = value3;
				_value4 = value4;
			}

			private object[] ToArray()
			{
				return new object[5] { _value0, _value1, _value2, _value3, _value4 };
			}

			public override string ToString()
			{
				return _formatter.FormatWithOverwrite(ToArray());
			}

			public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
			{
				int i = 0;
				while (i < Count)
				{
					yield return this[i];
					int num = i + 1;
					i = num;
				}
			}

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

		private readonly struct LogValues<T0, T1, T2, T3, T4, T5> : IReadOnlyList<KeyValuePair<string, object>>, IEnumerable<KeyValuePair<string, object>>, IEnumerable, IReadOnlyCollection<KeyValuePair<string, object>>
		{
			public static readonly Func<LogValues<T0, T1, T2, T3, T4, T5>, Exception, string> Callback = (LogValues<T0, T1, T2, T3, T4, T5> state, Exception exception) => state.ToString();

			private readonly LogValuesFormatter _formatter;

			private readonly T0 _value0;

			private readonly T1 _value1;

			private readonly T2 _value2;

			private readonly T3 _value3;

			private readonly T4 _value4;

			private readonly T5 _value5;

			public int Count => 7;

			public KeyValuePair<string, object> this[int index] => index switch
			{
				0 => new KeyValuePair<string, object>(_formatter.ValueNames[0], _value0), 
				1 => new KeyValuePair<string, object>(_formatter.ValueNames[1], _value1), 
				2 => new KeyValuePair<string, object>(_formatter.ValueNames[2], _value2), 
				3 => new KeyValuePair<string, object>(_formatter.ValueNames[3], _value3), 
				4 => new KeyValuePair<string, object>(_formatter.ValueNames[4], _value4), 
				5 => new KeyValuePair<string, object>(_formatter.ValueNames[5], _value5), 
				6 => new KeyValuePair<string, object>("{OriginalFormat}", _formatter.OriginalFormat), 
				_ => throw new IndexOutOfRangeException("index"), 
			};

			public LogValues(LogValuesFormatter formatter, T0 value0, T1 value1, T2 value2, T3 value3, T4 value4, T5 value5)
			{
				_formatter = formatter;
				_value0 = value0;
				_value1 = value1;
				_value2 = value2;
				_value3 = value3;
				_value4 = value4;
				_value5 = value5;
			}

			private object[] ToArray()
			{
				return new object[6] { _value0, _value1, _value2, _value3, _value4, _value5 };
			}

			public override string ToString()
			{
				return _formatter.FormatWithOverwrite(ToArray());
			}

			public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
			{
				int i = 0;
				while (i < Count)
				{
					yield return this[i];
					int num = i + 1;
					i = num;
				}
			}

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

		public static Func<ILogger, IDisposable?> DefineScope(string formatString)
		{
			LogValuesFormatter formatter = CreateLogValuesFormatter(formatString, 0);
			LogValues logValues = new LogValues(formatter);
			return (ILogger logger) => logger.BeginScope(logValues);
		}

		public static Func<ILogger, T1, IDisposable?> DefineScope<T1>(string formatString)
		{
			LogValuesFormatter formatter = CreateLogValuesFormatter(formatString, 1);
			return (ILogger logger, T1 arg1) => logger.BeginScope(new LogValues<T1>(formatter, arg1));
		}

		public static Func<ILogger, T1, T2, IDisposable?> DefineScope<T1, T2>(string formatString)
		{
			LogValuesFormatter formatter = CreateLogValuesFormatter(formatString, 2);
			return (ILogger logger, T1 arg1, T2 arg2) => logger.BeginScope(new LogValues<T1, T2>(formatter, arg1, arg2));
		}

		public static Func<ILogger, T1, T2, T3, IDisposable?> DefineScope<T1, T2, T3>(string formatString)
		{
			LogValuesFormatter formatter = CreateLogValuesFormatter(formatString, 3);
			return (ILogger logger, T1 arg1, T2 arg2, T3 arg3) => logger.BeginScope(new LogValues<T1, T2, T3>(formatter, arg1, arg2, arg3));
		}

		public static Func<ILogger, T1, T2, T3, T4, IDisposable?> DefineScope<T1, T2, T3, T4>(string formatString)
		{
			LogValuesFormatter formatter = CreateLogValuesFormatter(formatString, 4);
			return (ILogger logger, T1 arg1, T2 arg2, T3 arg3, T4 arg4) => logger.BeginScope(new LogValues<T1, T2, T3, T4>(formatter, arg1, arg2, arg3, arg4));
		}

		public static Func<ILogger, T1, T2, T3, T4, T5, IDisposable?> DefineScope<T1, T2, T3, T4, T5>(string formatString)
		{
			LogValuesFormatter formatter = CreateLogValuesFormatter(formatString, 5);
			return (ILogger logger, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) => logger.BeginScope(new LogValues<T1, T2, T3, T4, T5>(formatter, arg1, arg2, arg3, arg4, arg5));
		}

		public static Func<ILogger, T1, T2, T3, T4, T5, T6, IDisposable?> DefineScope<T1, T2, T3, T4, T5, T6>(string formatString)
		{
			LogValuesFormatter formatter = CreateLogValuesFormatter(formatString, 6);
			return (ILogger logger, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6) => logger.BeginScope(new LogValues<T1, T2, T3, T4, T5, T6>(formatter, arg1, arg2, arg3, arg4, arg5, arg6));
		}

		public static Action<ILogger, Exception?> Define(LogLevel logLevel, EventId eventId, string formatString)
		{
			return Define(logLevel, eventId, formatString, null);
		}

		public static Action<ILogger, Exception?> Define(LogLevel logLevel, EventId eventId, string formatString, LogDefineOptions? options)
		{
			LogValuesFormatter formatter = CreateLogValuesFormatter(formatString, 0);
			if (options != null && options.SkipEnabledCheck)
			{
				return Log;
			}
			return delegate(ILogger logger, Exception exception)
			{
				if (logger.IsEnabled(logLevel))
				{
					Log(logger, exception);
				}
			};
			void Log(ILogger logger, Exception exception)
			{
				logger.Log(logLevel, eventId, new LogValues(formatter), exception, LogValues.Callback);
			}
		}

		public static Action<ILogger, T1, Exception?> Define<T1>(LogLevel logLevel, EventId eventId, string formatString)
		{
			return Define<T1>(logLevel, eventId, formatString, null);
		}

		public static Action<ILogger, T1, Exception?> Define<T1>(LogLevel logLevel, EventId eventId, string formatString, LogDefineOptions? options)
		{
			LogValuesFormatter formatter = CreateLogValuesFormatter(formatString, 1);
			if (options != null && options.SkipEnabledCheck)
			{
				return Log;
			}
			return delegate(ILogger logger, T1 arg1, Exception exception)
			{
				if (logger.IsEnabled(logLevel))
				{
					Log(logger, arg1, exception);
				}
			};
			void Log(ILogger logger, T1 arg1, Exception exception)
			{
				logger.Log(logLevel, eventId, new LogValues<T1>(formatter, arg1), exception, LogValues<T1>.Callback);
			}
		}

		public static Action<ILogger, T1, T2, Exception?> Define<T1, T2>(LogLevel logLevel, EventId eventId, string formatString)
		{
			return Define<T1, T2>(logLevel, eventId, formatString, null);
		}

		public static Action<ILogger, T1, T2, Exception?> Define<T1, T2>(LogLevel logLevel, EventId eventId, string formatString, LogDefineOptions? options)
		{
			LogValuesFormatter formatter = CreateLogValuesFormatter(formatString, 2);
			if (options != null && options.SkipEnabledCheck)
			{
				return Log;
			}
			return delegate(ILogger logger, T1 arg1, T2 arg2, Exception exception)
			{
				if (logger.IsEnabled(logLevel))
				{
					Log(logger, arg1, arg2, exception);
				}
			};
			void Log(ILogger logger, T1 arg1, T2 arg2, Exception exception)
			{
				logger.Log(logLevel, eventId, new LogValues<T1, T2>(formatter, arg1, arg2), exception, LogValues<T1, T2>.Callback);
			}
		}

		public static Action<ILogger, T1, T2, T3, Exception?> Define<T1, T2, T3>(LogLevel logLevel, EventId eventId, string formatString)
		{
			return Define<T1, T2, T3>(logLevel, eventId, formatString, null);
		}

		public static Action<ILogger, T1, T2, T3, Exception?> Define<T1, T2, T3>(LogLevel logLevel, EventId eventId, string formatString, LogDefineOptions? options)
		{
			LogValuesFormatter formatter = CreateLogValuesFormatter(formatString, 3);
			if (options != null && options.SkipEnabledCheck)
			{
				return Log;
			}
			return delegate(ILogger logger, T1 arg1, T2 arg2, T3 arg3, Exception exception)
			{
				if (logger.IsEnabled(logLevel))
				{
					Log(logger, arg1, arg2, arg3, exception);
				}
			};
			void Log(ILogger logger, T1 arg1, T2 arg2, T3 arg3, Exception exception)
			{
				logger.Log(logLevel, eventId, new LogValues<T1, T2, T3>(formatter, arg1, arg2, arg3), exception, LogValues<T1, T2, T3>.Callback);
			}
		}

		public static Action<ILogger, T1, T2, T3, T4, Exception?> Define<T1, T2, T3, T4>(LogLevel logLevel, EventId eventId, string formatString)
		{
			return Define<T1, T2, T3, T4>(logLevel, eventId, formatString, null);
		}

		public static Action<ILogger, T1, T2, T3, T4, Exception?> Define<T1, T2, T3, T4>(LogLevel logLevel, EventId eventId, string formatString, LogDefineOptions? options)
		{
			LogValuesFormatter formatter = CreateLogValuesFormatter(formatString, 4);
			if (options != null && options.SkipEnabledCheck)
			{
				return Log;
			}
			return delegate(ILogger logger, T1 arg1, T2 arg2, T3 arg3, T4 arg4, Exception exception)
			{
				if (logger.IsEnabled(logLevel))
				{
					Log(logger, arg1, arg2, arg3, arg4, exception);
				}
			};
			void Log(ILogger logger, T1 arg1, T2 arg2, T3 arg3, T4 arg4, Exception exception)
			{
				logger.Log(logLevel, eventId, new LogValues<T1, T2, T3, T4>(formatter, arg1, arg2, arg3, arg4), exception, LogValues<T1, T2, T3, T4>.Callback);
			}
		}

		public static Action<ILogger, T1, T2, T3, T4, T5, Exception?> Define<T1, T2, T3, T4, T5>(LogLevel logLevel, EventId eventId, string formatString)
		{
			return Define<T1, T2, T3, T4, T5>(logLevel, eventId, formatString, null);
		}

		public static Action<ILogger, T1, T2, T3, T4, T5, Exception?> Define<T1, T2, T3, T4, T5>(LogLevel logLevel, EventId eventId, string formatString, LogDefineOptions? options)
		{
			LogValuesFormatter formatter = CreateLogValuesFormatter(formatString, 5);
			if (options != null && options.SkipEnabledCheck)
			{
				return Log;
			}
			return delegate(ILogger logger, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, Exception exception)
			{
				if (logger.IsEnabled(logLevel))
				{
					Log(logger, arg1, arg2, arg3, arg4, arg5, exception);
				}
			};
			void Log(ILogger logger, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, Exception exception)
			{
				logger.Log(logLevel, eventId, new LogValues<T1, T2, T3, T4, T5>(formatter, arg1, arg2, arg3, arg4, arg5), exception, LogValues<T1, T2, T3, T4, T5>.Callback);
			}
		}

		public static Action<ILogger, T1, T2, T3, T4, T5, T6, Exception?> Define<T1, T2, T3, T4, T5, T6>(LogLevel logLevel, EventId eventId, string formatString)
		{
			return Define<T1, T2, T3, T4, T5, T6>(logLevel, eventId, formatString, null);
		}

		public static Action<ILogger, T1, T2, T3, T4, T5, T6, Exception?> Define<T1, T2, T3, T4, T5, T6>(LogLevel logLevel, EventId eventId, string formatString, LogDefineOptions? options)
		{
			LogValuesFormatter formatter = CreateLogValuesFormatter(formatString, 6);
			if (options != null && options.SkipEnabledCheck)
			{
				return Log;
			}
			return delegate(ILogger logger, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, Exception exception)
			{
				if (logger.IsEnabled(logLevel))
				{
					Log(logger, arg1, arg2, arg3, arg4, arg5, arg6, exception);
				}
			};
			void Log(ILogger logger, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, Exception exception)
			{
				logger.Log(logLevel, eventId, new LogValues<T1, T2, T3, T4, T5, T6>(formatter, arg1, arg2, arg3, arg4, arg5, arg6), exception, LogValues<T1, T2, T3, T4, T5, T6>.Callback);
			}
		}

		private static LogValuesFormatter CreateLogValuesFormatter(string formatString, int expectedNamedParameterCount)
		{
			LogValuesFormatter logValuesFormatter = new LogValuesFormatter(formatString);
			int count = logValuesFormatter.ValueNames.Count;
			if (count != expectedNamedParameterCount)
			{
				throw new ArgumentException(System.SR.Format(System.SR.UnexpectedNumberOfNamedParameters, formatString, expectedNamedParameterCount, count));
			}
			return logValuesFormatter;
		}
	}
	[AttributeUsage(AttributeTargets.Method)]
	public sealed class LoggerMessageAttribute : Attribute
	{
		public int EventId { get; set; } = -1;


		public string? EventName { get; set; }

		public LogLevel Level { get; set; } = LogLevel.None;


		public string Message { get; set; } = "";


		public bool SkipEnabledCheck { get; set; }

		public LoggerMessageAttribute()
		{
		}

		public LoggerMessageAttribute(int eventId, LogLevel level, string message)
		{
			EventId = eventId;
			Level = level;
			Message = message;
		}

		public LoggerMessageAttribute(LogLevel level, string message)
		{
			Level = level;
			Message = message;
		}

		public LoggerMessageAttribute(LogLevel level)
		{
			Level = level;
		}

		public LoggerMessageAttribute(string message)
		{
			Message = message;
		}
	}
	[DebuggerDisplay("{DebuggerToString(),nq}")]
	public class Logger<T> : ILogger<T>, ILogger
	{
		[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
		private readonly ILogger _logger;

		public Logger(ILoggerFactory factory)
		{
			System.ThrowHelper.ThrowIfNull(factory, "factory");
			_logger = factory.CreateLogger(GetCategoryName());
		}

		IDisposable ILogger.BeginScope<TState>(TState state)
		{
			return _logger.BeginScope(state);
		}

		bool ILogger.IsEnabled(LogLevel logLevel)
		{
			return _logger.IsEnabled(logLevel);
		}

		void ILogger.Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
		{
			_logger.Log(logLevel, eventId, state, exception, formatter);
		}

		private static string GetCategoryName()
		{
			return TypeNameHelper.GetTypeDisplayName(typeof(T), fullName: true, includeGenericParameterNames: false, includeGenericParameters: false, '.');
		}

		internal string DebuggerToString()
		{
			return DebuggerDisplayFormatting.DebuggerToString(GetCategoryName(), this);
		}
	}
	public enum LogLevel
	{
		Trace,
		Debug,
		Information,
		Warning,
		Error,
		Critical,
		None
	}
	internal sealed class LogValuesFormatter
	{
		private const string NullValue = "(null)";

		private static readonly char[] FormatDelimiters = new char[2] { ',', ':' };

		private readonly List<string> _valueNames = new List<string>();

		private readonly string _format;

		public string OriginalFormat { get; private set; }

		public List<string> ValueNames => _valueNames;

		public LogValuesFormatter(string format)
		{
			System.ThrowHelper.ThrowIfNull(format, "format");
			OriginalFormat = format;
			Span<char> initialBuffer = stackalloc char[256];
			System.Text.ValueStringBuilder valueStringBuilder = new System.Text.ValueStringBuilder(initialBuffer);
			int num = 0;
			int length = format.Length;
			while (num < length)
			{
				int num2 = FindBraceIndex(format, '{', num, length);
				if (num == 0 && num2 == length)
				{
					_format = format;
					return;
				}
				int num3 = FindBraceIndex(format, '}', num2, length);
				if (num3 == length)
				{
					valueStringBuilder.Append(format.AsSpan(num, length - num));
					num = length;
					continue;
				}
				int num4 = FindIndexOfAny(format, FormatDelimiters, num2, num3);
				valueStringBuilder.Append(format.AsSpan(num, num2 - num + 1));
				valueStringBuilder.Append(_valueNames.Count.ToString());
				_valueNames.Add(format.Substring(num2 + 1, num4 - num2 - 1));
				valueStringBuilder.Append(format.AsSpan(num4, num3 - num4 + 1));
				num = num3 + 1;
			}
			_format = valueStringBuilder.ToString();
		}

		private static int FindBraceIndex(string format, char brace, int startIndex, int endIndex)
		{
			int result = endIndex;
			int i = startIndex;
			int num = 0;
			for (; i < endIndex; i++)
			{
				if (num > 0 && format[i] != brace)
				{
					if (num % 2 != 0)
					{
						break;
					}
					num = 0;
					result = endIndex;
				}
				else
				{
					if (format[i] != brace)
					{
						continue;
					}
					if (brace == '}')
					{
						if (num == 0)
						{
							result = i;
						}
					}
					else
					{
						result = i;
					}
					num++;
				}
			}
			return result;
		}

		private static int FindIndexOfAny(string format, char[] chars, int startIndex, int endIndex)
		{
			int num = format.IndexOfAny(chars, startIndex, endIndex - startIndex);
			if (num != -1)
			{
				return num;
			}
			return endIndex;
		}

		public string Format(object?[]? values)
		{
			object[] array = values;
			if (values != null)
			{
				for (int i = 0; i < values.Length; i++)
				{
					object obj = FormatArgument(values[i]);
					if (obj != values[i])
					{
						array = new object[values.Length];
						Array.Copy(values, array, i);
						array[i++] = obj;
						for (; i < values.Length; i++)
						{
							array[i] = FormatArgument(values[i]);
						}
						break;
					}
				}
			}
			return string.Format(CultureInfo.InvariantCulture, _format, array ?? Array.Empty<object>());
		}

		internal string FormatWithOverwrite(object?[]? values)
		{
			if (values != null)
			{
				for (int i = 0; i < values.Length; i++)
				{
					values[i] = FormatArgument(values[i]);
				}
			}
			return string.Format(CultureInfo.InvariantCulture, _format, values ?? Array.Empty<object>());
		}

		internal string Format()
		{
			return _format;
		}

		internal string Format(object? arg0)
		{
			return string.Format(CultureInfo.InvariantCulture, _format, FormatArgument(arg0));
		}

		internal string Format(object? arg0, object? arg1)
		{
			return string.Format(CultureInfo.InvariantCulture, _format, FormatArgument(arg0), FormatArgument(arg1));
		}

		internal string Format(object? arg0, object? arg1, object? arg2)
		{
			return string.Format(CultureInfo.InvariantCulture, _format, FormatArgument(arg0), FormatArgument(arg1), FormatArgument(arg2));
		}

		public KeyValuePair<string, object?> GetValue(object?[] values, int index)
		{
			if (index < 0 || index > _valueNames.Count)
			{
				throw new IndexOutOfRangeException("index");
			}
			if (_valueNames.Count > index)
			{
				return new KeyValuePair<string, object>(_valueNames[index], values[index]);
			}
			return new KeyValuePair<string, object>("{OriginalFormat}", OriginalFormat);
		}

		public IEnumerable<KeyValuePair<string, object?>> GetValues(object[] values)
		{
			KeyValuePair<string, object>[] array = new KeyValuePair<string, object>[values.Length + 1];
			for (int i = 0; i != _valueNames.Count; i++)
			{
				array[i] = new KeyValuePair<string, object>(_valueNames[i], values[i]);
			}
			array[^1] = new KeyValuePair<string, object>("{OriginalFormat}", OriginalFormat);
			return array;
		}

		private static object FormatArgument(object value)
		{
			object stringValue = null;
			if (!TryFormatArgumentIfNullOrEnumerable(value, ref stringValue))
			{
				return value;
			}
			return stringValue;
		}

		private static bool TryFormatArgumentIfNullOrEnumerable<T>(T value, [NotNullWhen(true)] ref object stringValue)
		{
			if (value == null)
			{
				stringValue = "(null)";
				return true;
			}
			if (!(value is string) && (object)value is IEnumerable enumerable)
			{
				Span<char> initialBuffer = stackalloc char[256];
				System.Text.ValueStringBuilder valueStringBuilder = new System.Text.ValueStringBuilder(initialBuffer);
				bool flag = true;
				foreach (object item in enumerable)
				{
					if (!flag)
					{
						valueStringBuilder.Append(", ");
					}
					valueStringBuilder.Append((item != null) ? item.ToString() : "(null)");
					flag = false;
				}
				stringValue = valueStringBuilder.ToString();
				return true;
			}
			return false;
		}
	}
	internal sealed class NullExternalScopeProvider : IExternalScopeProvider
	{
		public static IExternalScopeProvider Instance { get; } = new NullExternalScopeProvider();


		private NullExternalScopeProvider()
		{
		}

		void IExternalScopeProvider.ForEachScope<TState>(Action<object, TState> callback, TState state)
		{
		}

		IDisposable IExternalScopeProvider.Push(object state)
		{
			return NullScope.Instance;
		}
	}
	internal sealed class NullScope : IDisposable
	{
		public static NullScope Instance { get; } = new NullScope();


		private NullScope()
		{
		}

		public void Dispose()
		{
		}
	}
	internal static class DebuggerDisplayFormatting
	{
		internal static string DebuggerToString(string name, ILogger logger)
		{
			LogLevel? logLevel = CalculateEnabledLogLevel(logger);
			string text = "Name = \"" + name + "\"";
			if (logLevel.HasValue)
			{
				return text + $", MinLevel = {logLevel}";
			}
			return text + ", Enabled = false";
		}

		internal static LogLevel? CalculateEnabledLogLevel(ILogger logger)
		{
			Span<LogLevel> span = stackalloc LogLevel[6]
			{
				LogLevel.Critical,
				LogLevel.Error,
				LogLevel.Warning,
				LogLevel.Information,
				LogLevel.Debug,
				LogLevel.Trace
			};
			ReadOnlySpan<LogLevel> readOnlySpan = span;
			LogLevel? result = null;
			ReadOnlySpan<LogLevel> readOnlySpan2 = readOnlySpan;
			for (int i = 0; i < readOnlySpan2.Length; i++)
			{
				LogLevel logLevel = readOnlySpan2[i];
				if (!logger.IsEnabled(logLevel))
				{
					break;
				}
				result = logLevel;
			}
			return result;
		}
	}
}
namespace Microsoft.Extensions.Logging.Abstractions
{
	public readonly struct LogEntry<TState>
	{
		public LogLevel LogLevel { get; }

		public string Category { get; }

		public EventId EventId { get; }

		public TState State { get; }

		public Exception? Exception { get; }

		public Func<TState, Exception?, string> Formatter { get; }

		public LogEntry(LogLevel logLevel, string category, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
		{
			LogLevel = logLevel;
			Category = category;
			EventId = eventId;
			State = state;
			Exception = exception;
			Formatter = formatter;
		}
	}
	public class NullLogger : ILogger
	{
		public static NullLogger Instance { get; } = new NullLogger();


		private NullLogger()
		{
		}

		public IDisposable BeginScope<TState>(TState state) where TState : notnull
		{
			return NullScope.Instance;
		}

		public bool IsEnabled(LogLevel logLevel)
		{
			return false;
		}

		public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
		{
		}
	}
	public class NullLoggerFactory : ILoggerFactory, IDisposable
	{
		public static readonly NullLoggerFactory Instance = new NullLoggerFactory();

		public ILogger CreateLogger(string name)
		{
			return NullLogger.Instance;
		}

		public void AddProvider(ILoggerProvider provider)
		{
		}

		public void Dispose()
		{
		}
	}
	public class NullLoggerProvider : ILoggerProvider, IDisposable
	{
		public static NullLoggerProvider Instance { get; } = new NullLoggerProvider();


		private NullLoggerProvider()
		{
		}

		public ILogger CreateLogger(string categoryName)
		{
			return NullLogger.Instance;
		}

		public void Dispose()
		{
		}
	}
	public class NullLogger<T> : ILogger<T>, ILogger
	{
		public static readonly NullLogger<T> Instance = new NullLogger<T>();

		public IDisposable BeginScope<TState>(TState state) where TState : notnull
		{
			return NullScope.Instance;
		}

		public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
		{
		}

		public bool IsEnabled(LogLevel logLevel)
		{
			return false;
		}
	}
}

Mods/RealRadio/Microsoft.IO.RecyclableMemoryStream.dll

Decompiled a day ago
using System;
using System.Buffers;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Tracing;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Microsoft.IO.RecyclableMemoryStream")]
[assembly: AssemblyDescription("Pooled memory allocator.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("Microsoft.IO.RecyclableMemoryStream")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2015")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9ca0730b-3653-4fc4-b722-9e59fa70ea0b")]
[assembly: AssemblyFileVersion("3.0.0.0")]
[assembly: CLSCompliant(true)]
[assembly: AllowPartiallyTrustedCallers]
[assembly: SecurityRules(SecurityRuleSet.Level1)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyVersion("3.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 Microsoft.IO
{
	public sealed class RecyclableMemoryStreamManager
	{
		public sealed class StreamCreatedEventArgs : EventArgs
		{
			public Guid Id { get; }

			public string? Tag { get; }

			public long RequestedSize { get; }

			public long ActualSize { get; }

			public StreamCreatedEventArgs(Guid guid, string? tag, long requestedSize, long actualSize)
			{
				Id = guid;
				Tag = tag;
				RequestedSize = requestedSize;
				ActualSize = actualSize;
				base..ctor();
			}
		}

		public sealed class StreamDisposedEventArgs : EventArgs
		{
			public Guid Id { get; }

			public string? Tag { get; }

			public string? AllocationStack { get; }

			public string? DisposeStack { get; }

			public TimeSpan Lifetime { get; }

			public StreamDisposedEventArgs(Guid guid, string? tag, TimeSpan lifetime, string? allocationStack, string? disposeStack)
			{
				Id = guid;
				Tag = tag;
				AllocationStack = allocationStack;
				DisposeStack = disposeStack;
				Lifetime = lifetime;
				base..ctor();
			}
		}

		public sealed class StreamDoubleDisposedEventArgs : EventArgs
		{
			public Guid Id { get; }

			public string? Tag { get; }

			public string? AllocationStack { get; }

			public string? DisposeStack1 { get; }

			public string? DisposeStack2 { get; }

			public StreamDoubleDisposedEventArgs(Guid guid, string? tag, string? allocationStack, string? disposeStack1, string? disposeStack2)
			{
				Id = guid;
				Tag = tag;
				AllocationStack = allocationStack;
				DisposeStack1 = disposeStack1;
				DisposeStack2 = disposeStack2;
				base..ctor();
			}
		}

		public sealed class StreamFinalizedEventArgs : EventArgs
		{
			public Guid Id { get; }

			public string? Tag { get; }

			public string? AllocationStack { get; }

			public StreamFinalizedEventArgs(Guid guid, string? tag, string? allocationStack)
			{
				Id = guid;
				Tag = tag;
				AllocationStack = allocationStack;
				base..ctor();
			}
		}

		public sealed class StreamConvertedToArrayEventArgs : EventArgs
		{
			public Guid Id { get; }

			public string? Tag { get; }

			public string? Stack { get; }

			public long Length { get; }

			public StreamConvertedToArrayEventArgs(Guid guid, string? tag, string? stack, long length)
			{
				Id = guid;
				Tag = tag;
				Stack = stack;
				Length = length;
				base..ctor();
			}
		}

		public sealed class StreamOverCapacityEventArgs : EventArgs
		{
			public Guid Id { get; }

			public string? Tag { get; }

			public string? AllocationStack { get; }

			public long RequestedCapacity { get; }

			public long MaximumCapacity { get; }

			internal StreamOverCapacityEventArgs(Guid guid, string? tag, long requestedCapacity, long maximumCapacity, string? allocationStack)
			{
				Id = guid;
				Tag = tag;
				RequestedCapacity = requestedCapacity;
				MaximumCapacity = maximumCapacity;
				AllocationStack = allocationStack;
			}
		}

		public sealed class BlockCreatedEventArgs : EventArgs
		{
			public long SmallPoolInUse { get; }

			internal BlockCreatedEventArgs(long smallPoolInUse)
			{
				SmallPoolInUse = smallPoolInUse;
			}
		}

		public sealed class LargeBufferCreatedEventArgs : EventArgs
		{
			public Guid Id { get; }

			public string? Tag { get; }

			public bool Pooled { get; }

			public long RequiredSize { get; }

			public long LargePoolInUse { get; }

			public string? CallStack { get; }

			internal LargeBufferCreatedEventArgs(Guid guid, string? tag, long requiredSize, long largePoolInUse, bool pooled, string? callStack)
			{
				RequiredSize = requiredSize;
				LargePoolInUse = largePoolInUse;
				Pooled = pooled;
				Id = guid;
				Tag = tag;
				CallStack = callStack;
			}
		}

		public sealed class BufferDiscardedEventArgs : EventArgs
		{
			public Guid Id { get; }

			public string? Tag { get; }

			public Events.MemoryStreamBufferType BufferType { get; }

			public Events.MemoryStreamDiscardReason Reason { get; }

			internal BufferDiscardedEventArgs(Guid guid, string? tag, Events.MemoryStreamBufferType bufferType, Events.MemoryStreamDiscardReason reason)
			{
				Id = guid;
				Tag = tag;
				BufferType = bufferType;
				Reason = reason;
			}
		}

		public sealed class StreamLengthEventArgs : EventArgs
		{
			public long Length { get; }

			public StreamLengthEventArgs(long length)
			{
				Length = length;
				base..ctor();
			}
		}

		public sealed class UsageReportEventArgs : EventArgs
		{
			public long SmallPoolInUseBytes { get; }

			public long SmallPoolFreeBytes { get; }

			public long LargePoolInUseBytes { get; }

			public long LargePoolFreeBytes { get; }

			public UsageReportEventArgs(long smallPoolInUseBytes, long smallPoolFreeBytes, long largePoolInUseBytes, long largePoolFreeBytes)
			{
				SmallPoolInUseBytes = smallPoolInUseBytes;
				SmallPoolFreeBytes = smallPoolFreeBytes;
				LargePoolInUseBytes = largePoolInUseBytes;
				LargePoolFreeBytes = largePoolFreeBytes;
				base..ctor();
			}
		}

		[EventSource(Name = "Microsoft-IO-RecyclableMemoryStream", Guid = "{B80CD4E4-890E-468D-9CBA-90EB7C82DFC7}")]
		public sealed class Events : EventSource
		{
			public enum MemoryStreamBufferType
			{
				Small,
				Large
			}

			public enum MemoryStreamDiscardReason
			{
				TooLarge,
				EnoughFree
			}

			public static Events Writer = new Events();

			[Event(1, Level = EventLevel.Verbose, Version = 2)]
			public void MemoryStreamCreated(Guid guid, string? tag, long requestedSize, long actualSize)
			{
				if (IsEnabled(EventLevel.Verbose, EventKeywords.None))
				{
					WriteEvent(1, guid, tag ?? string.Empty, requestedSize, actualSize);
				}
			}

			[Event(2, Level = EventLevel.Verbose, Version = 3)]
			public void MemoryStreamDisposed(Guid guid, string? tag, long lifetimeMs, string? allocationStack, string? disposeStack)
			{
				if (IsEnabled(EventLevel.Verbose, EventKeywords.None))
				{
					WriteEvent(2, guid, tag ?? string.Empty, lifetimeMs, allocationStack ?? string.Empty, disposeStack ?? string.Empty);
				}
			}

			[Event(3, Level = EventLevel.Critical)]
			public void MemoryStreamDoubleDispose(Guid guid, string? tag, string? allocationStack, string? disposeStack1, string? disposeStack2)
			{
				if (IsEnabled())
				{
					WriteEvent(3, guid, tag ?? string.Empty, allocationStack ?? string.Empty, disposeStack1 ?? string.Empty, disposeStack2 ?? string.Empty);
				}
			}

			[Event(4, Level = EventLevel.Error)]
			public void MemoryStreamFinalized(Guid guid, string? tag, string? allocationStack)
			{
				if (IsEnabled())
				{
					WriteEvent(4, guid, tag ?? string.Empty, allocationStack ?? string.Empty);
				}
			}

			[Event(5, Level = EventLevel.Verbose, Version = 2)]
			public void MemoryStreamToArray(Guid guid, string? tag, string? stack, long size)
			{
				if (IsEnabled(EventLevel.Verbose, EventKeywords.None))
				{
					WriteEvent(5, guid, tag ?? string.Empty, stack ?? string.Empty, size);
				}
			}

			[Event(6, Level = EventLevel.Informational)]
			public void MemoryStreamManagerInitialized(int blockSize, int largeBufferMultiple, int maximumBufferSize)
			{
				if (IsEnabled())
				{
					WriteEvent(6, blockSize, largeBufferMultiple, maximumBufferSize);
				}
			}

			[Event(7, Level = EventLevel.Warning, Version = 2)]
			public void MemoryStreamNewBlockCreated(long smallPoolInUseBytes)
			{
				if (IsEnabled(EventLevel.Warning, EventKeywords.None))
				{
					WriteEvent(7, smallPoolInUseBytes);
				}
			}

			[Event(8, Level = EventLevel.Warning, Version = 3)]
			public void MemoryStreamNewLargeBufferCreated(long requiredSize, long largePoolInUseBytes)
			{
				if (IsEnabled(EventLevel.Warning, EventKeywords.None))
				{
					WriteEvent(8, requiredSize, largePoolInUseBytes);
				}
			}

			[Event(9, Level = EventLevel.Verbose, Version = 3)]
			public void MemoryStreamNonPooledLargeBufferCreated(Guid guid, string? tag, long requiredSize, string? allocationStack)
			{
				if (IsEnabled(EventLevel.Verbose, EventKeywords.None))
				{
					WriteEvent(9, guid, tag ?? string.Empty, requiredSize, allocationStack ?? string.Empty);
				}
			}

			[Event(10, Level = EventLevel.Warning, Version = 2)]
			public void MemoryStreamDiscardBuffer(Guid guid, string? tag, MemoryStreamBufferType bufferType, MemoryStreamDiscardReason reason, long smallBlocksFree, long smallPoolBytesFree, long smallPoolBytesInUse, long largeBlocksFree, long largePoolBytesFree, long largePoolBytesInUse)
			{
				if (IsEnabled(EventLevel.Warning, EventKeywords.None))
				{
					WriteEvent(10, guid, tag ?? string.Empty, bufferType, reason, smallBlocksFree, smallPoolBytesFree, smallPoolBytesInUse, largeBlocksFree, largePoolBytesFree, largePoolBytesInUse);
				}
			}

			[Event(11, Level = EventLevel.Error, Version = 3)]
			public void MemoryStreamOverCapacity(Guid guid, string? tag, long requestedCapacity, long maxCapacity, string? allocationStack)
			{
				if (IsEnabled())
				{
					WriteEvent(11, guid, tag ?? string.Empty, requestedCapacity, maxCapacity, allocationStack ?? string.Empty);
				}
			}
		}

		public class Options
		{
			public int BlockSize { get; set; } = 131072;


			public int LargeBufferMultiple { get; set; } = 1048576;


			public int MaximumBufferSize { get; set; } = 134217728;


			public long MaximumSmallPoolFreeBytes { get; set; }

			public long MaximumLargePoolFreeBytes { get; set; }

			public bool UseExponentialLargeBuffer { get; set; }

			public long MaximumStreamCapacity { get; set; }

			public bool GenerateCallStacks { get; set; }

			public bool AggressiveBufferReturn { get; set; }

			public bool ThrowExceptionOnToArray { get; set; }

			public bool ZeroOutBuffer { get; set; }

			public Options()
			{
			}

			public Options(int blockSize, int largeBufferMultiple, int maximumBufferSize, long maximumSmallPoolFreeBytes, long maximumLargePoolFreeBytes)
			{
				BlockSize = blockSize;
				LargeBufferMultiple = largeBufferMultiple;
				MaximumBufferSize = maximumBufferSize;
				MaximumSmallPoolFreeBytes = maximumSmallPoolFreeBytes;
				MaximumLargePoolFreeBytes = maximumLargePoolFreeBytes;
			}
		}

		internal const int MaxArrayLength = 2147483591;

		public const int DefaultBlockSize = 131072;

		public const int DefaultLargeBufferMultiple = 1048576;

		public const int DefaultMaximumBufferSize = 134217728;

		private const long DefaultMaxSmallPoolFreeBytes = 0L;

		private const long DefaultMaxLargePoolFreeBytes = 0L;

		private readonly long[] largeBufferFreeSize;

		private readonly long[] largeBufferInUseSize;

		private readonly ConcurrentStack<byte[]>[] largePools;

		private readonly ConcurrentStack<byte[]> smallPool;

		private long smallPoolFreeSize;

		private long smallPoolInUseSize;

		internal readonly Options options;

		public Options Settings => options;

		public long SmallPoolFreeSize => smallPoolFreeSize;

		public long SmallPoolInUseSize => smallPoolInUseSize;

		public long LargePoolFreeSize
		{
			get
			{
				long num = 0L;
				long[] array = largeBufferFreeSize;
				foreach (long num2 in array)
				{
					num += num2;
				}
				return num;
			}
		}

		public long LargePoolInUseSize
		{
			get
			{
				long num = 0L;
				long[] array = largeBufferInUseSize;
				foreach (long num2 in array)
				{
					num += num2;
				}
				return num;
			}
		}

		public long SmallBlocksFree => smallPool.Count;

		public long LargeBuffersFree
		{
			get
			{
				long num = 0L;
				ConcurrentStack<byte[]>[] array = largePools;
				foreach (ConcurrentStack<byte[]> concurrentStack in array)
				{
					num += concurrentStack.Count;
				}
				return num;
			}
		}

		public event EventHandler<BlockCreatedEventArgs>? BlockCreated;

		public event EventHandler<LargeBufferCreatedEventArgs>? LargeBufferCreated;

		public event EventHandler<StreamCreatedEventArgs>? StreamCreated;

		public event EventHandler<StreamDisposedEventArgs>? StreamDisposed;

		public event EventHandler<StreamDoubleDisposedEventArgs>? StreamDoubleDisposed;

		public event EventHandler<StreamFinalizedEventArgs>? StreamFinalized;

		public event EventHandler<StreamLengthEventArgs>? StreamLength;

		public event EventHandler<StreamConvertedToArrayEventArgs>? StreamConvertedToArray;

		public event EventHandler<StreamOverCapacityEventArgs>? StreamOverCapacity;

		public event EventHandler<BufferDiscardedEventArgs>? BufferDiscarded;

		public event EventHandler<UsageReportEventArgs>? UsageReport;

		public RecyclableMemoryStreamManager()
			: this(new Options())
		{
		}

		public RecyclableMemoryStreamManager(Options options)
		{
			if (options.BlockSize <= 0)
			{
				throw new InvalidOperationException("BlockSize must be a positive number");
			}
			if (options.LargeBufferMultiple <= 0)
			{
				throw new InvalidOperationException("LargeBufferMultiple must be a positive number");
			}
			if (options.MaximumBufferSize < options.BlockSize)
			{
				throw new InvalidOperationException("MaximumBufferSize must be at least BlockSize");
			}
			if (options.MaximumSmallPoolFreeBytes < 0)
			{
				throw new InvalidOperationException("MaximumSmallPoolFreeBytes must be non-negative");
			}
			if (options.MaximumLargePoolFreeBytes < 0)
			{
				throw new InvalidOperationException("MaximumLargePoolFreeBytes must be non-negative");
			}
			this.options = options;
			if (!IsLargeBufferSize(options.MaximumBufferSize))
			{
				throw new InvalidOperationException("MaximumBufferSize is not " + (options.UseExponentialLargeBuffer ? "an exponential" : "a multiple") + " of LargeBufferMultiple.");
			}
			smallPool = new ConcurrentStack<byte[]>();
			int num = (options.UseExponentialLargeBuffer ? ((int)Math.Log(options.MaximumBufferSize / options.LargeBufferMultiple, 2.0) + 1) : (options.MaximumBufferSize / options.LargeBufferMultiple));
			largeBufferInUseSize = new long[num + 1];
			largeBufferFreeSize = new long[num];
			largePools = new ConcurrentStack<byte[]>[num];
			for (int i = 0; i < largePools.Length; i++)
			{
				largePools[i] = new ConcurrentStack<byte[]>();
			}
			Events.Writer.MemoryStreamManagerInitialized(options.BlockSize, options.LargeBufferMultiple, options.MaximumBufferSize);
		}

		internal byte[] GetBlock()
		{
			Interlocked.Add(ref smallPoolInUseSize, options.BlockSize);
			if (!smallPool.TryPop(out byte[] result))
			{
				result = new byte[options.BlockSize];
				ReportBlockCreated();
			}
			else
			{
				Interlocked.Add(ref smallPoolFreeSize, -options.BlockSize);
			}
			return result;
		}

		internal byte[] GetLargeBuffer(long requiredSize, Guid id, string? tag)
		{
			if (requiredSize > 2147483591)
			{
				throw new OutOfMemoryException($"Requested size exceeds maximum array length of {2147483591}.");
			}
			requiredSize = RoundToLargeBufferSize(requiredSize);
			int num = GetPoolIndex(requiredSize);
			bool flag = false;
			bool pooled = true;
			string callStack = null;
			byte[] result;
			if (num < largePools.Length)
			{
				if (!largePools[num].TryPop(out result))
				{
					result = AllocateArray(requiredSize, options.ZeroOutBuffer);
					flag = true;
				}
				else
				{
					Interlocked.Add(ref largeBufferFreeSize[num], -result.Length);
				}
			}
			else
			{
				num = largeBufferInUseSize.Length - 1;
				result = AllocateArray(requiredSize, options.ZeroOutBuffer);
				if (options.GenerateCallStacks)
				{
					callStack = Environment.StackTrace;
				}
				flag = true;
				pooled = false;
			}
			Interlocked.Add(ref largeBufferInUseSize[num], result.Length);
			if (flag)
			{
				ReportLargeBufferCreated(id, tag, requiredSize, pooled, callStack);
			}
			return result;
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			static byte[] AllocateArray(long requiredSize, bool zeroInitializeArray)
			{
				return new byte[requiredSize];
			}
		}

		private long RoundToLargeBufferSize(long requiredSize)
		{
			if (options.UseExponentialLargeBuffer)
			{
				long num = 1L;
				while (options.LargeBufferMultiple * num < requiredSize)
				{
					num <<= 1;
				}
				return options.LargeBufferMultiple * num;
			}
			return (requiredSize + options.LargeBufferMultiple - 1) / options.LargeBufferMultiple * options.LargeBufferMultiple;
		}

		private bool IsLargeBufferSize(int value)
		{
			if (value != 0)
			{
				if (!options.UseExponentialLargeBuffer)
				{
					return value % options.LargeBufferMultiple == 0;
				}
				return value == RoundToLargeBufferSize(value);
			}
			return false;
		}

		private int GetPoolIndex(long length)
		{
			if (options.UseExponentialLargeBuffer)
			{
				int i;
				for (i = 0; options.LargeBufferMultiple << i < length; i++)
				{
				}
				return i;
			}
			return (int)(length / options.LargeBufferMultiple - 1);
		}

		internal void ReturnLargeBuffer(byte[] buffer, Guid id, string? tag)
		{
			if (buffer == null)
			{
				throw new ArgumentNullException("buffer");
			}
			if (!IsLargeBufferSize(buffer.Length))
			{
				throw new ArgumentException("buffer did not originate from this memory manager. The size is not " + string.Format("{0} of {1}.", options.UseExponentialLargeBuffer ? "an exponential" : "a multiple", options.LargeBufferMultiple));
			}
			ZeroOutMemoryIfEnabled(buffer);
			int num = GetPoolIndex(buffer.Length);
			if (num < largePools.Length)
			{
				if ((largePools[num].Count + 1) * buffer.Length <= options.MaximumLargePoolFreeBytes || options.MaximumLargePoolFreeBytes == 0L)
				{
					largePools[num].Push(buffer);
					Interlocked.Add(ref largeBufferFreeSize[num], buffer.Length);
				}
				else
				{
					ReportBufferDiscarded(id, tag, Events.MemoryStreamBufferType.Large, Events.MemoryStreamDiscardReason.EnoughFree);
				}
			}
			else
			{
				num = largeBufferInUseSize.Length - 1;
				ReportBufferDiscarded(id, tag, Events.MemoryStreamBufferType.Large, Events.MemoryStreamDiscardReason.TooLarge);
			}
			Interlocked.Add(ref largeBufferInUseSize[num], -buffer.Length);
		}

		internal void ReturnBlocks(List<byte[]> blocks, Guid id, string? tag)
		{
			if (blocks == null)
			{
				throw new ArgumentNullException("blocks");
			}
			long num = (long)blocks.Count * (long)options.BlockSize;
			Interlocked.Add(ref smallPoolInUseSize, -num);
			foreach (byte[] block in blocks)
			{
				if (block == null || block.Length != options.BlockSize)
				{
					throw new ArgumentException("blocks contains buffers that are not BlockSize in length.", "blocks");
				}
			}
			foreach (byte[] block2 in blocks)
			{
				ZeroOutMemoryIfEnabled(block2);
				if (options.MaximumSmallPoolFreeBytes == 0L || SmallPoolFreeSize < options.MaximumSmallPoolFreeBytes)
				{
					Interlocked.Add(ref smallPoolFreeSize, options.BlockSize);
					smallPool.Push(block2);
					continue;
				}
				ReportBufferDiscarded(id, tag, Events.MemoryStreamBufferType.Small, Events.MemoryStreamDiscardReason.EnoughFree);
				break;
			}
		}

		internal void ReturnBlock(byte[] block, Guid id, string? tag)
		{
			int blockSize = options.BlockSize;
			Interlocked.Add(ref smallPoolInUseSize, -blockSize);
			if (block == null)
			{
				throw new ArgumentNullException("block");
			}
			if (block.Length != options.BlockSize)
			{
				throw new ArgumentException("block is not not BlockSize in length.");
			}
			ZeroOutMemoryIfEnabled(block);
			if (options.MaximumSmallPoolFreeBytes == 0L || SmallPoolFreeSize < options.MaximumSmallPoolFreeBytes)
			{
				Interlocked.Add(ref smallPoolFreeSize, options.BlockSize);
				smallPool.Push(block);
			}
			else
			{
				ReportBufferDiscarded(id, tag, Events.MemoryStreamBufferType.Small, Events.MemoryStreamDiscardReason.EnoughFree);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private void ZeroOutMemoryIfEnabled(byte[] buffer)
		{
			if (options.ZeroOutBuffer)
			{
				Array.Clear(buffer, 0, buffer.Length);
			}
		}

		internal void ReportBlockCreated()
		{
			Events.Writer.MemoryStreamNewBlockCreated(smallPoolInUseSize);
			this.BlockCreated?.Invoke(this, new BlockCreatedEventArgs(smallPoolInUseSize));
		}

		internal void ReportLargeBufferCreated(Guid id, string? tag, long requiredSize, bool pooled, string? callStack)
		{
			if (pooled)
			{
				Events.Writer.MemoryStreamNewLargeBufferCreated(requiredSize, LargePoolInUseSize);
			}
			else
			{
				Events.Writer.MemoryStreamNonPooledLargeBufferCreated(id, tag, requiredSize, callStack);
			}
			this.LargeBufferCreated?.Invoke(this, new LargeBufferCreatedEventArgs(id, tag, requiredSize, LargePoolInUseSize, pooled, callStack));
		}

		internal void ReportBufferDiscarded(Guid id, string? tag, Events.MemoryStreamBufferType bufferType, Events.MemoryStreamDiscardReason reason)
		{
			Events.Writer.MemoryStreamDiscardBuffer(id, tag, bufferType, reason, SmallBlocksFree, smallPoolFreeSize, smallPoolInUseSize, LargeBuffersFree, LargePoolFreeSize, LargePoolInUseSize);
			this.BufferDiscarded?.Invoke(this, new BufferDiscardedEventArgs(id, tag, bufferType, reason));
		}

		internal void ReportStreamCreated(Guid id, string? tag, long requestedSize, long actualSize)
		{
			Events.Writer.MemoryStreamCreated(id, tag, requestedSize, actualSize);
			this.StreamCreated?.Invoke(this, new StreamCreatedEventArgs(id, tag, requestedSize, actualSize));
		}

		internal void ReportStreamDisposed(Guid id, string? tag, TimeSpan lifetime, string? allocationStack, string? disposeStack)
		{
			Events.Writer.MemoryStreamDisposed(id, tag, (long)lifetime.TotalMilliseconds, allocationStack, disposeStack);
			this.StreamDisposed?.Invoke(this, new StreamDisposedEventArgs(id, tag, lifetime, allocationStack, disposeStack));
		}

		internal void ReportStreamDoubleDisposed(Guid id, string? tag, string? allocationStack, string? disposeStack1, string? disposeStack2)
		{
			Events.Writer.MemoryStreamDoubleDispose(id, tag, allocationStack, disposeStack1, disposeStack2);
			this.StreamDoubleDisposed?.Invoke(this, new StreamDoubleDisposedEventArgs(id, tag, allocationStack, disposeStack1, disposeStack2));
		}

		internal void ReportStreamFinalized(Guid id, string? tag, string? allocationStack)
		{
			Events.Writer.MemoryStreamFinalized(id, tag, allocationStack);
			this.StreamFinalized?.Invoke(this, new StreamFinalizedEventArgs(id, tag, allocationStack));
		}

		internal void ReportStreamLength(long bytes)
		{
			this.StreamLength?.Invoke(this, new StreamLengthEventArgs(bytes));
		}

		internal void ReportStreamToArray(Guid id, string? tag, string? stack, long length)
		{
			Events.Writer.MemoryStreamToArray(id, tag, stack, length);
			this.StreamConvertedToArray?.Invoke(this, new StreamConvertedToArrayEventArgs(id, tag, stack, length));
		}

		internal void ReportStreamOverCapacity(Guid id, string? tag, long requestedCapacity, string? allocationStack)
		{
			Events.Writer.MemoryStreamOverCapacity(id, tag, requestedCapacity, options.MaximumStreamCapacity, allocationStack);
			this.StreamOverCapacity?.Invoke(this, new StreamOverCapacityEventArgs(id, tag, requestedCapacity, options.MaximumStreamCapacity, allocationStack));
		}

		internal void ReportUsageReport()
		{
			this.UsageReport?.Invoke(this, new UsageReportEventArgs(smallPoolInUseSize, smallPoolFreeSize, LargePoolInUseSize, LargePoolFreeSize));
		}

		public RecyclableMemoryStream GetStream()
		{
			return new RecyclableMemoryStream(this);
		}

		public RecyclableMemoryStream GetStream(Guid id)
		{
			return new RecyclableMemoryStream(this, id);
		}

		public RecyclableMemoryStream GetStream(string? tag)
		{
			return new RecyclableMemoryStream(this, tag);
		}

		public RecyclableMemoryStream GetStream(Guid id, string? tag)
		{
			return new RecyclableMemoryStream(this, id, tag);
		}

		public RecyclableMemoryStream GetStream(string? tag, long requiredSize)
		{
			return new RecyclableMemoryStream(this, tag, requiredSize);
		}

		public RecyclableMemoryStream GetStream(Guid id, string? tag, long requiredSize)
		{
			return new RecyclableMemoryStream(this, id, tag, requiredSize);
		}

		public RecyclableMemoryStream GetStream(Guid id, string? tag, long requiredSize, bool asContiguousBuffer)
		{
			if (!asContiguousBuffer || requiredSize <= options.BlockSize)
			{
				return GetStream(id, tag, requiredSize);
			}
			return new RecyclableMemoryStream(this, id, tag, requiredSize, GetLargeBuffer(requiredSize, id, tag));
		}

		public RecyclableMemoryStream GetStream(string? tag, long requiredSize, bool asContiguousBuffer)
		{
			return GetStream(Guid.NewGuid(), tag, requiredSize, asContiguousBuffer);
		}

		public RecyclableMemoryStream GetStream(Guid id, string? tag, byte[] buffer, int offset, int count)
		{
			RecyclableMemoryStream recyclableMemoryStream = null;
			try
			{
				recyclableMemoryStream = new RecyclableMemoryStream(this, id, tag, count);
				recyclableMemoryStream.Write(buffer, offset, count);
				recyclableMemoryStream.Position = 0L;
				return recyclableMemoryStream;
			}
			catch
			{
				recyclableMemoryStream?.Dispose();
				throw;
			}
		}

		public RecyclableMemoryStream GetStream(byte[] buffer)
		{
			return GetStream(null, buffer, 0, buffer.Length);
		}

		public RecyclableMemoryStream GetStream(string? tag, byte[] buffer, int offset, int count)
		{
			return GetStream(Guid.NewGuid(), tag, buffer, offset, count);
		}

		public RecyclableMemoryStream GetStream(Guid id, string? tag, ReadOnlySpan<byte> buffer)
		{
			RecyclableMemoryStream recyclableMemoryStream = null;
			try
			{
				recyclableMemoryStream = new RecyclableMemoryStream(this, id, tag, buffer.Length);
				recyclableMemoryStream.Write(buffer);
				recyclableMemoryStream.Position = 0L;
				return recyclableMemoryStream;
			}
			catch
			{
				recyclableMemoryStream?.Dispose();
				throw;
			}
		}

		public RecyclableMemoryStream GetStream(ReadOnlySpan<byte> buffer)
		{
			return GetStream(null, buffer);
		}

		public RecyclableMemoryStream GetStream(string? tag, ReadOnlySpan<byte> buffer)
		{
			return GetStream(Guid.NewGuid(), tag, buffer);
		}
	}
	public sealed class RecyclableMemoryStream : MemoryStream, IBufferWriter<byte>
	{
		private sealed class BlockSegment : ReadOnlySequenceSegment<byte>
		{
			public BlockSegment(Memory<byte> memory)
			{
				base.Memory = memory;
			}

			public BlockSegment Append(Memory<byte> memory)
			{
				return (BlockSegment)(base.Next = new BlockSegment(memory)
				{
					RunningIndex = base.RunningIndex + base.Memory.Length
				});
			}
		}

		private struct BlockAndOffset
		{
			public int Block;

			public int Offset;

			public BlockAndOffset(int block, int offset)
			{
				Block = block;
				Offset = offset;
			}
		}

		private readonly List<byte[]> blocks;

		private readonly Guid id;

		private readonly RecyclableMemoryStreamManager memoryManager;

		private readonly string? tag;

		private readonly long creationTimestamp;

		private List<byte[]>? dirtyBuffers;

		private bool disposed;

		private byte[]? largeBuffer;

		private long length;

		private long position;

		private byte[]? bufferWriterTempBuffer;

		internal Guid Id
		{
			get
			{
				CheckDisposed();
				return id;
			}
		}

		internal string? Tag
		{
			get
			{
				CheckDisposed();
				return tag;
			}
		}

		internal RecyclableMemoryStreamManager MemoryManager
		{
			get
			{
				CheckDisposed();
				return memoryManager;
			}
		}

		internal string? AllocationStack { get; }

		internal string? DisposeStack { get; private set; }

		public override int Capacity
		{
			get
			{
				CheckDisposed();
				if (largeBuffer != null)
				{
					return largeBuffer.Length;
				}
				long num = (long)blocks.Count * (long)memoryManager.options.BlockSize;
				if (num > int.MaxValue)
				{
					throw new InvalidOperationException("Capacity is larger than int.MaxValue. Use Capacity64 instead.");
				}
				return (int)num;
			}
			set
			{
				Capacity64 = value;
			}
		}

		public long Capacity64
		{
			get
			{
				CheckDisposed();
				if (largeBuffer != null)
				{
					return largeBuffer.Length;
				}
				return (long)blocks.Count * (long)memoryManager.options.BlockSize;
			}
			set
			{
				CheckDisposed();
				EnsureCapacity(value);
			}
		}

		public override long Length
		{
			get
			{
				CheckDisposed();
				return length;
			}
		}

		public override long Position
		{
			get
			{
				CheckDisposed();
				return position;
			}
			set
			{
				CheckDisposed();
				if (value < 0)
				{
					throw new ArgumentOutOfRangeException("value", "value must be non-negative.");
				}
				if (largeBuffer != null && value > 2147483591)
				{
					throw new InvalidOperationException($"Once the stream is converted to a single large buffer, position cannot be set past {2147483591}.");
				}
				position = value;
			}
		}

		public override bool CanRead => !Disposed;

		public override bool CanSeek => !Disposed;

		public override bool CanTimeout => false;

		public override bool CanWrite => !Disposed;

		private bool Disposed => disposed;

		public RecyclableMemoryStream(RecyclableMemoryStreamManager memoryManager)
			: this(memoryManager, Guid.NewGuid(), null, 0L, null)
		{
		}

		public RecyclableMemoryStream(RecyclableMemoryStreamManager memoryManager, Guid id)
			: this(memoryManager, id, null, 0L, null)
		{
		}

		public RecyclableMemoryStream(RecyclableMemoryStreamManager memoryManager, string? tag)
			: this(memoryManager, Guid.NewGuid(), tag, 0L, null)
		{
		}

		public RecyclableMemoryStream(RecyclableMemoryStreamManager memoryManager, Guid id, string? tag)
			: this(memoryManager, id, tag, 0L, null)
		{
		}

		public RecyclableMemoryStream(RecyclableMemoryStreamManager memoryManager, string? tag, long requestedSize)
			: this(memoryManager, Guid.NewGuid(), tag, requestedSize, null)
		{
		}

		public RecyclableMemoryStream(RecyclableMemoryStreamManager memoryManager, Guid id, string? tag, long requestedSize)
			: this(memoryManager, id, tag, requestedSize, null)
		{
		}

		internal RecyclableMemoryStream(RecyclableMemoryStreamManager memoryManager, Guid id, string? tag, long requestedSize, byte[]? initialLargeBuffer)
			: base(Array.Empty<byte>())
		{
			this.memoryManager = memoryManager;
			this.id = id;
			this.tag = tag;
			blocks = new List<byte[]>();
			creationTimestamp = Stopwatch.GetTimestamp();
			long num = Math.Max(requestedSize, this.memoryManager.options.BlockSize);
			if (initialLargeBuffer == null)
			{
				EnsureCapacity(num);
			}
			else
			{
				largeBuffer = initialLargeBuffer;
			}
			if (this.memoryManager.options.GenerateCallStacks)
			{
				AllocationStack = Environment.StackTrace;
			}
			this.memoryManager.ReportStreamCreated(this.id, this.tag, requestedSize, num);
			this.memoryManager.ReportUsageReport();
		}

		~RecyclableMemoryStream()
		{
			Dispose(disposing: false);
		}

		protected override void Dispose(bool disposing)
		{
			if (disposed)
			{
				string disposeStack = null;
				if (memoryManager.options.GenerateCallStacks)
				{
					disposeStack = Environment.StackTrace;
				}
				memoryManager.ReportStreamDoubleDisposed(id, tag, AllocationStack, DisposeStack, disposeStack);
				return;
			}
			disposed = true;
			TimeSpan lifetime = TimeSpan.FromTicks((Stopwatch.GetTimestamp() - creationTimestamp) * 10000000 / Stopwatch.Frequency);
			if (memoryManager.options.GenerateCallStacks)
			{
				DisposeStack = Environment.StackTrace;
			}
			memoryManager.ReportStreamDisposed(id, tag, lifetime, AllocationStack, DisposeStack);
			if (disposing)
			{
				GC.SuppressFinalize(this);
			}
			else
			{
				memoryManager.ReportStreamFinalized(id, tag, AllocationStack);
				if (AppDomain.CurrentDomain.IsFinalizingForUnload())
				{
					base.Dispose(disposing);
					return;
				}
			}
			memoryManager.ReportStreamLength(length);
			if (largeBuffer != null)
			{
				memoryManager.ReturnLargeBuffer(largeBuffer, id, tag);
			}
			if (dirtyBuffers != null)
			{
				foreach (byte[] dirtyBuffer in dirtyBuffers)
				{
					memoryManager.ReturnLargeBuffer(dirtyBuffer, id, tag);
				}
			}
			memoryManager.ReturnBlocks(blocks, id, tag);
			memoryManager.ReportUsageReport();
			blocks.Clear();
			base.Dispose(disposing);
		}

		public override void Close()
		{
			Dispose(disposing: true);
		}

		public override byte[] GetBuffer()
		{
			CheckDisposed();
			if (largeBuffer != null)
			{
				return largeBuffer;
			}
			if (blocks.Count == 1)
			{
				return blocks[0];
			}
			byte[] buffer = memoryManager.GetLargeBuffer(Capacity64, id, tag);
			AssertLengthIsSmall();
			InternalRead(buffer, 0, (int)length, 0L);
			largeBuffer = buffer;
			if (blocks.Count > 0 && memoryManager.options.AggressiveBufferReturn)
			{
				memoryManager.ReturnBlocks(blocks, id, tag);
				blocks.Clear();
			}
			return largeBuffer;
		}

		public override void CopyTo(Stream destination, int bufferSize)
		{
			WriteTo(destination, position, length - position);
		}

		public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken)
		{
			if (destination == null)
			{
				throw new ArgumentNullException("destination");
			}
			CheckDisposed();
			if (length == 0L)
			{
				return Task.CompletedTask;
			}
			long num = position;
			long num2 = length - num;
			position += num2;
			if (destination is MemoryStream stream)
			{
				WriteTo(stream, num, num2);
				return Task.CompletedTask;
			}
			if (largeBuffer == null)
			{
				if (blocks.Count == 1)
				{
					AssertLengthIsSmall();
					return destination.WriteAsync(blocks[0], (int)num, (int)num2, cancellationToken);
				}
				return CopyToAsyncImpl(destination, GetBlockAndRelativeOffset(num), num2, blocks, cancellationToken);
			}
			AssertLengthIsSmall();
			return destination.WriteAsync(largeBuffer, (int)num, (int)num2, cancellationToken);
			static async Task CopyToAsyncImpl(Stream destination, BlockAndOffset blockAndOffset, long count, List<byte[]> blocks, CancellationToken cancellationToken)
			{
				long bytesRemaining = count;
				int currentBlock = blockAndOffset.Block;
				int num3 = blockAndOffset.Offset;
				while (bytesRemaining > 0)
				{
					byte[] array = blocks[currentBlock];
					int amountToCopy = (int)Math.Min(array.Length - num3, bytesRemaining);
					await destination.WriteAsync(array, num3, amountToCopy, cancellationToken);
					bytesRemaining -= amountToCopy;
					int num4 = currentBlock + 1;
					currentBlock = num4;
					num3 = 0;
				}
			}
		}

		public void Advance(int count)
		{
			CheckDisposed();
			if (count < 0)
			{
				throw new ArgumentOutOfRangeException("count", "count must be non-negative.");
			}
			byte[] array = bufferWriterTempBuffer;
			if (array != null)
			{
				if (count > array.Length)
				{
					throw new InvalidOperationException($"Cannot advance past the end of the buffer, which has a size of {array.Length}.");
				}
				Write(array, 0, count);
				ReturnTempBuffer(array);
				bufferWriterTempBuffer = null;
			}
			else
			{
				long num = ((largeBuffer == null) ? (memoryManager.options.BlockSize - GetBlockAndRelativeOffset(position).Offset) : (largeBuffer.Length - position));
				if (count > num)
				{
					throw new InvalidOperationException($"Cannot advance past the end of the buffer, which has a size of {num}.");
				}
				position += count;
				length = Math.Max(position, length);
			}
		}

		private void ReturnTempBuffer(byte[] buffer)
		{
			if (buffer.Length == memoryManager.options.BlockSize)
			{
				memoryManager.ReturnBlock(buffer, id, tag);
			}
			else
			{
				memoryManager.ReturnLargeBuffer(buffer, id, tag);
			}
		}

		public Memory<byte> GetMemory(int sizeHint = 0)
		{
			return GetWritableBuffer(sizeHint);
		}

		public Span<byte> GetSpan(int sizeHint = 0)
		{
			return GetWritableBuffer(sizeHint);
		}

		private ArraySegment<byte> GetWritableBuffer(int sizeHint)
		{
			CheckDisposed();
			if (sizeHint < 0)
			{
				throw new ArgumentOutOfRangeException("sizeHint", "sizeHint must be non-negative.");
			}
			int num = Math.Max(sizeHint, 1);
			EnsureCapacity(position + num);
			if (bufferWriterTempBuffer != null)
			{
				ReturnTempBuffer(bufferWriterTempBuffer);
				bufferWriterTempBuffer = null;
			}
			if (largeBuffer != null)
			{
				return new ArraySegment<byte>(largeBuffer, (int)position, largeBuffer.Length - (int)position);
			}
			BlockAndOffset blockAndRelativeOffset = GetBlockAndRelativeOffset(position);
			if (MemoryManager.options.BlockSize - blockAndRelativeOffset.Offset >= num)
			{
				return new ArraySegment<byte>(blocks[blockAndRelativeOffset.Block], blockAndRelativeOffset.Offset, MemoryManager.options.BlockSize - blockAndRelativeOffset.Offset);
			}
			bufferWriterTempBuffer = ((num > memoryManager.options.BlockSize) ? memoryManager.GetLargeBuffer(num, id, tag) : memoryManager.GetBlock());
			return new ArraySegment<byte>(bufferWriterTempBuffer);
		}

		public ReadOnlySequence<byte> GetReadOnlySequence()
		{
			CheckDisposed();
			if (largeBuffer != null)
			{
				AssertLengthIsSmall();
				return new ReadOnlySequence<byte>(largeBuffer, 0, (int)length);
			}
			if (blocks.Count == 1)
			{
				AssertLengthIsSmall();
				return new ReadOnlySequence<byte>(blocks[0], 0, (int)length);
			}
			BlockSegment blockSegment = new BlockSegment(blocks[0]);
			BlockSegment blockSegment2 = blockSegment;
			int num = 1;
			while (blockSegment2.RunningIndex + blockSegment2.Memory.Length < length)
			{
				blockSegment2 = blockSegment2.Append(blocks[num]);
				num++;
			}
			return new ReadOnlySequence<byte>(blockSegment, 0, blockSegment2, (int)(length - blockSegment2.RunningIndex));
		}

		public override bool TryGetBuffer(out ArraySegment<byte> buffer)
		{
			CheckDisposed();
			try
			{
				if (length <= 2147483591)
				{
					buffer = new ArraySegment<byte>(GetBuffer(), 0, (int)Length);
					return true;
				}
			}
			catch (OutOfMemoryException)
			{
			}
			buffer = ArraySegment<byte>.Empty;
			return false;
		}

		[Obsolete("This method has degraded performance vs. GetBuffer and should be avoided.")]
		public override byte[] ToArray()
		{
			CheckDisposed();
			string stack = (memoryManager.options.GenerateCallStacks ? Environment.StackTrace : null);
			memoryManager.ReportStreamToArray(id, tag, stack, length);
			if (memoryManager.options.ThrowExceptionOnToArray)
			{
				throw new NotSupportedException("The underlying RecyclableMemoryStreamManager is configured to not allow calls to ToArray.");
			}
			byte[] array = new byte[Length];
			InternalRead(array, 0, (int)length, 0L);
			return array;
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			return SafeRead(buffer, offset, count, ref position);
		}

		public int SafeRead(byte[] buffer, int offset, int count, ref long streamPosition)
		{
			CheckDisposed();
			if (buffer == null)
			{
				throw new ArgumentNullException("buffer");
			}
			if (offset < 0)
			{
				throw new ArgumentOutOfRangeException("offset", "offset cannot be negative.");
			}
			if (count < 0)
			{
				throw new ArgumentOutOfRangeException("count", "count cannot be negative.");
			}
			if (offset + count > buffer.Length)
			{
				throw new ArgumentException("buffer length must be at least offset + count.");
			}
			int num = InternalRead(buffer, offset, count, streamPosition);
			streamPosition += num;
			return num;
		}

		public override int Read(Span<byte> buffer)
		{
			return SafeRead(buffer, ref position);
		}

		public int SafeRead(Span<byte> buffer, ref long streamPosition)
		{
			CheckDisposed();
			int num = InternalRead(buffer, streamPosition);
			streamPosition += num;
			return num;
		}

		public override void Write(byte[] buffer, int offset, int count)
		{
			CheckDisposed();
			if (buffer == null)
			{
				throw new ArgumentNullException("buffer");
			}
			if (offset < 0)
			{
				throw new ArgumentOutOfRangeException("offset", offset, "offset must be in the range of 0 - buffer.Length-1.");
			}
			if (count < 0)
			{
				throw new ArgumentOutOfRangeException("count", count, "count must be non-negative.");
			}
			if (count + offset > buffer.Length)
			{
				throw new ArgumentException("count must be greater than buffer.Length - offset.");
			}
			int blockSize = memoryManager.options.BlockSize;
			long newCapacity = position + count;
			EnsureCapacity(newCapacity);
			if (largeBuffer == null)
			{
				int num = count;
				int num2 = 0;
				BlockAndOffset blockAndRelativeOffset = GetBlockAndRelativeOffset(position);
				while (num > 0)
				{
					byte[] dst = blocks[blockAndRelativeOffset.Block];
					int num3 = Math.Min(blockSize - blockAndRelativeOffset.Offset, num);
					Buffer.BlockCopy(buffer, offset + num2, dst, blockAndRelativeOffset.Offset, num3);
					num -= num3;
					num2 += num3;
					blockAndRelativeOffset.Block++;
					blockAndRelativeOffset.Offset = 0;
				}
			}
			else
			{
				Buffer.BlockCopy(buffer, offset, largeBuffer, (int)position, count);
			}
			position = newCapacity;
			length = Math.Max(position, length);
		}

		public override void Write(ReadOnlySpan<byte> source)
		{
			CheckDisposed();
			int blockSize = memoryManager.options.BlockSize;
			long newCapacity = position + source.Length;
			EnsureCapacity(newCapacity);
			if (largeBuffer == null)
			{
				BlockAndOffset blockAndRelativeOffset = GetBlockAndRelativeOffset(position);
				while (source.Length > 0)
				{
					byte[] array = blocks[blockAndRelativeOffset.Block];
					int start = Math.Min(blockSize - blockAndRelativeOffset.Offset, source.Length);
					source.Slice(0, start).CopyTo(array.AsSpan(blockAndRelativeOffset.Offset));
					source = source.Slice(start);
					blockAndRelativeOffset.Block++;
					blockAndRelativeOffset.Offset = 0;
				}
			}
			else
			{
				source.CopyTo(largeBuffer.AsSpan((int)position));
			}
			position = newCapacity;
			length = Math.Max(position, length);
		}

		public override string ToString()
		{
			if (!disposed)
			{
				return $"Id = {Id}, Tag = {Tag}, Length = {Length:N0} bytes";
			}
			return $"Disposed: Id = {id}, Tag = {tag}, Final Length: {length:N0} bytes";
		}

		public override void WriteByte(byte value)
		{
			CheckDisposed();
			long newCapacity = position + 1;
			if (largeBuffer == null)
			{
				int blockSize = memoryManager.options.BlockSize;
				long result;
				int num = (int)Math.DivRem(position, blockSize, out result);
				if (num >= blocks.Count)
				{
					EnsureCapacity(newCapacity);
				}
				blocks[num][result] = value;
			}
			else
			{
				if (position >= largeBuffer.Length)
				{
					EnsureCapacity(newCapacity);
				}
				largeBuffer[position] = value;
			}
			position = newCapacity;
			if (position > length)
			{
				length = position;
			}
		}

		public override int ReadByte()
		{
			return SafeReadByte(ref position);
		}

		public int SafeReadByte(ref long streamPosition)
		{
			CheckDisposed();
			if (streamPosition == length)
			{
				return -1;
			}
			byte result;
			if (largeBuffer == null)
			{
				BlockAndOffset blockAndRelativeOffset = GetBlockAndRelativeOffset(streamPosition);
				result = blocks[blockAndRelativeOffset.Block][blockAndRelativeOffset.Offset];
			}
			else
			{
				result = largeBuffer[streamPosition];
			}
			streamPosition++;
			return result;
		}

		public override void SetLength(long value)
		{
			CheckDisposed();
			if (value < 0)
			{
				throw new ArgumentOutOfRangeException("value", "value must be non-negative.");
			}
			EnsureCapacity(value);
			length = value;
			if (position > value)
			{
				position = value;
			}
		}

		public override long Seek(long offset, SeekOrigin loc)
		{
			CheckDisposed();
			long num = loc switch
			{
				SeekOrigin.Begin => offset, 
				SeekOrigin.Current => offset + position, 
				SeekOrigin.End => offset + length, 
				_ => throw new ArgumentException("Invalid seek origin.", "loc"), 
			};
			if (num < 0)
			{
				throw new IOException("Seek before beginning.");
			}
			position = num;
			return position;
		}

		public override void WriteTo(Stream stream)
		{
			WriteTo(stream, 0L, length);
		}

		public void WriteTo(Stream stream, long offset, long count)
		{
			CheckDisposed();
			if (stream == null)
			{
				throw new ArgumentNullException("stream");
			}
			if (offset < 0 || offset + count > length)
			{
				throw new ArgumentOutOfRangeException("offset must not be negative and offset + count must not exceed the length of the stream.", (Exception?)null);
			}
			if (largeBuffer == null)
			{
				BlockAndOffset blockAndRelativeOffset = GetBlockAndRelativeOffset(offset);
				long num = count;
				int num2 = blockAndRelativeOffset.Block;
				int num3 = blockAndRelativeOffset.Offset;
				while (num > 0)
				{
					byte[] array = blocks[num2];
					int num4 = (int)Math.Min((long)array.Length - (long)num3, num);
					stream.Write(array, num3, num4);
					num -= num4;
					num2++;
					num3 = 0;
				}
			}
			else
			{
				stream.Write(largeBuffer, (int)offset, (int)count);
			}
		}

		public void WriteTo(byte[] buffer)
		{
			WriteTo(buffer, 0L, Length);
		}

		public void WriteTo(byte[] buffer, long offset, long count)
		{
			WriteTo(buffer, offset, count, 0);
		}

		public void WriteTo(byte[] buffer, long offset, long count, int targetOffset)
		{
			CheckDisposed();
			if (buffer == null)
			{
				throw new ArgumentNullException("buffer");
			}
			if (offset < 0 || offset + count > length)
			{
				throw new ArgumentOutOfRangeException("offset must not be negative and offset + count must not exceed the length of the stream.", (Exception?)null);
			}
			if (targetOffset < 0 || count + targetOffset > buffer.Length)
			{
				throw new ArgumentOutOfRangeException("targetOffset must not be negative and targetOffset + count must not exceed the length of the target buffer.", (Exception?)null);
			}
			if (largeBuffer == null)
			{
				BlockAndOffset blockAndRelativeOffset = GetBlockAndRelativeOffset(offset);
				long num = count;
				int num2 = blockAndRelativeOffset.Block;
				int num3 = blockAndRelativeOffset.Offset;
				int num4 = targetOffset;
				while (num > 0)
				{
					byte[] array = blocks[num2];
					int num5 = (int)Math.Min((long)array.Length - (long)num3, num);
					Buffer.BlockCopy(array, num3, buffer, num4, num5);
					num -= num5;
					num2++;
					num3 = 0;
					num4 += num5;
				}
			}
			else
			{
				AssertLengthIsSmall();
				Buffer.BlockCopy(largeBuffer, (int)offset, buffer, targetOffset, (int)count);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private void CheckDisposed()
		{
			if (Disposed)
			{
				ThrowDisposedException();
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private void ThrowDisposedException()
		{
			throw new ObjectDisposedException($"The stream with Id {id} and Tag {tag} is disposed.");
		}

		private int InternalRead(byte[] buffer, int offset, int count, long fromPosition)
		{
			if (length - fromPosition <= 0)
			{
				return 0;
			}
			int num3;
			if (largeBuffer == null)
			{
				BlockAndOffset blockAndRelativeOffset = GetBlockAndRelativeOffset(fromPosition);
				int num = 0;
				int num2 = (int)Math.Min(count, length - fromPosition);
				while (num2 > 0)
				{
					byte[] array = blocks[blockAndRelativeOffset.Block];
					num3 = Math.Min(array.Length - blockAndRelativeOffset.Offset, num2);
					Buffer.BlockCopy(array, blockAndRelativeOffset.Offset, buffer, num + offset, num3);
					num += num3;
					num2 -= num3;
					blockAndRelativeOffset.Block++;
					blockAndRelativeOffset.Offset = 0;
				}
				return num;
			}
			num3 = (int)Math.Min(count, length - fromPosition);
			Buffer.BlockCopy(largeBuffer, (int)fromPosition, buffer, offset, num3);
			return num3;
		}

		private int InternalRead(Span<byte> buffer, long fromPosition)
		{
			if (length - fromPosition <= 0)
			{
				return 0;
			}
			int num3;
			if (largeBuffer == null)
			{
				BlockAndOffset blockAndRelativeOffset = GetBlockAndRelativeOffset(fromPosition);
				int num = 0;
				int num2 = (int)Math.Min(buffer.Length, length - fromPosition);
				while (num2 > 0)
				{
					byte[] array = blocks[blockAndRelativeOffset.Block];
					num3 = Math.Min(array.Length - blockAndRelativeOffset.Offset, num2);
					array.AsSpan(blockAndRelativeOffset.Offset, num3).CopyTo(buffer.Slice(num));
					num += num3;
					num2 -= num3;
					blockAndRelativeOffset.Block++;
					blockAndRelativeOffset.Offset = 0;
				}
				return num;
			}
			num3 = (int)Math.Min(buffer.Length, length - fromPosition);
			largeBuffer.AsSpan((int)fromPosition, num3).CopyTo(buffer);
			return num3;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private BlockAndOffset GetBlockAndRelativeOffset(long offset)
		{
			int blockSize = memoryManager.options.BlockSize;
			long result;
			return new BlockAndOffset((int)Math.DivRem(offset, blockSize, out result), (int)result);
		}

		private void EnsureCapacity(long newCapacity)
		{
			if (newCapacity > memoryManager.options.MaximumStreamCapacity && memoryManager.options.MaximumStreamCapacity > 0)
			{
				memoryManager.ReportStreamOverCapacity(id, tag, newCapacity, AllocationStack);
				throw new OutOfMemoryException($"Requested capacity is too large: {newCapacity}. Limit is {memoryManager.options.MaximumStreamCapacity}.");
			}
			if (largeBuffer != null)
			{
				if (newCapacity > largeBuffer.Length)
				{
					byte[] buffer = memoryManager.GetLargeBuffer(newCapacity, id, tag);
					InternalRead(buffer, 0, (int)length, 0L);
					ReleaseLargeBuffer();
					largeBuffer = buffer;
				}
			}
			else
			{
				long num = newCapacity / memoryManager.options.BlockSize + 1;
				if (blocks.Capacity < num)
				{
					blocks.Capacity = (int)num;
				}
				while (Capacity64 < newCapacity)
				{
					blocks.Add(memoryManager.GetBlock());
				}
			}
		}

		private void ReleaseLargeBuffer()
		{
			if (memoryManager.options.AggressiveBufferReturn)
			{
				memoryManager.ReturnLargeBuffer(largeBuffer, id, tag);
			}
			else
			{
				if (dirtyBuffers == null)
				{
					dirtyBuffers = new List<byte[]>(1);
				}
				dirtyBuffers.Add(largeBuffer);
			}
			largeBuffer = null;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private void AssertLengthIsSmall()
		{
		}
	}
}

Mods/RealRadio/NAudio.Asio.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using Microsoft.Win32;
using NAudio.Wave.Asio;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("Mark Heath")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("© Mark Heath 2023")]
[assembly: AssemblyFileVersion("2.2.1.0")]
[assembly: AssemblyInformationalVersion("2.2.1")]
[assembly: AssemblyProduct("NAudio.Asio")]
[assembly: AssemblyTitle("NAudio.Asio")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/naudio/NAudio")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.2.1.0")]
[module: UnverifiableCode]
namespace NAudio.Wave
{
	public class AsioAudioAvailableEventArgs : EventArgs
	{
		public IntPtr[] InputBuffers { get; private set; }

		public IntPtr[] OutputBuffers { get; private set; }

		public bool WrittenToOutputBuffers { get; set; }

		public int SamplesPerBuffer { get; private set; }

		public AsioSampleType AsioSampleType { get; private set; }

		public AsioAudioAvailableEventArgs(IntPtr[] inputBuffers, IntPtr[] outputBuffers, int samplesPerBuffer, AsioSampleType asioSampleType)
		{
			InputBuffers = inputBuffers;
			OutputBuffers = outputBuffers;
			SamplesPerBuffer = samplesPerBuffer;
			AsioSampleType = asioSampleType;
		}

		public unsafe int GetAsInterleavedSamples(float[] samples)
		{
			int num = InputBuffers.Length;
			if (samples.Length < SamplesPerBuffer * num)
			{
				throw new ArgumentException("Buffer not big enough");
			}
			int num2 = 0;
			if (AsioSampleType == AsioSampleType.Int32LSB)
			{
				for (int i = 0; i < SamplesPerBuffer; i++)
				{
					for (int j = 0; j < num; j++)
					{
						samples[num2++] = (float)(*(int*)((byte*)(void*)InputBuffers[j] + (nint)i * (nint)4)) / 2.1474836E+09f;
					}
				}
			}
			else if (AsioSampleType == AsioSampleType.Int16LSB)
			{
				for (int k = 0; k < SamplesPerBuffer; k++)
				{
					for (int l = 0; l < num; l++)
					{
						samples[num2++] = (float)(*(short*)((byte*)(void*)InputBuffers[l] + (nint)k * (nint)2)) / 32767f;
					}
				}
			}
			else if (AsioSampleType == AsioSampleType.Int24LSB)
			{
				for (int m = 0; m < SamplesPerBuffer; m++)
				{
					for (int n = 0; n < num; n++)
					{
						byte* ptr = (byte*)(void*)InputBuffers[n] + m * 3;
						int num3 = *ptr | (ptr[1] << 8) | ((sbyte)ptr[2] << 16);
						samples[num2++] = (float)num3 / 8388608f;
					}
				}
			}
			else
			{
				if (AsioSampleType != AsioSampleType.Float32LSB)
				{
					throw new NotImplementedException($"ASIO Sample Type {AsioSampleType} not supported");
				}
				for (int num4 = 0; num4 < SamplesPerBuffer; num4++)
				{
					for (int num5 = 0; num5 < num; num5++)
					{
						samples[num2++] = *(float*)((byte*)(void*)InputBuffers[num5] + (nint)num4 * (nint)4);
					}
				}
			}
			return SamplesPerBuffer * num;
		}

		[Obsolete("Better performance if you use the overload that takes an array, and reuse the same one")]
		public float[] GetAsInterleavedSamples()
		{
			int num = InputBuffers.Length;
			float[] array = new float[SamplesPerBuffer * num];
			GetAsInterleavedSamples(array);
			return array;
		}
	}
	public class AsioOut : IWavePlayer, IDisposable
	{
		private AsioDriverExt driver;

		private IWaveProvider sourceStream;

		private PlaybackState playbackState;

		private int nbSamples;

		private byte[] waveBuffer;

		private AsioSampleConvertor.SampleConvertor convertor;

		private string driverName;

		private readonly SynchronizationContext syncContext;

		private bool isInitialized;

		public int PlaybackLatency
		{
			get
			{
				driver.Driver.GetLatencies(out var _, out var outputLatency);
				return outputLatency;
			}
		}

		public bool AutoStop { get; set; }

		public bool HasReachedEnd { get; private set; }

		public PlaybackState PlaybackState => playbackState;

		public string DriverName => driverName;

		public int NumberOfOutputChannels { get; private set; }

		public int NumberOfInputChannels { get; private set; }

		public int DriverInputChannelCount => driver.Capabilities.NbInputChannels;

		public int DriverOutputChannelCount => driver.Capabilities.NbOutputChannels;

		public int FramesPerBuffer
		{
			get
			{
				if (!isInitialized)
				{
					throw new Exception("Not initialized yet. Call this after calling Init");
				}
				return nbSamples;
			}
		}

		public int ChannelOffset { get; set; }

		public int InputChannelOffset { get; set; }

		[Obsolete("this function will be removed in a future NAudio as ASIO does not support setting the volume on the device")]
		public float Volume
		{
			get
			{
				return 1f;
			}
			set
			{
				if (value != 1f)
				{
					throw new InvalidOperationException("AsioOut does not support setting the device volume");
				}
			}
		}

		public WaveFormat OutputWaveFormat { get; private set; }

		public event EventHandler<StoppedEventArgs> PlaybackStopped;

		public event EventHandler<AsioAudioAvailableEventArgs> AudioAvailable;

		public event EventHandler DriverResetRequest;

		public AsioOut()
			: this(0)
		{
		}

		public AsioOut(string driverName)
		{
			syncContext = SynchronizationContext.Current;
			InitFromName(driverName);
		}

		public AsioOut(int driverIndex)
		{
			syncContext = SynchronizationContext.Current;
			string[] driverNames = GetDriverNames();
			if (driverNames.Length == 0)
			{
				throw new ArgumentException("There is no ASIO Driver installed on your system");
			}
			if (driverIndex < 0 || driverIndex > driverNames.Length)
			{
				throw new ArgumentException($"Invalid device number. Must be in the range [0,{driverNames.Length}]");
			}
			InitFromName(driverNames[driverIndex]);
		}

		~AsioOut()
		{
			Dispose();
		}

		public void Dispose()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (driver != null)
			{
				if ((int)playbackState != 0)
				{
					driver.Stop();
				}
				driver.ResetRequestCallback = null;
				driver.ReleaseDriver();
				driver = null;
			}
		}

		public static string[] GetDriverNames()
		{
			return AsioDriver.GetAsioDriverNames();
		}

		public static bool isSupported()
		{
			return GetDriverNames().Length != 0;
		}

		public bool IsSampleRateSupported(int sampleRate)
		{
			return driver.IsSampleRateSupported(sampleRate);
		}

		private void InitFromName(string driverName)
		{
			this.driverName = driverName;
			AsioDriver asioDriverByName = AsioDriver.GetAsioDriverByName(driverName);
			try
			{
				driver = new AsioDriverExt(asioDriverByName);
			}
			catch
			{
				ReleaseDriver(asioDriverByName);
				throw;
			}
			driver.ResetRequestCallback = OnDriverResetRequest;
			ChannelOffset = 0;
		}

		private void OnDriverResetRequest()
		{
			this.DriverResetRequest?.Invoke(this, EventArgs.Empty);
		}

		private void ReleaseDriver(AsioDriver driver)
		{
			driver.DisposeBuffers();
			driver.ReleaseComAsioDriver();
		}

		public void ShowControlPanel()
		{
			driver.ShowControlPanel();
		}

		public void Play()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if ((int)playbackState != 1)
			{
				playbackState = (PlaybackState)1;
				HasReachedEnd = false;
				driver.Start();
			}
		}

		public void Stop()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			playbackState = (PlaybackState)0;
			driver.Stop();
			HasReachedEnd = false;
			RaisePlaybackStopped(null);
		}

		public void Pause()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			playbackState = (PlaybackState)2;
			driver.Stop();
		}

		public void Init(IWaveProvider waveProvider)
		{
			InitRecordAndPlayback(waveProvider, 0, -1);
		}

		public void InitRecordAndPlayback(IWaveProvider waveProvider, int recordChannels, int recordOnlySampleRate)
		{
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Expected O, but got Unknown
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Expected O, but got Unknown
			if (isInitialized)
			{
				throw new InvalidOperationException("Already initialised this instance of AsioOut - dispose and create a new one");
			}
			isInitialized = true;
			int num = ((waveProvider != null) ? waveProvider.WaveFormat.SampleRate : recordOnlySampleRate);
			if (waveProvider != null)
			{
				sourceStream = waveProvider;
				NumberOfOutputChannels = waveProvider.WaveFormat.Channels;
				AsioSampleType type = driver.Capabilities.OutputChannelInfos[0].type;
				convertor = AsioSampleConvertor.SelectSampleConvertor(waveProvider.WaveFormat, type);
				switch (type)
				{
				case AsioSampleType.Float32LSB:
					OutputWaveFormat = WaveFormat.CreateIeeeFloatWaveFormat(waveProvider.WaveFormat.SampleRate, waveProvider.WaveFormat.Channels);
					break;
				case AsioSampleType.Int32LSB:
					OutputWaveFormat = new WaveFormat(waveProvider.WaveFormat.SampleRate, 32, waveProvider.WaveFormat.Channels);
					break;
				case AsioSampleType.Int16LSB:
					OutputWaveFormat = new WaveFormat(waveProvider.WaveFormat.SampleRate, 16, waveProvider.WaveFormat.Channels);
					break;
				case AsioSampleType.Int24LSB:
					OutputWaveFormat = new WaveFormat(waveProvider.WaveFormat.SampleRate, 24, waveProvider.WaveFormat.Channels);
					break;
				default:
					throw new NotSupportedException($"{type} not currently supported");
				}
			}
			else
			{
				NumberOfOutputChannels = 0;
			}
			if (!driver.IsSampleRateSupported(num))
			{
				throw new ArgumentException("SampleRate is not supported");
			}
			if (driver.Capabilities.SampleRate != (double)num)
			{
				driver.SetSampleRate(num);
			}
			driver.FillBufferCallback = driver_BufferUpdate;
			NumberOfInputChannels = recordChannels;
			nbSamples = driver.CreateBuffers(NumberOfOutputChannels, NumberOfInputChannels, useMaxBufferSize: false);
			driver.SetChannelOffset(ChannelOffset, InputChannelOffset);
			if (waveProvider != null)
			{
				waveBuffer = new byte[nbSamples * NumberOfOutputChannels * waveProvider.WaveFormat.BitsPerSample / 8];
			}
		}

		private unsafe void driver_BufferUpdate(IntPtr[] inputChannels, IntPtr[] outputChannels)
		{
			if (NumberOfInputChannels > 0)
			{
				EventHandler<AsioAudioAvailableEventArgs> audioAvailable = this.AudioAvailable;
				if (audioAvailable != null)
				{
					AsioAudioAvailableEventArgs asioAudioAvailableEventArgs = new AsioAudioAvailableEventArgs(inputChannels, outputChannels, nbSamples, driver.Capabilities.InputChannelInfos[0].type);
					audioAvailable(this, asioAudioAvailableEventArgs);
					if (asioAudioAvailableEventArgs.WrittenToOutputBuffers)
					{
						return;
					}
				}
			}
			if (NumberOfOutputChannels <= 0)
			{
				return;
			}
			int num = sourceStream.Read(waveBuffer, 0, waveBuffer.Length);
			if (num < waveBuffer.Length)
			{
				Array.Clear(waveBuffer, num, waveBuffer.Length - num);
			}
			fixed (byte* ptr = &waveBuffer[0])
			{
				void* value = ptr;
				convertor(new IntPtr(value), outputChannels, NumberOfOutputChannels, nbSamples);
			}
			if (num == 0)
			{
				if (AutoStop)
				{
					Stop();
				}
				HasReachedEnd = true;
			}
		}

		private void RaisePlaybackStopped(Exception e)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			EventHandler<StoppedEventArgs> handler = this.PlaybackStopped;
			if (handler == null)
			{
				return;
			}
			if (syncContext == null)
			{
				handler(this, new StoppedEventArgs(e));
				return;
			}
			syncContext.Post(delegate
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Expected O, but got Unknown
				handler(this, new StoppedEventArgs(e));
			}, null);
		}

		public string AsioInputChannelName(int channel)
		{
			if (channel <= DriverInputChannelCount)
			{
				return driver.Capabilities.InputChannelInfos[channel].name;
			}
			return "";
		}

		public string AsioOutputChannelName(int channel)
		{
			if (channel <= DriverOutputChannelCount)
			{
				return driver.Capabilities.OutputChannelInfos[channel].name;
			}
			return "";
		}
	}
}
namespace NAudio.Wave.Asio
{
	[StructLayout(LayoutKind.Sequential, Pack = 4)]
	public struct Asio64Bit
	{
		public uint hi;

		public uint lo;
	}
	[StructLayout(LayoutKind.Sequential, Pack = 4)]
	public struct AsioCallbacks
	{
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		public delegate void AsioBufferSwitchCallBack(int doubleBufferIndex, bool directProcess);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		public delegate void AsioSampleRateDidChangeCallBack(double sRate);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		public delegate int AsioAsioMessageCallBack(AsioMessageSelector selector, int value, IntPtr message, IntPtr opt);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		public delegate IntPtr AsioBufferSwitchTimeInfoCallBack(IntPtr asioTimeParam, int doubleBufferIndex, bool directProcess);

		public AsioBufferSwitchCallBack pbufferSwitch;

		public AsioSampleRateDidChangeCallBack psampleRateDidChange;

		public AsioAsioMessageCallBack pasioMessage;

		public AsioBufferSwitchTimeInfoCallBack pbufferSwitchTimeInfo;
	}
	[StructLayout(LayoutKind.Sequential, Pack = 4)]
	public struct AsioChannelInfo
	{
		public int channel;

		public bool isInput;

		public bool isActive;

		public int channelGroup;

		[MarshalAs(UnmanagedType.U4)]
		public AsioSampleType type;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
		public string name;
	}
	public class AsioDriver
	{
		[StructLayout(LayoutKind.Sequential, Pack = 2)]
		private class AsioDriverVTable
		{
			[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
			public delegate int ASIOInit(IntPtr _pUnknown, IntPtr sysHandle);

			[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
			public delegate void ASIOgetDriverName(IntPtr _pUnknown, StringBuilder name);

			[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
			public delegate int ASIOgetDriverVersion(IntPtr _pUnknown);

			[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
			public delegate void ASIOgetErrorMessage(IntPtr _pUnknown, StringBuilder errorMessage);

			[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
			public delegate AsioError ASIOstart(IntPtr _pUnknown);

			[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
			public delegate AsioError ASIOstop(IntPtr _pUnknown);

			[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
			public delegate AsioError ASIOgetChannels(IntPtr _pUnknown, out int numInputChannels, out int numOutputChannels);

			[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
			public delegate AsioError ASIOgetLatencies(IntPtr _pUnknown, out int inputLatency, out int outputLatency);

			[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
			public delegate AsioError ASIOgetBufferSize(IntPtr _pUnknown, out int minSize, out int maxSize, out int preferredSize, out int granularity);

			[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
			public delegate AsioError ASIOcanSampleRate(IntPtr _pUnknown, double sampleRate);

			[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
			public delegate AsioError ASIOgetSampleRate(IntPtr _pUnknown, out double sampleRate);

			[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
			public delegate AsioError ASIOsetSampleRate(IntPtr _pUnknown, double sampleRate);

			[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
			public delegate AsioError ASIOgetClockSources(IntPtr _pUnknown, out long clocks, int numSources);

			[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
			public delegate AsioError ASIOsetClockSource(IntPtr _pUnknown, int reference);

			[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
			public delegate AsioError ASIOgetSamplePosition(IntPtr _pUnknown, out long samplePos, ref Asio64Bit timeStamp);

			[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
			public delegate AsioError ASIOgetChannelInfo(IntPtr _pUnknown, ref AsioChannelInfo info);

			[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
			public delegate AsioError ASIOcreateBuffers(IntPtr _pUnknown, IntPtr bufferInfos, int numChannels, int bufferSize, IntPtr callbacks);

			[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
			public delegate AsioError ASIOdisposeBuffers(IntPtr _pUnknown);

			[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
			public delegate AsioError ASIOcontrolPanel(IntPtr _pUnknown);

			[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
			public delegate AsioError ASIOfuture(IntPtr _pUnknown, int selector, IntPtr opt);

			[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
			public delegate AsioError ASIOoutputReady(IntPtr _pUnknown);

			public ASIOInit init;

			public ASIOgetDriverName getDriverName;

			public ASIOgetDriverVersion getDriverVersion;

			public ASIOgetErrorMessage getErrorMessage;

			public ASIOstart start;

			public ASIOstop stop;

			public ASIOgetChannels getChannels;

			public ASIOgetLatencies getLatencies;

			public ASIOgetBufferSize getBufferSize;

			public ASIOcanSampleRate canSampleRate;

			public ASIOgetSampleRate getSampleRate;

			public ASIOsetSampleRate setSampleRate;

			public ASIOgetClockSources getClockSources;

			public ASIOsetClockSource setClockSource;

			public ASIOgetSamplePosition getSamplePosition;

			public ASIOgetChannelInfo getChannelInfo;

			public ASIOcreateBuffers createBuffers;

			public ASIOdisposeBuffers disposeBuffers;

			public ASIOcontrolPanel controlPanel;

			public ASIOfuture future;

			public ASIOoutputReady outputReady;
		}

		private IntPtr pAsioComObject;

		private IntPtr pinnedcallbacks;

		private AsioDriverVTable asioDriverVTable;

		private AsioDriver()
		{
		}

		public static string[] GetAsioDriverNames()
		{
			RegistryKey registryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\ASIO");
			string[] result = new string[0];
			if (registryKey != null)
			{
				result = registryKey.GetSubKeyNames();
				registryKey.Close();
			}
			return result;
		}

		public static AsioDriver GetAsioDriverByName(string name)
		{
			return GetAsioDriverByGuid(new Guid((Registry.LocalMachine.OpenSubKey("SOFTWARE\\ASIO\\" + name) ?? throw new ArgumentException("Driver Name " + name + " doesn't exist")).GetValue("CLSID").ToString()));
		}

		public static AsioDriver GetAsioDriverByGuid(Guid guid)
		{
			AsioDriver asioDriver = new AsioDriver();
			asioDriver.InitFromGuid(guid);
			return asioDriver;
		}

		public bool Init(IntPtr sysHandle)
		{
			return asioDriverVTable.init(pAsioComObject, sysHandle) == 1;
		}

		public string GetDriverName()
		{
			StringBuilder stringBuilder = new StringBuilder(256);
			asioDriverVTable.getDriverName(pAsioComObject, stringBuilder);
			return stringBuilder.ToString();
		}

		public int GetDriverVersion()
		{
			return asioDriverVTable.getDriverVersion(pAsioComObject);
		}

		public string GetErrorMessage()
		{
			StringBuilder stringBuilder = new StringBuilder(256);
			asioDriverVTable.getErrorMessage(pAsioComObject, stringBuilder);
			return stringBuilder.ToString();
		}

		public void Start()
		{
			HandleException(asioDriverVTable.start(pAsioComObject), "start");
		}

		public AsioError Stop()
		{
			return asioDriverVTable.stop(pAsioComObject);
		}

		public void GetChannels(out int numInputChannels, out int numOutputChannels)
		{
			HandleException(asioDriverVTable.getChannels(pAsioComObject, out numInputChannels, out numOutputChannels), "getChannels");
		}

		public AsioError GetLatencies(out int inputLatency, out int outputLatency)
		{
			return asioDriverVTable.getLatencies(pAsioComObject, out inputLatency, out outputLatency);
		}

		public void GetBufferSize(out int minSize, out int maxSize, out int preferredSize, out int granularity)
		{
			HandleException(asioDriverVTable.getBufferSize(pAsioComObject, out minSize, out maxSize, out preferredSize, out granularity), "getBufferSize");
		}

		public bool CanSampleRate(double sampleRate)
		{
			AsioError asioError = asioDriverVTable.canSampleRate(pAsioComObject, sampleRate);
			switch (asioError)
			{
			case AsioError.ASE_NoClock:
				return false;
			case AsioError.ASE_OK:
				return true;
			default:
				HandleException(asioError, "canSampleRate");
				return false;
			}
		}

		public double GetSampleRate()
		{
			HandleException(asioDriverVTable.getSampleRate(pAsioComObject, out var sampleRate), "getSampleRate");
			return sampleRate;
		}

		public void SetSampleRate(double sampleRate)
		{
			HandleException(asioDriverVTable.setSampleRate(pAsioComObject, sampleRate), "setSampleRate");
		}

		public void GetClockSources(out long clocks, int numSources)
		{
			HandleException(asioDriverVTable.getClockSources(pAsioComObject, out clocks, numSources), "getClockSources");
		}

		public void SetClockSource(int reference)
		{
			HandleException(asioDriverVTable.setClockSource(pAsioComObject, reference), "setClockSources");
		}

		public void GetSamplePosition(out long samplePos, ref Asio64Bit timeStamp)
		{
			HandleException(asioDriverVTable.getSamplePosition(pAsioComObject, out samplePos, ref timeStamp), "getSamplePosition");
		}

		public AsioChannelInfo GetChannelInfo(int channelNumber, bool trueForInputInfo)
		{
			AsioChannelInfo asioChannelInfo = default(AsioChannelInfo);
			asioChannelInfo.channel = channelNumber;
			asioChannelInfo.isInput = trueForInputInfo;
			AsioChannelInfo info = asioChannelInfo;
			HandleException(asioDriverVTable.getChannelInfo(pAsioComObject, ref info), "getChannelInfo");
			return info;
		}

		public void CreateBuffers(IntPtr bufferInfos, int numChannels, int bufferSize, ref AsioCallbacks callbacks)
		{
			pinnedcallbacks = Marshal.AllocHGlobal(Marshal.SizeOf(callbacks));
			Marshal.StructureToPtr(callbacks, pinnedcallbacks, fDeleteOld: false);
			HandleException(asioDriverVTable.createBuffers(pAsioComObject, bufferInfos, numChannels, bufferSize, pinnedcallbacks), "createBuffers");
		}

		public AsioError DisposeBuffers()
		{
			AsioError result = asioDriverVTable.disposeBuffers(pAsioComObject);
			Marshal.FreeHGlobal(pinnedcallbacks);
			return result;
		}

		public void ControlPanel()
		{
			HandleException(asioDriverVTable.controlPanel(pAsioComObject), "controlPanel");
		}

		public void Future(int selector, IntPtr opt)
		{
			HandleException(asioDriverVTable.future(pAsioComObject, selector, opt), "future");
		}

		public AsioError OutputReady()
		{
			return asioDriverVTable.outputReady(pAsioComObject);
		}

		public void ReleaseComAsioDriver()
		{
			Marshal.Release(pAsioComObject);
		}

		private void HandleException(AsioError error, string methodName)
		{
			if (error != 0 && error != AsioError.ASE_SUCCESS)
			{
				throw new AsioException("Error code [" + AsioException.getErrorName(error) + "] while calling ASIO method <" + methodName + ">, " + GetErrorMessage())
				{
					Error = error
				};
			}
		}

		private void InitFromGuid(Guid asioGuid)
		{
			int num = CoCreateInstance(ref asioGuid, IntPtr.Zero, 1u, ref asioGuid, out pAsioComObject);
			if (num != 0)
			{
				throw new COMException("Unable to instantiate ASIO. Check if STAThread is set", num);
			}
			IntPtr ptr = Marshal.ReadIntPtr(pAsioComObject);
			asioDriverVTable = new AsioDriverVTable();
			FieldInfo[] fields = typeof(AsioDriverVTable).GetFields();
			for (int i = 0; i < fields.Length; i++)
			{
				FieldInfo fieldInfo = fields[i];
				object delegateForFunctionPointer = Marshal.GetDelegateForFunctionPointer(Marshal.ReadIntPtr(ptr, (i + 3) * IntPtr.Size), fieldInfo.FieldType);
				fieldInfo.SetValue(asioDriverVTable, delegateForFunctionPointer);
			}
		}

		[DllImport("ole32.Dll")]
		private static extern int CoCreateInstance(ref Guid clsid, IntPtr inner, uint context, ref Guid uuid, out IntPtr rReturnedComObject);
	}
	public class AsioDriverCapability
	{
		public string DriverName;

		public int NbInputChannels;

		public int NbOutputChannels;

		public int InputLatency;

		public int OutputLatency;

		public int BufferMinSize;

		public int BufferMaxSize;

		public int BufferPreferredSize;

		public int BufferGranularity;

		public double SampleRate;

		public AsioChannelInfo[] InputChannelInfos;

		public AsioChannelInfo[] OutputChannelInfos;
	}
	public delegate void AsioFillBufferCallback(IntPtr[] inputChannels, IntPtr[] outputChannels);
	public class AsioDriverExt
	{
		private readonly AsioDriver driver;

		private AsioCallbacks callbacks;

		private AsioDriverCapability capability;

		private AsioBufferInfo[] bufferInfos;

		private bool isOutputReadySupported;

		private IntPtr[] currentOutputBuffers;

		private IntPtr[] currentInputBuffers;

		private int numberOfOutputChannels;

		private int numberOfInputChannels;

		private AsioFillBufferCallback fillBufferCallback;

		private int bufferSize;

		private int outputChannelOffset;

		private int inputChannelOffset;

		public Action ResetRequestCallback;

		public AsioDriver Driver => driver;

		public AsioFillBufferCallback FillBufferCallback
		{
			get
			{
				return fillBufferCallback;
			}
			set
			{
				fillBufferCallback = value;
			}
		}

		public AsioDriverCapability Capabilities => capability;

		public AsioDriverExt(AsioDriver driver)
		{
			this.driver = driver;
			if (!driver.Init(IntPtr.Zero))
			{
				throw new InvalidOperationException(driver.GetErrorMessage());
			}
			callbacks = default(AsioCallbacks);
			callbacks.pasioMessage = AsioMessageCallBack;
			callbacks.pbufferSwitch = BufferSwitchCallBack;
			callbacks.pbufferSwitchTimeInfo = BufferSwitchTimeInfoCallBack;
			callbacks.psampleRateDidChange = SampleRateDidChangeCallBack;
			BuildCapabilities();
		}

		public void SetChannelOffset(int outputChannelOffset, int inputChannelOffset)
		{
			if (outputChannelOffset + numberOfOutputChannels <= Capabilities.NbOutputChannels)
			{
				this.outputChannelOffset = outputChannelOffset;
				if (inputChannelOffset + numberOfInputChannels <= Capabilities.NbInputChannels)
				{
					this.inputChannelOffset = inputChannelOffset;
					return;
				}
				throw new ArgumentException("Invalid channel offset");
			}
			throw new ArgumentException("Invalid channel offset");
		}

		public void Start()
		{
			driver.Start();
		}

		public void Stop()
		{
			driver.Stop();
		}

		public void ShowControlPanel()
		{
			driver.ControlPanel();
		}

		public void ReleaseDriver()
		{
			try
			{
				driver.DisposeBuffers();
			}
			catch (Exception ex)
			{
				Console.Out.WriteLine(ex.ToString());
			}
			driver.ReleaseComAsioDriver();
		}

		public bool IsSampleRateSupported(double sampleRate)
		{
			return driver.CanSampleRate(sampleRate);
		}

		public void SetSampleRate(double sampleRate)
		{
			driver.SetSampleRate(sampleRate);
			BuildCapabilities();
		}

		public unsafe int CreateBuffers(int numberOfOutputChannels, int numberOfInputChannels, bool useMaxBufferSize)
		{
			if (numberOfOutputChannels < 0 || numberOfOutputChannels > capability.NbOutputChannels)
			{
				throw new ArgumentException($"Invalid number of channels {numberOfOutputChannels}, must be in the range [0,{capability.NbOutputChannels}]");
			}
			if (numberOfInputChannels < 0 || numberOfInputChannels > capability.NbInputChannels)
			{
				throw new ArgumentException("numberOfInputChannels", $"Invalid number of input channels {numberOfInputChannels}, must be in the range [0,{capability.NbInputChannels}]");
			}
			this.numberOfOutputChannels = numberOfOutputChannels;
			this.numberOfInputChannels = numberOfInputChannels;
			int num = capability.NbInputChannels + capability.NbOutputChannels;
			bufferInfos = new AsioBufferInfo[num];
			currentOutputBuffers = new IntPtr[numberOfOutputChannels];
			currentInputBuffers = new IntPtr[numberOfInputChannels];
			int num2 = 0;
			int num3 = 0;
			while (num3 < capability.NbInputChannels)
			{
				bufferInfos[num2].isInput = true;
				bufferInfos[num2].channelNum = num3;
				bufferInfos[num2].pBuffer0 = IntPtr.Zero;
				bufferInfos[num2].pBuffer1 = IntPtr.Zero;
				num3++;
				num2++;
			}
			int num4 = 0;
			while (num4 < capability.NbOutputChannels)
			{
				bufferInfos[num2].isInput = false;
				bufferInfos[num2].channelNum = num4;
				bufferInfos[num2].pBuffer0 = IntPtr.Zero;
				bufferInfos[num2].pBuffer1 = IntPtr.Zero;
				num4++;
				num2++;
			}
			if (useMaxBufferSize)
			{
				bufferSize = capability.BufferMaxSize;
			}
			else
			{
				bufferSize = capability.BufferPreferredSize;
			}
			fixed (AsioBufferInfo* value = &bufferInfos[0])
			{
				IntPtr intPtr = new IntPtr(value);
				driver.CreateBuffers(intPtr, num, bufferSize, ref callbacks);
			}
			isOutputReadySupported = driver.OutputReady() == AsioError.ASE_OK;
			return bufferSize;
		}

		private void BuildCapabilities()
		{
			capability = new AsioDriverCapability();
			capability.DriverName = driver.GetDriverName();
			driver.GetChannels(out capability.NbInputChannels, out capability.NbOutputChannels);
			capability.InputChannelInfos = new AsioChannelInfo[capability.NbInputChannels];
			capability.OutputChannelInfos = new AsioChannelInfo[capability.NbOutputChannels];
			for (int i = 0; i < capability.NbInputChannels; i++)
			{
				capability.InputChannelInfos[i] = driver.GetChannelInfo(i, trueForInputInfo: true);
			}
			for (int j = 0; j < capability.NbOutputChannels; j++)
			{
				capability.OutputChannelInfos[j] = driver.GetChannelInfo(j, trueForInputInfo: false);
			}
			capability.SampleRate = driver.GetSampleRate();
			AsioError latencies = driver.GetLatencies(out capability.InputLatency, out capability.OutputLatency);
			if (latencies != 0 && latencies != AsioError.ASE_NotPresent)
			{
				throw new AsioException("ASIOgetLatencies")
				{
					Error = latencies
				};
			}
			driver.GetBufferSize(out capability.BufferMinSize, out capability.BufferMaxSize, out capability.BufferPreferredSize, out capability.BufferGranularity);
		}

		private void BufferSwitchCallBack(int doubleBufferIndex, bool directProcess)
		{
			for (int i = 0; i < numberOfInputChannels; i++)
			{
				currentInputBuffers[i] = bufferInfos[i + inputChannelOffset].Buffer(doubleBufferIndex);
			}
			for (int j = 0; j < numberOfOutputChannels; j++)
			{
				currentOutputBuffers[j] = bufferInfos[j + outputChannelOffset + capability.NbInputChannels].Buffer(doubleBufferIndex);
			}
			fillBufferCallback?.Invoke(currentInputBuffers, currentOutputBuffers);
			if (isOutputReadySupported)
			{
				driver.OutputReady();
			}
		}

		private void SampleRateDidChangeCallBack(double sRate)
		{
			capability.SampleRate = sRate;
		}

		private int AsioMessageCallBack(AsioMessageSelector selector, int value, IntPtr message, IntPtr opt)
		{
			switch (selector)
			{
			case AsioMessageSelector.kAsioSelectorSupported:
				switch ((AsioMessageSelector)Enum.ToObject(typeof(AsioMessageSelector), value))
				{
				case AsioMessageSelector.kAsioEngineVersion:
					return 1;
				case AsioMessageSelector.kAsioResetRequest:
					ResetRequestCallback?.Invoke();
					return 0;
				case AsioMessageSelector.kAsioBufferSizeChange:
					return 0;
				case AsioMessageSelector.kAsioResyncRequest:
					return 0;
				case AsioMessageSelector.kAsioLatenciesChanged:
					return 0;
				case AsioMessageSelector.kAsioSupportsTimeInfo:
					return 0;
				case AsioMessageSelector.kAsioSupportsTimeCode:
					return 0;
				}
				break;
			case AsioMessageSelector.kAsioEngineVersion:
				return 2;
			case AsioMessageSelector.kAsioResetRequest:
				ResetRequestCallback?.Invoke();
				return 1;
			case AsioMessageSelector.kAsioBufferSizeChange:
				return 0;
			case AsioMessageSelector.kAsioResyncRequest:
				return 0;
			case AsioMessageSelector.kAsioLatenciesChanged:
				return 0;
			case AsioMessageSelector.kAsioSupportsTimeInfo:
				return 0;
			case AsioMessageSelector.kAsioSupportsTimeCode:
				return 0;
			}
			return 0;
		}

		private IntPtr BufferSwitchTimeInfoCallBack(IntPtr asioTimeParam, int doubleBufferIndex, bool directProcess)
		{
			return IntPtr.Zero;
		}
	}
	public enum AsioError
	{
		ASE_OK = 0,
		ASE_SUCCESS = 1061701536,
		ASE_NotPresent = -1000,
		ASE_HWMalfunction = -999,
		ASE_InvalidParameter = -998,
		ASE_InvalidMode = -997,
		ASE_SPNotAdvancing = -996,
		ASE_NoClock = -995,
		ASE_NoMemory = -994
	}
	public enum AsioMessageSelector
	{
		kAsioSelectorSupported = 1,
		kAsioEngineVersion,
		kAsioResetRequest,
		kAsioBufferSizeChange,
		kAsioResyncRequest,
		kAsioLatenciesChanged,
		kAsioSupportsTimeInfo,
		kAsioSupportsTimeCode,
		kAsioMMCCommand,
		kAsioSupportsInputMonitor,
		kAsioSupportsInputGain,
		kAsioSupportsInputMeter,
		kAsioSupportsOutputGain,
		kAsioSupportsOutputMeter,
		kAsioOverload
	}
	internal class AsioSampleConvertor
	{
		public delegate void SampleConvertor(IntPtr inputInterleavedBuffer, IntPtr[] asioOutputBuffers, int nbChannels, int nbSamples);

		public static SampleConvertor SelectSampleConvertor(WaveFormat waveFormat, AsioSampleType asioType)
		{
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Invalid comparison between Unknown and I4
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Invalid comparison between Unknown and I4
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Invalid comparison between Unknown and I4
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Invalid comparison between Unknown and I4
			SampleConvertor result = null;
			bool flag = waveFormat.Channels == 2;
			switch (asioType)
			{
			case AsioSampleType.Int32LSB:
				switch (waveFormat.BitsPerSample)
				{
				case 16:
					result = (flag ? new SampleConvertor(ConvertorShortToInt2Channels) : new SampleConvertor(ConvertorShortToIntGeneric));
					break;
				case 32:
					result = (((int)waveFormat.Encoding != 3) ? (flag ? new SampleConvertor(ConvertorIntToInt2Channels) : new SampleConvertor(ConvertorIntToIntGeneric)) : (flag ? new SampleConvertor(ConvertorFloatToInt2Channels) : new SampleConvertor(ConvertorFloatToIntGeneric)));
					break;
				}
				break;
			case AsioSampleType.Int16LSB:
				switch (waveFormat.BitsPerSample)
				{
				case 16:
					result = (flag ? new SampleConvertor(ConvertorShortToShort2Channels) : new SampleConvertor(ConvertorShortToShortGeneric));
					break;
				case 32:
					result = (((int)waveFormat.Encoding != 3) ? (flag ? new SampleConvertor(ConvertorIntToShort2Channels) : new SampleConvertor(ConvertorIntToShortGeneric)) : (flag ? new SampleConvertor(ConvertorFloatToShort2Channels) : new SampleConvertor(ConvertorFloatToShortGeneric)));
					break;
				}
				break;
			case AsioSampleType.Int24LSB:
				switch (waveFormat.BitsPerSample)
				{
				case 16:
					throw new ArgumentException("Not a supported conversion");
				case 32:
					if ((int)waveFormat.Encoding == 3)
					{
						result = ConverterFloatTo24LSBGeneric;
						break;
					}
					throw new ArgumentException("Not a supported conversion");
				}
				break;
			case AsioSampleType.Float32LSB:
				switch (waveFormat.BitsPerSample)
				{
				case 16:
					throw new ArgumentException("Not a supported conversion");
				case 32:
					result = (((int)waveFormat.Encoding != 3) ? new SampleConvertor(ConvertorIntToFloatGeneric) : new SampleConvertor(ConverterFloatToFloatGeneric));
					break;
				}
				break;
			default:
				throw new ArgumentException($"ASIO Buffer Type {Enum.GetName(typeof(AsioSampleType), asioType)} is not yet supported.");
			}
			return result;
		}

		public unsafe static void ConvertorShortToInt2Channels(IntPtr inputInterleavedBuffer, IntPtr[] asioOutputBuffers, int nbChannels, int nbSamples)
		{
			short* ptr = (short*)(void*)inputInterleavedBuffer;
			short* ptr2 = (short*)(void*)asioOutputBuffers[0];
			short* ptr3 = (short*)(void*)asioOutputBuffers[1];
			ptr2++;
			ptr3++;
			for (int i = 0; i < nbSamples; i++)
			{
				*ptr2 = *ptr;
				*ptr3 = ptr[1];
				ptr += 2;
				ptr2 += 2;
				ptr3 += 2;
			}
		}

		public unsafe static void ConvertorShortToIntGeneric(IntPtr inputInterleavedBuffer, IntPtr[] asioOutputBuffers, int nbChannels, int nbSamples)
		{
			short* ptr = (short*)(void*)inputInterleavedBuffer;
			short*[] array = new short*[nbChannels];
			for (int i = 0; i < nbChannels; i++)
			{
				array[i] = (short*)(void*)asioOutputBuffers[i];
				int num = i;
				short* ptr2 = array[num];
				array[num] = ptr2 + 1;
			}
			for (int j = 0; j < nbSamples; j++)
			{
				for (int k = 0; k < nbChannels; k++)
				{
					*array[k] = *(ptr++);
					short*[] array2 = array;
					int num = k;
					array2[num] += 2;
				}
			}
		}

		public unsafe static void ConvertorFloatToInt2Channels(IntPtr inputInterleavedBuffer, IntPtr[] asioOutputBuffers, int nbChannels, int nbSamples)
		{
			float* ptr = (float*)(void*)inputInterleavedBuffer;
			int* ptr2 = (int*)(void*)asioOutputBuffers[0];
			int* ptr3 = (int*)(void*)asioOutputBuffers[1];
			for (int i = 0; i < nbSamples; i++)
			{
				*(ptr2++) = clampToInt(*ptr);
				*(ptr3++) = clampToInt(ptr[1]);
				ptr += 2;
			}
		}

		public unsafe static void ConvertorFloatToIntGeneric(IntPtr inputInterleavedBuffer, IntPtr[] asioOutputBuffers, int nbChannels, int nbSamples)
		{
			float* ptr = (float*)(void*)inputInterleavedBuffer;
			int*[] array = new int*[nbChannels];
			for (int i = 0; i < nbChannels; i++)
			{
				array[i] = (int*)(void*)asioOutputBuffers[i];
			}
			for (int j = 0; j < nbSamples; j++)
			{
				for (int k = 0; k < nbChannels; k++)
				{
					int num = k;
					int* ptr2 = array[num];
					array[num] = ptr2 + 1;
					*ptr2 = clampToInt(*(ptr++));
				}
			}
		}

		public unsafe static void ConvertorIntToInt2Channels(IntPtr inputInterleavedBuffer, IntPtr[] asioOutputBuffers, int nbChannels, int nbSamples)
		{
			int* ptr = (int*)(void*)inputInterleavedBuffer;
			int* ptr2 = (int*)(void*)asioOutputBuffers[0];
			int* ptr3 = (int*)(void*)asioOutputBuffers[1];
			for (int i = 0; i < nbSamples; i++)
			{
				*(ptr2++) = *ptr;
				*(ptr3++) = ptr[1];
				ptr += 2;
			}
		}

		public unsafe static void ConvertorIntToIntGeneric(IntPtr inputInterleavedBuffer, IntPtr[] asioOutputBuffers, int nbChannels, int nbSamples)
		{
			int* ptr = (int*)(void*)inputInterleavedBuffer;
			int*[] array = new int*[nbChannels];
			for (int i = 0; i < nbChannels; i++)
			{
				array[i] = (int*)(void*)asioOutputBuffers[i];
			}
			for (int j = 0; j < nbSamples; j++)
			{
				for (int k = 0; k < nbChannels; k++)
				{
					int num = k;
					int* ptr2 = array[num];
					array[num] = ptr2 + 1;
					*ptr2 = *(ptr++);
				}
			}
		}

		public unsafe static void ConvertorIntToShort2Channels(IntPtr inputInterleavedBuffer, IntPtr[] asioOutputBuffers, int nbChannels, int nbSamples)
		{
			int* ptr = (int*)(void*)inputInterleavedBuffer;
			short* ptr2 = (short*)(void*)asioOutputBuffers[0];
			short* ptr3 = (short*)(void*)asioOutputBuffers[1];
			for (int i = 0; i < nbSamples; i++)
			{
				*(ptr2++) = (short)(*ptr / 65536);
				*(ptr3++) = (short)(ptr[1] / 65536);
				ptr += 2;
			}
		}

		public unsafe static void ConvertorIntToShortGeneric(IntPtr inputInterleavedBuffer, IntPtr[] asioOutputBuffers, int nbChannels, int nbSamples)
		{
			int* ptr = (int*)(void*)inputInterleavedBuffer;
			int*[] array = new int*[nbChannels];
			for (int i = 0; i < nbChannels; i++)
			{
				array[i] = (int*)(void*)asioOutputBuffers[i];
			}
			for (int j = 0; j < nbSamples; j++)
			{
				for (int k = 0; k < nbChannels; k++)
				{
					int num = k;
					int* ptr2 = array[num];
					array[num] = ptr2 + 1;
					*ptr2 = (short)(*(ptr++) / 65536);
				}
			}
		}

		public unsafe static void ConvertorIntToFloatGeneric(IntPtr inputInterleavedBuffer, IntPtr[] asioOutputBuffers, int nbChannels, int nbSamples)
		{
			int* ptr = (int*)(void*)inputInterleavedBuffer;
			float*[] array = new float*[nbChannels];
			for (int i = 0; i < nbChannels; i++)
			{
				array[i] = (float*)(void*)asioOutputBuffers[i];
			}
			for (int j = 0; j < nbSamples; j++)
			{
				for (int k = 0; k < nbChannels; k++)
				{
					int num = k;
					float* ptr2 = array[num];
					array[num] = ptr2 + 1;
					*ptr2 = *(ptr++) / int.MinValue;
				}
			}
		}

		public unsafe static void ConvertorShortToShort2Channels(IntPtr inputInterleavedBuffer, IntPtr[] asioOutputBuffers, int nbChannels, int nbSamples)
		{
			short* ptr = (short*)(void*)inputInterleavedBuffer;
			short* ptr2 = (short*)(void*)asioOutputBuffers[0];
			short* ptr3 = (short*)(void*)asioOutputBuffers[1];
			for (int i = 0; i < nbSamples; i++)
			{
				*(ptr2++) = *ptr;
				*(ptr3++) = ptr[1];
				ptr += 2;
			}
		}

		public unsafe static void ConvertorShortToShortGeneric(IntPtr inputInterleavedBuffer, IntPtr[] asioOutputBuffers, int nbChannels, int nbSamples)
		{
			short* ptr = (short*)(void*)inputInterleavedBuffer;
			short*[] array = new short*[nbChannels];
			for (int i = 0; i < nbChannels; i++)
			{
				array[i] = (short*)(void*)asioOutputBuffers[i];
			}
			for (int j = 0; j < nbSamples; j++)
			{
				for (int k = 0; k < nbChannels; k++)
				{
					int num = k;
					short* ptr2 = array[num];
					array[num] = ptr2 + 1;
					*ptr2 = *(ptr++);
				}
			}
		}

		public unsafe static void ConvertorFloatToShort2Channels(IntPtr inputInterleavedBuffer, IntPtr[] asioOutputBuffers, int nbChannels, int nbSamples)
		{
			float* ptr = (float*)(void*)inputInterleavedBuffer;
			short* ptr2 = (short*)(void*)asioOutputBuffers[0];
			short* ptr3 = (short*)(void*)asioOutputBuffers[1];
			for (int i = 0; i < nbSamples; i++)
			{
				*(ptr2++) = clampToShort(*ptr);
				*(ptr3++) = clampToShort(ptr[1]);
				ptr += 2;
			}
		}

		public unsafe static void ConvertorFloatToShortGeneric(IntPtr inputInterleavedBuffer, IntPtr[] asioOutputBuffers, int nbChannels, int nbSamples)
		{
			float* ptr = (float*)(void*)inputInterleavedBuffer;
			short*[] array = new short*[nbChannels];
			for (int i = 0; i < nbChannels; i++)
			{
				array[i] = (short*)(void*)asioOutputBuffers[i];
			}
			for (int j = 0; j < nbSamples; j++)
			{
				for (int k = 0; k < nbChannels; k++)
				{
					int num = k;
					short* ptr2 = array[num];
					array[num] = ptr2 + 1;
					*ptr2 = clampToShort(*(ptr++));
				}
			}
		}

		public unsafe static void ConverterFloatTo24LSBGeneric(IntPtr inputInterleavedBuffer, IntPtr[] asioOutputBuffers, int nbChannels, int nbSamples)
		{
			float* ptr = (float*)(void*)inputInterleavedBuffer;
			byte*[] array = new byte*[nbChannels];
			for (int i = 0; i < nbChannels; i++)
			{
				array[i] = (byte*)(void*)asioOutputBuffers[i];
			}
			for (int j = 0; j < nbSamples; j++)
			{
				for (int k = 0; k < nbChannels; k++)
				{
					int num = clampTo24Bit(*(ptr++));
					int num2 = k;
					*(array[num2]++) = (byte)num;
					num2 = k;
					*(array[num2]++) = (byte)(num >> 8);
					num2 = k;
					*(array[num2]++) = (byte)(num >> 16);
				}
			}
		}

		public unsafe static void ConverterFloatToFloatGeneric(IntPtr inputInterleavedBuffer, IntPtr[] asioOutputBuffers, int nbChannels, int nbSamples)
		{
			float* ptr = (float*)(void*)inputInterleavedBuffer;
			float*[] array = new float*[nbChannels];
			for (int i = 0; i < nbChannels; i++)
			{
				array[i] = (float*)(void*)asioOutputBuffers[i];
			}
			for (int j = 0; j < nbSamples; j++)
			{
				for (int k = 0; k < nbChannels; k++)
				{
					int num = k;
					float* ptr2 = array[num];
					array[num] = ptr2 + 1;
					*ptr2 = *(ptr++);
				}
			}
		}

		private static int clampTo24Bit(double sampleValue)
		{
			sampleValue = ((sampleValue < -1.0) ? (-1.0) : ((sampleValue > 1.0) ? 1.0 : sampleValue));
			return (int)(sampleValue * 8388607.0);
		}

		private static int clampToInt(double sampleValue)
		{
			sampleValue = ((sampleValue < -1.0) ? (-1.0) : ((sampleValue > 1.0) ? 1.0 : sampleValue));
			return (int)(sampleValue * 2147483647.0);
		}

		private static short clampToShort(double sampleValue)
		{
			sampleValue = ((sampleValue < -1.0) ? (-1.0) : ((sampleValue > 1.0) ? 1.0 : sampleValue));
			return (short)(sampleValue * 32767.0);
		}
	}
	public enum AsioSampleType
	{
		Int16MSB = 0,
		Int24MSB = 1,
		Int32MSB = 2,
		Float32MSB = 3,
		Float64MSB = 4,
		Int32MSB16 = 8,
		Int32MSB18 = 9,
		Int32MSB20 = 10,
		Int32MSB24 = 11,
		Int16LSB = 16,
		Int24LSB = 17,
		Int32LSB = 18,
		Float32LSB = 19,
		Float64LSB = 20,
		Int32LSB16 = 24,
		Int32LSB18 = 25,
		Int32LSB20 = 26,
		Int32LSB24 = 27,
		DSDInt8LSB1 = 32,
		DSDInt8MSB1 = 33,
		DSDInt8NER8 = 40
	}
	internal class AsioException : Exception
	{
		private AsioError error;

		public AsioError Error
		{
			get
			{
				return error;
			}
			set
			{
				error = value;
				Data["ASIOError"] = error;
			}
		}

		public AsioException()
		{
		}

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

		public AsioException(string message, Exception innerException)
			: base(message, innerException)
		{
		}

		public static string getErrorName(AsioError error)
		{
			return Enum.GetName(typeof(AsioError), error);
		}
	}
	[StructLayout(LayoutKind.Sequential, Pack = 4)]
	internal struct AsioBufferInfo
	{
		public bool isInput;

		public int channelNum;

		public IntPtr pBuffer0;

		public IntPtr pBuffer1;

		public IntPtr Buffer(int bufferIndex)
		{
			if (bufferIndex != 0)
			{
				return pBuffer1;
			}
			return pBuffer0;
		}
	}
	[StructLayout(LayoutKind.Sequential, Pack = 4)]
	internal struct AsioTimeCode
	{
		public double speed;

		public Asio64Bit timeCodeSamples;

		public AsioTimeCodeFlags flags;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
		public string future;
	}
	[Flags]
	internal enum AsioTimeCodeFlags
	{
		kTcValid = 1,
		kTcRunning = 2,
		kTcReverse = 4,
		kTcOnspeed = 8,
		kTcStill = 0x10,
		kTcSpeedValid = 0x100
	}
	[StructLayout(LayoutKind.Sequential, Pack = 4)]
	internal struct AsioTimeInfo
	{
		public double speed;

		public Asio64Bit systemTime;

		public Asio64Bit samplePosition;

		public double sampleRate;

		public AsioTimeInfoFlags flags;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)]
		public string reserved;
	}
	[Flags]
	internal enum AsioTimeInfoFlags
	{
		kSystemTimeValid = 1,
		kSamplePositionValid = 2,
		kSampleRateValid = 4,
		kSpeedValid = 8,
		kSampleRateChanged = 0x10,
		kClockSourceChanged = 0x20
	}
	[StructLayout(LayoutKind.Sequential, Pack = 4)]
	internal struct AsioTime
	{
		public int reserved1;

		public int reserved2;

		public int reserved3;

		public int reserved4;

		public AsioTimeInfo timeInfo;

		public AsioTimeCode timeCode;
	}
}

Mods/RealRadio/NAudio.Core.dll

Decompiled a day 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.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using NAudio.Dmo;
using NAudio.Dsp;
using NAudio.FileFormats.Wav;
using NAudio.Utils;
using NAudio.Wave;
using NAudio.Wave.SampleProviders;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("Mark Heath")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("© Mark Heath 2023")]
[assembly: AssemblyFileVersion("2.2.1.0")]
[assembly: AssemblyInformationalVersion("2.2.1")]
[assembly: AssemblyProduct("NAudio.Core")]
[assembly: AssemblyTitle("NAudio.Core")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/naudio/NAudio")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.2.1.0")]
[module: UnverifiableCode]
namespace NAudio
{
	public enum Manufacturers
	{
		Microsoft = 1,
		Creative = 2,
		Mediavision = 3,
		Fujitsu = 4,
		Artisoft = 20,
		TurtleBeach = 21,
		Ibm = 22,
		Vocaltec = 23,
		Roland = 24,
		DspSolutions = 25,
		Nec = 26,
		Ati = 27,
		Wanglabs = 28,
		Tandy = 29,
		Voyetra = 30,
		Antex = 31,
		IclPS = 32,
		Intel = 33,
		Gravis = 34,
		Val = 35,
		Interactive = 36,
		Yamaha = 37,
		Everex = 38,
		Echo = 39,
		Sierra = 40,
		Cat = 41,
		Apps = 42,
		DspGroup = 43,
		Melabs = 44,
		ComputerFriends = 45,
		Ess = 46,
		Audiofile = 47,
		Motorola = 48,
		Canopus = 49,
		Epson = 50,
		Truevision = 51,
		Aztech = 52,
		Videologic = 53,
		Scalacs = 54,
		Korg = 55,
		Apt = 56,
		Ics = 57,
		Iteratedsys = 58,
		Metheus = 59,
		Logitech = 60,
		Winnov = 61,
		Ncr = 62,
		Exan = 63,
		Ast = 64,
		Willowpond = 65,
		Sonicfoundry = 66,
		Vitec = 67,
		Moscom = 68,
		Siliconsoft = 69,
		Supermac = 73,
		Audiopt = 74,
		Speechcomp = 76,
		Ahead = 77,
		Dolby = 78,
		Oki = 79,
		Auravision = 80,
		Olivetti = 81,
		Iomagic = 82,
		Matsushita = 83,
		Controlres = 84,
		Xebec = 85,
		Newmedia = 86,
		Nms = 87,
		Lyrrus = 88,
		Compusic = 89,
		Opti = 90,
		Adlacc = 91,
		Compaq = 92,
		Dialogic = 93,
		Insoft = 94,
		Mptus = 95,
		Weitek = 96,
		LernoutAndHauspie = 97,
		Qciar = 98,
		Apple = 99,
		Digital = 100,
		Motu = 101,
		Workbit = 102,
		Ositech = 103,
		Miro = 104,
		Cirruslogic = 105,
		Isolution = 106,
		Horizons = 107,
		Concepts = 108,
		Vtg = 109,
		Radius = 110,
		Rockwell = 111,
		Xyz = 112,
		Opcode = 113,
		Voxware = 114,
		NorthernTelecom = 115,
		Apicom = 116,
		Grande = 117,
		Addx = 118,
		Wildcat = 119,
		Rhetorex = 120,
		Brooktree = 121,
		Ensoniq = 125,
		Fast = 126,
		Nvidia = 127,
		Oksori = 128,
		Diacoustics = 129,
		Gulbransen = 130,
		KayElemetrics = 131,
		Crystal = 132,
		SplashStudios = 133,
		Quarterdeck = 134,
		Tdk = 135,
		DigitalAudioLabs = 136,
		Seersys = 137,
		Picturetel = 138,
		AttMicroelectronics = 139,
		Osprey = 140,
		Mediatrix = 141,
		Soundesigns = 142,
		Aldigital = 143,
		SpectrumSignalProcessing = 144,
		Ecs = 145,
		Amd = 146,
		Coredynamics = 147,
		Canam = 148,
		Softsound = 149,
		Norris = 150,
		Ddd = 151,
		Euphonics = 152,
		Precept = 153,
		CrystalNet = 154,
		Chromatic = 155,
		Voiceinfo = 156,
		Viennasys = 157,
		Connectix = 158,
		Gadgetlabs = 159,
		Frontier = 160,
		Viona = 161,
		Casio = 162,
		Diamondmm = 163,
		S3 = 164,
		FraunhoferIis = 172
	}
	public class MmException : Exception
	{
		public MmResult Result { get; }

		public string Function { get; }

		public MmException(MmResult result, string function)
			: base(ErrorMessage(result, function))
		{
			Result = result;
			Function = function;
		}

		private static string ErrorMessage(MmResult result, string function)
		{
			return $"{result} calling {function}";
		}

		public static void Try(MmResult result, string function)
		{
			if (result != 0)
			{
				throw new MmException(result, function);
			}
		}
	}
	public enum MmResult
	{
		NoError = 0,
		UnspecifiedError = 1,
		BadDeviceId = 2,
		NotEnabled = 3,
		AlreadyAllocated = 4,
		InvalidHandle = 5,
		NoDriver = 6,
		MemoryAllocationError = 7,
		NotSupported = 8,
		BadErrorNumber = 9,
		InvalidFlag = 10,
		InvalidParameter = 11,
		HandleBusy = 12,
		InvalidAlias = 13,
		BadRegistryDatabase = 14,
		RegistryKeyNotFound = 15,
		RegistryReadError = 16,
		RegistryWriteError = 17,
		RegistryDeleteError = 18,
		RegistryValueNotFound = 19,
		NoDriverCallback = 20,
		MoreData = 21,
		WaveBadFormat = 32,
		WaveStillPlaying = 33,
		WaveHeaderUnprepared = 34,
		WaveSync = 35,
		AcmNotPossible = 512,
		AcmBusy = 513,
		AcmHeaderUnprepared = 514,
		AcmCancelled = 515,
		MixerInvalidLine = 1024,
		MixerInvalidControl = 1025,
		MixerInvalidValue = 1026
	}
}
namespace NAudio.CoreAudioApi
{
	public enum CaptureState
	{
		Stopped,
		Starting,
		Capturing,
		Stopping
	}
}
namespace NAudio.Dmo
{
	public class AudioMediaSubtypes
	{
		public static readonly Guid MEDIASUBTYPE_PCM = new Guid("00000001-0000-0010-8000-00AA00389B71");

		public static readonly Guid MEDIASUBTYPE_PCMAudioObsolete = new Guid("e436eb8a-524f-11ce-9f53-0020af0ba770");

		public static readonly Guid MEDIASUBTYPE_MPEG1Packet = new Guid("e436eb80-524f-11ce-9f53-0020af0ba770");

		public static readonly Guid MEDIASUBTYPE_MPEG1Payload = new Guid("e436eb81-524f-11ce-9f53-0020af0ba770");

		public static readonly Guid MEDIASUBTYPE_MPEG2_AUDIO = new Guid("e06d802b-db46-11cf-b4d1-00805f6cbbea");

		public static readonly Guid MEDIASUBTYPE_DVD_LPCM_AUDIO = new Guid("e06d8032-db46-11cf-b4d1-00805f6cbbea");

		public static readonly Guid MEDIASUBTYPE_DRM_Audio = new Guid("00000009-0000-0010-8000-00aa00389b71");

		public static readonly Guid MEDIASUBTYPE_IEEE_FLOAT = new Guid("00000003-0000-0010-8000-00aa00389b71");

		public static readonly Guid MEDIASUBTYPE_DOLBY_AC3 = new Guid("e06d802c-db46-11cf-b4d1-00805f6cbbea");

		public static readonly Guid MEDIASUBTYPE_DOLBY_AC3_SPDIF = new Guid("00000092-0000-0010-8000-00aa00389b71");

		public static readonly Guid MEDIASUBTYPE_RAW_SPORT = new Guid("00000240-0000-0010-8000-00aa00389b71");

		public static readonly Guid MEDIASUBTYPE_SPDIF_TAG_241h = new Guid("00000241-0000-0010-8000-00aa00389b71");

		public static readonly Guid MEDIASUBTYPE_I420 = new Guid("30323449-0000-0010-8000-00AA00389B71");

		public static readonly Guid MEDIASUBTYPE_IYUV = new Guid("56555949-0000-0010-8000-00AA00389B71");

		public static readonly Guid MEDIASUBTYPE_RGB1 = new Guid("e436eb78-524f-11ce-9f53-0020af0ba770");

		public static readonly Guid MEDIASUBTYPE_RGB24 = new Guid("e436eb7d-524f-11ce-9f53-0020af0ba770");

		public static readonly Guid MEDIASUBTYPE_RGB32 = new Guid("e436eb7e-524f-11ce-9f53-0020af0ba770");

		public static readonly Guid MEDIASUBTYPE_RGB4 = new Guid("e436eb79-524f-11ce-9f53-0020af0ba770");

		public static readonly Guid MEDIASUBTYPE_RGB555 = new Guid("e436eb7c-524f-11ce-9f53-0020af0ba770");

		public static readonly Guid MEDIASUBTYPE_RGB565 = new Guid("e436eb7b-524f-11ce-9f53-0020af0ba770");

		public static readonly Guid MEDIASUBTYPE_RGB8 = new Guid("e436eb7a-524f-11ce-9f53-0020af0ba770");

		public static readonly Guid MEDIASUBTYPE_UYVY = new Guid("59565955-0000-0010-8000-00AA00389B71");

		public static readonly Guid MEDIASUBTYPE_VIDEOIMAGE = new Guid("1d4a45f2-e5f6-4b44-8388-f0ae5c0e0c37");

		public static readonly Guid MEDIASUBTYPE_YUY2 = new Guid("32595559-0000-0010-8000-00AA00389B71");

		public static readonly Guid MEDIASUBTYPE_YV12 = new Guid("31313259-0000-0010-8000-00AA00389B71");

		public static readonly Guid MEDIASUBTYPE_YVU9 = new Guid("39555659-0000-0010-8000-00AA00389B71");

		public static readonly Guid MEDIASUBTYPE_YVYU = new Guid("55595659-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMFORMAT_MPEG2Video = new Guid("e06d80e3-db46-11cf-b4d1-00805f6cbbea");

		public static readonly Guid WMFORMAT_Script = new Guid("5C8510F2-DEBE-4ca7-BBA5-F07A104F8DFF");

		public static readonly Guid WMFORMAT_VideoInfo = new Guid("05589f80-c356-11ce-bf01-00aa0055595a");

		public static readonly Guid WMFORMAT_WaveFormatEx = new Guid("05589f81-c356-11ce-bf01-00aa0055595a");

		public static readonly Guid WMFORMAT_WebStream = new Guid("da1e6b13-8359-4050-b398-388e965bf00c");

		public static readonly Guid WMMEDIASUBTYPE_ACELPnet = new Guid("00000130-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_Base = new Guid("00000000-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_DRM = new Guid("00000009-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_MP3 = new Guid("00000055-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_MP43 = new Guid("3334504D-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_MP4S = new Guid("5334504D-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_M4S2 = new Guid("3253344D-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_P422 = new Guid("32323450-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_MPEG2_VIDEO = new Guid("e06d8026-db46-11cf-b4d1-00805f6cbbea");

		public static readonly Guid WMMEDIASUBTYPE_MSS1 = new Guid("3153534D-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_MSS2 = new Guid("3253534D-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_PCM = new Guid("00000001-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_WebStream = new Guid("776257d4-c627-41cb-8f81-7ac7ff1c40cc");

		public static readonly Guid WMMEDIASUBTYPE_WMAudio_Lossless = new Guid("00000163-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_WMAudioV2 = new Guid("00000161-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_WMAudioV7 = new Guid("00000161-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_WMAudioV8 = new Guid("00000161-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_WMAudioV9 = new Guid("00000162-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_WMSP1 = new Guid("0000000A-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_WMV1 = new Guid("31564D57-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_WMV2 = new Guid("32564D57-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_WMV3 = new Guid("33564D57-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_WMVA = new Guid("41564D57-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_WMVP = new Guid("50564D57-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIASUBTYPE_WVP2 = new Guid("32505657-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIATYPE_Audio = new Guid("73647561-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIATYPE_FileTransfer = new Guid("D9E47579-930E-4427-ADFC-AD80F290E470");

		public static readonly Guid WMMEDIATYPE_Image = new Guid("34A50FD8-8AA5-4386-81FE-A0EFE0488E31");

		public static readonly Guid WMMEDIATYPE_Script = new Guid("73636d64-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMMEDIATYPE_Text = new Guid("9BBA1EA7-5AB2-4829-BA57-0940209BCF3E");

		public static readonly Guid WMMEDIATYPE_Video = new Guid("73646976-0000-0010-8000-00AA00389B71");

		public static readonly Guid WMSCRIPTTYPE_TwoStrings = new Guid("82f38a70-c29f-11d1-97ad-00a0c95ea850");

		public static readonly Guid MEDIASUBTYPE_WAVE = new Guid("e436eb8b-524f-11ce-9f53-0020af0ba770");

		public static readonly Guid MEDIASUBTYPE_AU = new Guid("e436eb8c-524f-11ce-9f53-0020af0ba770");

		public static readonly Guid MEDIASUBTYPE_AIFF = new Guid("e436eb8d-524f-11ce-9f53-0020af0ba770");

		public static readonly Guid[] AudioSubTypes = new Guid[13]
		{
			MEDIASUBTYPE_PCM, MEDIASUBTYPE_PCMAudioObsolete, MEDIASUBTYPE_MPEG1Packet, MEDIASUBTYPE_MPEG1Payload, MEDIASUBTYPE_MPEG2_AUDIO, MEDIASUBTYPE_DVD_LPCM_AUDIO, MEDIASUBTYPE_DRM_Audio, MEDIASUBTYPE_IEEE_FLOAT, MEDIASUBTYPE_DOLBY_AC3, MEDIASUBTYPE_DOLBY_AC3_SPDIF,
			MEDIASUBTYPE_RAW_SPORT, MEDIASUBTYPE_SPDIF_TAG_241h, WMMEDIASUBTYPE_MP3
		};

		public static readonly string[] AudioSubTypeNames = new string[13]
		{
			"PCM", "PCM Obsolete", "MPEG1Packet", "MPEG1Payload", "MPEG2_AUDIO", "DVD_LPCM_AUDIO", "DRM_Audio", "IEEE_FLOAT", "DOLBY_AC3", "DOLBY_AC3_SPDIF",
			"RAW_SPORT", "SPDIF_TAG_241h", "MP3"
		};

		public static string GetAudioSubtypeName(Guid subType)
		{
			for (int i = 0; i < AudioSubTypes.Length; i++)
			{
				if (subType == AudioSubTypes[i])
				{
					return AudioSubTypeNames[i];
				}
			}
			return subType.ToString();
		}
	}
}
namespace NAudio.Utils
{
	public static class BufferHelpers
	{
		public static byte[] Ensure(byte[] buffer, int bytesRequired)
		{
			if (buffer == null || buffer.Length < bytesRequired)
			{
				buffer = new byte[bytesRequired];
			}
			return buffer;
		}

		public static float[] Ensure(float[] buffer, int samplesRequired)
		{
			if (buffer == null || buffer.Length < samplesRequired)
			{
				buffer = new float[samplesRequired];
			}
			return buffer;
		}
	}
	public static class ByteArrayExtensions
	{
		public static bool IsEntirelyNull(byte[] buffer)
		{
			for (int i = 0; i < buffer.Length; i++)
			{
				if (buffer[i] != 0)
				{
					return false;
				}
			}
			return true;
		}

		public static string DescribeAsHex(byte[] buffer, string separator, int bytesPerLine)
		{
			StringBuilder stringBuilder = new StringBuilder();
			int num = 0;
			foreach (byte b in buffer)
			{
				stringBuilder.AppendFormat("{0:X2}{1}", b, separator);
				if (++num % bytesPerLine == 0)
				{
					stringBuilder.Append("\r\n");
				}
			}
			stringBuilder.Append("\r\n");
			return stringBuilder.ToString();
		}

		public static string DecodeAsString(byte[] buffer, int offset, int length, Encoding encoding)
		{
			for (int i = 0; i < length; i++)
			{
				if (buffer[offset + i] == 0)
				{
					length = i;
				}
			}
			return encoding.GetString(buffer, offset, length);
		}

		public static byte[] Concat(params byte[][] byteArrays)
		{
			int num = 0;
			byte[][] array = byteArrays;
			foreach (byte[] array2 in array)
			{
				num += array2.Length;
			}
			if (num <= 0)
			{
				return new byte[0];
			}
			byte[] array3 = new byte[num];
			int num2 = 0;
			array = byteArrays;
			foreach (byte[] array4 in array)
			{
				Array.Copy(array4, 0, array3, num2, array4.Length);
				num2 += array4.Length;
			}
			return array3;
		}
	}
	public class ByteEncoding : Encoding
	{
		public static readonly ByteEncoding Instance = new ByteEncoding();

		private ByteEncoding()
		{
		}

		public override int GetByteCount(char[] chars, int index, int count)
		{
			return count;
		}

		public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
		{
			for (int i = 0; i < charCount; i++)
			{
				bytes[byteIndex + i] = (byte)chars[charIndex + i];
			}
			return charCount;
		}

		public override int GetCharCount(byte[] bytes, int index, int count)
		{
			for (int i = 0; i < count; i++)
			{
				if (bytes[index + i] == 0)
				{
					return i;
				}
			}
			return count;
		}

		public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
		{
			for (int i = 0; i < byteCount; i++)
			{
				byte b = bytes[byteIndex + i];
				if (b == 0)
				{
					return i;
				}
				chars[charIndex + i] = (char)b;
			}
			return byteCount;
		}

		public override int GetMaxCharCount(int byteCount)
		{
			return byteCount;
		}

		public override int GetMaxByteCount(int charCount)
		{
			return charCount;
		}
	}
	public class ChunkIdentifier
	{
		public static int ChunkIdentifierToInt32(string s)
		{
			if (s.Length != 4)
			{
				throw new ArgumentException("Must be a four character string");
			}
			byte[] bytes = Encoding.UTF8.GetBytes(s);
			if (bytes.Length != 4)
			{
				throw new ArgumentException("Must encode to exactly four bytes");
			}
			return BitConverter.ToInt32(bytes, 0);
		}
	}
	public class CircularBuffer
	{
		private readonly byte[] buffer;

		private readonly object lockObject;

		private int writePosition;

		private int readPosition;

		private int byteCount;

		public int MaxLength => buffer.Length;

		public int Count
		{
			get
			{
				lock (lockObject)
				{
					return byteCount;
				}
			}
		}

		public CircularBuffer(int size)
		{
			buffer = new byte[size];
			lockObject = new object();
		}

		public int Write(byte[] data, int offset, int count)
		{
			lock (lockObject)
			{
				int num = 0;
				if (count > buffer.Length - byteCount)
				{
					count = buffer.Length - byteCount;
				}
				int num2 = Math.Min(buffer.Length - writePosition, count);
				Array.Copy(data, offset, buffer, writePosition, num2);
				writePosition += num2;
				writePosition %= buffer.Length;
				num += num2;
				if (num < count)
				{
					Array.Copy(data, offset + num, buffer, writePosition, count - num);
					writePosition += count - num;
					num = count;
				}
				byteCount += num;
				return num;
			}
		}

		public int Read(byte[] data, int offset, int count)
		{
			lock (lockObject)
			{
				if (count > byteCount)
				{
					count = byteCount;
				}
				int num = 0;
				int num2 = Math.Min(buffer.Length - readPosition, count);
				Array.Copy(buffer, readPosition, data, offset, num2);
				num += num2;
				readPosition += num2;
				readPosition %= buffer.Length;
				if (num < count)
				{
					Array.Copy(buffer, readPosition, data, offset + num, count - num);
					readPosition += count - num;
					num = count;
				}
				byteCount -= num;
				return num;
			}
		}

		public void Reset()
		{
			lock (lockObject)
			{
				ResetInner();
			}
		}

		private void ResetInner()
		{
			byteCount = 0;
			readPosition = 0;
			writePosition = 0;
		}

		public void Advance(int count)
		{
			lock (lockObject)
			{
				if (count >= byteCount)
				{
					ResetInner();
					return;
				}
				byteCount -= count;
				readPosition += count;
				readPosition %= MaxLength;
			}
		}
	}
	public class Decibels
	{
		private const double LOG_2_DB = 8.685889638065037;

		private const double DB_2_LOG = 0.11512925464970228;

		public static double LinearToDecibels(double lin)
		{
			return Math.Log(lin) * 8.685889638065037;
		}

		public static double DecibelsToLinear(double dB)
		{
			return Math.Exp(dB * 0.11512925464970228);
		}
	}
	[AttributeUsage(AttributeTargets.Field)]
	public class FieldDescriptionAttribute : Attribute
	{
		public string Description { get; }

		public FieldDescriptionAttribute(string description)
		{
			Description = description;
		}

		public override string ToString()
		{
			return Description;
		}
	}
	public static class FieldDescriptionHelper
	{
		public static string Describe(Type t, Guid guid)
		{
			FieldInfo[] fields = t.GetFields(BindingFlags.Static | BindingFlags.Public);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (!fieldInfo.IsPublic || !fieldInfo.IsStatic || !(fieldInfo.FieldType == typeof(Guid)) || !((Guid)fieldInfo.GetValue(null) == guid))
				{
					continue;
				}
				object[] customAttributes = fieldInfo.GetCustomAttributes(inherit: false);
				for (int j = 0; j < customAttributes.Length; j++)
				{
					if (customAttributes[j] is FieldDescriptionAttribute fieldDescriptionAttribute)
					{
						return fieldDescriptionAttribute.Description;
					}
				}
				return fieldInfo.Name;
			}
			return guid.ToString();
		}
	}
	public static class HResult
	{
		public const int S_OK = 0;

		public const int S_FALSE = 1;

		public const int E_INVALIDARG = -2147483645;

		private const int FACILITY_AAF = 18;

		private const int FACILITY_ACS = 20;

		private const int FACILITY_BACKGROUNDCOPY = 32;

		private const int FACILITY_CERT = 11;

		private const int FACILITY_COMPLUS = 17;

		private const int FACILITY_CONFIGURATION = 33;

		private const int FACILITY_CONTROL = 10;

		private const int FACILITY_DISPATCH = 2;

		private const int FACILITY_DPLAY = 21;

		private const int FACILITY_HTTP = 25;

		private const int FACILITY_INTERNET = 12;

		private const int FACILITY_ITF = 4;

		private const int FACILITY_MEDIASERVER = 13;

		private const int FACILITY_MSMQ = 14;

		private const int FACILITY_NULL = 0;

		private const int FACILITY_RPC = 1;

		private const int FACILITY_SCARD = 16;

		private const int FACILITY_SECURITY = 9;

		private const int FACILITY_SETUPAPI = 15;

		private const int FACILITY_SSPI = 9;

		private const int FACILITY_STORAGE = 3;

		private const int FACILITY_SXS = 23;

		private const int FACILITY_UMI = 22;

		private const int FACILITY_URT = 19;

		private const int FACILITY_WIN32 = 7;

		private const int FACILITY_WINDOWS = 8;

		private const int FACILITY_WINDOWS_CE = 24;

		public static int MAKE_HRESULT(int sev, int fac, int code)
		{
			return (sev << 31) | (fac << 16) | code;
		}

		public static int GetHResult(this COMException exception)
		{
			return exception.ErrorCode;
		}
	}
	public static class IEEE
	{
		private static double UnsignedToFloat(ulong u)
		{
			return (double)(long)(u - int.MaxValue - 1) + 2147483648.0;
		}

		private static double ldexp(double x, int exp)
		{
			return x * Math.Pow(2.0, exp);
		}

		private static double frexp(double x, out int exp)
		{
			exp = (int)Math.Floor(Math.Log(x) / Math.Log(2.0)) + 1;
			return 1.0 - (Math.Pow(2.0, exp) - x) / Math.Pow(2.0, exp);
		}

		private static ulong FloatToUnsigned(double f)
		{
			return (ulong)((long)(f - 2147483648.0) + int.MaxValue + 1);
		}

		public static byte[] ConvertToIeeeExtended(double num)
		{
			int num2;
			if (num < 0.0)
			{
				num2 = 32768;
				num *= -1.0;
			}
			else
			{
				num2 = 0;
			}
			ulong num4;
			ulong num5;
			int num3;
			if (num == 0.0)
			{
				num3 = 0;
				num4 = 0uL;
				num5 = 0uL;
			}
			else
			{
				double num6 = frexp(num, out num3);
				if (num3 > 16384 || !(num6 < 1.0))
				{
					num3 = num2 | 0x7FFF;
					num4 = 0uL;
					num5 = 0uL;
				}
				else
				{
					num3 += 16382;
					if (num3 < 0)
					{
						num6 = ldexp(num6, num3);
						num3 = 0;
					}
					num3 |= num2;
					num6 = ldexp(num6, 32);
					double num7 = Math.Floor(num6);
					num4 = FloatToUnsigned(num7);
					num6 = ldexp(num6 - num7, 32);
					num7 = Math.Floor(num6);
					num5 = FloatToUnsigned(num7);
				}
			}
			return new byte[10]
			{
				(byte)(num3 >> 8),
				(byte)num3,
				(byte)(num4 >> 24),
				(byte)(num4 >> 16),
				(byte)(num4 >> 8),
				(byte)num4,
				(byte)(num5 >> 24),
				(byte)(num5 >> 16),
				(byte)(num5 >> 8),
				(byte)num5
			};
		}

		public static double ConvertFromIeeeExtended(byte[] bytes)
		{
			if (bytes.Length != 10)
			{
				throw new Exception("Incorrect length for IEEE extended.");
			}
			int num = ((bytes[0] & 0x7F) << 8) | bytes[1];
			uint num2 = (uint)((bytes[2] << 24) | (bytes[3] << 16) | (bytes[4] << 8) | bytes[5]);
			uint num3 = (uint)((bytes[6] << 24) | (bytes[7] << 16) | (bytes[8] << 8) | bytes[9]);
			double num4;
			if (num == 0 && num2 == 0 && num3 == 0)
			{
				num4 = 0.0;
			}
			else if (num == 32767)
			{
				num4 = double.NaN;
			}
			else
			{
				num -= 16383;
				num4 = ldexp(UnsignedToFloat(num2), num -= 31);
				num4 += ldexp(UnsignedToFloat(num3), num -= 32);
			}
			if ((bytes[0] & 0x80) == 128)
			{
				return 0.0 - num4;
			}
			return num4;
		}
	}
	public class IgnoreDisposeStream : Stream
	{
		public Stream SourceStream { get; private set; }

		public bool IgnoreDispose { get; set; }

		public override bool CanRead => SourceStream.CanRead;

		public override bool CanSeek => SourceStream.CanSeek;

		public override bool CanWrite => SourceStream.CanWrite;

		public override long Length => SourceStream.Length;

		public override long Position
		{
			get
			{
				return SourceStream.Position;
			}
			set
			{
				SourceStream.Position = value;
			}
		}

		public IgnoreDisposeStream(Stream sourceStream)
		{
			SourceStream = sourceStream;
			IgnoreDispose = true;
		}

		public override void Flush()
		{
			SourceStream.Flush();
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			return SourceStream.Read(buffer, offset, count);
		}

		public override long Seek(long offset, SeekOrigin origin)
		{
			return SourceStream.Seek(offset, origin);
		}

		public override void SetLength(long value)
		{
			SourceStream.SetLength(value);
		}

		public override void Write(byte[] buffer, int offset, int count)
		{
			SourceStream.Write(buffer, offset, count);
		}

		protected override void Dispose(bool disposing)
		{
			if (!IgnoreDispose)
			{
				SourceStream.Dispose();
				SourceStream = null;
			}
		}
	}
	public static class NativeMethods
	{
		[DllImport("kernel32.dll")]
		public static extern IntPtr LoadLibrary(string dllToLoad);

		[DllImport("kernel32.dll")]
		public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);

		[DllImport("kernel32.dll")]
		public static extern bool FreeLibrary(IntPtr hModule);
	}
	public static class WavePositionExtensions
	{
		public static TimeSpan GetPositionTimeSpan(this IWavePosition @this)
		{
			return TimeSpan.FromMilliseconds((double)(@this.GetPosition() / (@this.OutputWaveFormat.Channels * @this.OutputWaveFormat.BitsPerSample / 8)) * 1000.0 / (double)@this.OutputWaveFormat.SampleRate);
		}
	}
}
namespace NAudio.FileFormats.Wav
{
	public class WaveFileChunkReader
	{
		private WaveFormat waveFormat;

		private long dataChunkPosition;

		private long dataChunkLength;

		private List<RiffChunk> riffChunks;

		private readonly bool strictMode;

		private bool isRf64;

		private readonly bool storeAllChunks;

		private long riffSize;

		public WaveFormat WaveFormat => waveFormat;

		public long DataChunkPosition => dataChunkPosition;

		public long DataChunkLength => dataChunkLength;

		public List<RiffChunk> RiffChunks => riffChunks;

		public WaveFileChunkReader()
		{
			storeAllChunks = true;
			strictMode = false;
		}

		public void ReadWaveHeader(Stream stream)
		{
			dataChunkPosition = -1L;
			waveFormat = null;
			riffChunks = new List<RiffChunk>();
			dataChunkLength = 0L;
			BinaryReader binaryReader = new BinaryReader(stream);
			ReadRiffHeader(binaryReader);
			riffSize = binaryReader.ReadUInt32();
			if (binaryReader.ReadInt32() != ChunkIdentifier.ChunkIdentifierToInt32("WAVE"))
			{
				throw new FormatException("Not a WAVE file - no WAVE header");
			}
			if (isRf64)
			{
				ReadDs64Chunk(binaryReader);
			}
			int num = ChunkIdentifier.ChunkIdentifierToInt32("data");
			int num2 = ChunkIdentifier.ChunkIdentifierToInt32("fmt ");
			long num3 = Math.Min(riffSize + 8, stream.Length);
			while (stream.Position <= num3 - 8)
			{
				int num4 = binaryReader.ReadInt32();
				uint num5 = binaryReader.ReadUInt32();
				if (num4 == num)
				{
					dataChunkPosition = stream.Position;
					if (!isRf64)
					{
						dataChunkLength = num5;
					}
					stream.Position += num5;
				}
				else if (num4 == num2)
				{
					if (num5 > int.MaxValue)
					{
						throw new InvalidDataException($"Format chunk length must be between 0 and {int.MaxValue}.");
					}
					waveFormat = WaveFormat.FromFormatChunk(binaryReader, (int)num5);
				}
				else
				{
					if (num5 > stream.Length - stream.Position)
					{
						if (!strictMode)
						{
						}
						break;
					}
					if (storeAllChunks)
					{
						if (num5 > int.MaxValue)
						{
							throw new InvalidDataException($"RiffChunk chunk length must be between 0 and {int.MaxValue}.");
						}
						riffChunks.Add(GetRiffChunk(stream, num4, (int)num5));
					}
					stream.Position += num5;
				}
				if (num5 % 2 != 0 && binaryReader.PeekChar() == 0)
				{
					stream.Position++;
				}
			}
			if (waveFormat == null)
			{
				throw new FormatException("Invalid WAV file - No fmt chunk found");
			}
			if (dataChunkPosition == -1)
			{
				throw new FormatException("Invalid WAV file - No data chunk found");
			}
		}

		private void ReadDs64Chunk(BinaryReader reader)
		{
			int num = ChunkIdentifier.ChunkIdentifierToInt32("ds64");
			if (reader.ReadInt32() != num)
			{
				throw new FormatException("Invalid RF64 WAV file - No ds64 chunk found");
			}
			int num2 = reader.ReadInt32();
			riffSize = reader.ReadInt64();
			dataChunkLength = reader.ReadInt64();
			reader.ReadInt64();
			reader.ReadBytes(num2 - 24);
		}

		private static RiffChunk GetRiffChunk(Stream stream, int chunkIdentifier, int chunkLength)
		{
			return new RiffChunk(chunkIdentifier, chunkLength, stream.Position);
		}

		private void ReadRiffHeader(BinaryReader br)
		{
			int num = br.ReadInt32();
			if (num == ChunkIdentifier.ChunkIdentifierToInt32("RF64"))
			{
				isRf64 = true;
			}
			else if (num != ChunkIdentifier.ChunkIdentifierToInt32("RIFF"))
			{
				throw new FormatException("Not a WAVE file - no RIFF header");
			}
		}
	}
}
namespace NAudio.SoundFont
{
	public class Generator
	{
		public GeneratorEnum GeneratorType { get; set; }

		public ushort UInt16Amount { get; set; }

		public short Int16Amount
		{
			get
			{
				return (short)UInt16Amount;
			}
			set
			{
				UInt16Amount = (ushort)value;
			}
		}

		public byte LowByteAmount
		{
			get
			{
				return (byte)(UInt16Amount & 0xFFu);
			}
			set
			{
				UInt16Amount &= 65280;
				UInt16Amount += value;
			}
		}

		public byte HighByteAmount
		{
			get
			{
				return (byte)((UInt16Amount & 0xFF00) >> 8);
			}
			set
			{
				UInt16Amount &= 255;
				UInt16Amount += (ushort)(value << 8);
			}
		}

		public Instrument Instrument { get; set; }

		public SampleHeader SampleHeader { get; set; }

		public override string ToString()
		{
			if (GeneratorType == GeneratorEnum.Instrument)
			{
				return "Generator Instrument " + Instrument.Name;
			}
			if (GeneratorType == GeneratorEnum.SampleID)
			{
				return $"Generator SampleID {SampleHeader}";
			}
			return $"Generator {GeneratorType} {UInt16Amount}";
		}
	}
	internal class GeneratorBuilder : StructureBuilder<Generator>
	{
		public override int Length => 4;

		public Generator[] Generators => data.ToArray();

		public override Generator Read(BinaryReader br)
		{
			Generator generator = new Generator();
			generator.GeneratorType = (GeneratorEnum)br.ReadUInt16();
			generator.UInt16Amount = br.ReadUInt16();
			data.Add(generator);
			return generator;
		}

		public override void Write(BinaryWriter bw, Generator o)
		{
		}

		public void Load(Instrument[] instruments)
		{
			Generator[] generators = Generators;
			foreach (Generator generator in generators)
			{
				if (generator.GeneratorType == GeneratorEnum.Instrument)
				{
					generator.Instrument = instruments[generator.UInt16Amount];
				}
			}
		}

		public void Load(SampleHeader[] sampleHeaders)
		{
			Generator[] generators = Generators;
			foreach (Generator generator in generators)
			{
				if (generator.GeneratorType == GeneratorEnum.SampleID)
				{
					generator.SampleHeader = sampleHeaders[generator.UInt16Amount];
				}
			}
		}
	}
	public enum GeneratorEnum
	{
		StartAddressOffset,
		EndAddressOffset,
		StartLoopAddressOffset,
		EndLoopAddressOffset,
		StartAddressCoarseOffset,
		ModulationLFOToPitch,
		VibratoLFOToPitch,
		ModulationEnvelopeToPitch,
		InitialFilterCutoffFrequency,
		InitialFilterQ,
		ModulationLFOToFilterCutoffFrequency,
		ModulationEnvelopeToFilterCutoffFrequency,
		EndAddressCoarseOffset,
		ModulationLFOToVolume,
		Unused1,
		ChorusEffectsSend,
		ReverbEffectsSend,
		Pan,
		Unused2,
		Unused3,
		Unused4,
		DelayModulationLFO,
		FrequencyModulationLFO,
		DelayVibratoLFO,
		FrequencyVibratoLFO,
		DelayModulationEnvelope,
		AttackModulationEnvelope,
		HoldModulationEnvelope,
		DecayModulationEnvelope,
		SustainModulationEnvelope,
		ReleaseModulationEnvelope,
		KeyNumberToModulationEnvelopeHold,
		KeyNumberToModulationEnvelopeDecay,
		DelayVolumeEnvelope,
		AttackVolumeEnvelope,
		HoldVolumeEnvelope,
		DecayVolumeEnvelope,
		SustainVolumeEnvelope,
		ReleaseVolumeEnvelope,
		KeyNumberToVolumeEnvelopeHold,
		KeyNumberToVolumeEnvelopeDecay,
		Instrument,
		Reserved1,
		KeyRange,
		VelocityRange,
		StartLoopAddressCoarseOffset,
		KeyNumber,
		Velocity,
		InitialAttenuation,
		Reserved2,
		EndLoopAddressCoarseOffset,
		CoarseTune,
		FineTune,
		SampleID,
		SampleModes,
		Reserved3,
		ScaleTuning,
		ExclusiveClass,
		OverridingRootKey,
		Unused5,
		UnusedEnd
	}
	public class InfoChunk
	{
		public SFVersion SoundFontVersion { get; }

		public string WaveTableSoundEngine { get; set; }

		public string BankName { get; set; }

		public string DataROM { get; set; }

		public string CreationDate { get; set; }

		public string Author { get; set; }

		public string TargetProduct { get; set; }

		public string Copyright { get; set; }

		public string Comments { get; set; }

		public string Tools { get; set; }

		public SFVersion ROMVersion { get; set; }

		internal InfoChunk(RiffChunk chunk)
		{
			bool flag = false;
			bool flag2 = false;
			if (chunk.ReadChunkID() != "INFO")
			{
				throw new InvalidDataException("Not an INFO chunk");
			}
			RiffChunk nextSubChunk;
			while ((nextSubChunk = chunk.GetNextSubChunk()) != null)
			{
				switch (nextSubChunk.ChunkID)
				{
				case "ifil":
					flag = true;
					SoundFontVersion = nextSubChunk.GetDataAsStructure(new SFVersionBuilder());
					break;
				case "isng":
					WaveTableSoundEngine = nextSubChunk.GetDataAsString();
					break;
				case "INAM":
					flag2 = true;
					BankName = nextSubChunk.GetDataAsString();
					break;
				case "irom":
					DataROM = nextSubChunk.GetDataAsString();
					break;
				case "iver":
					ROMVersion = nextSubChunk.GetDataAsStructure(new SFVersionBuilder());
					break;
				case "ICRD":
					CreationDate = nextSubChunk.GetDataAsString();
					break;
				case "IENG":
					Author = nextSubChunk.GetDataAsString();
					break;
				case "IPRD":
					TargetProduct = nextSubChunk.GetDataAsString();
					break;
				case "ICOP":
					Copyright = nextSubChunk.GetDataAsString();
					break;
				case "ICMT":
					Comments = nextSubChunk.GetDataAsString();
					break;
				case "ISFT":
					Tools = nextSubChunk.GetDataAsString();
					break;
				default:
					throw new InvalidDataException("Unknown chunk type " + nextSubChunk.ChunkID);
				}
			}
			if (!flag)
			{
				throw new InvalidDataException("Missing SoundFont version information");
			}
			if (!flag2)
			{
				throw new InvalidDataException("Missing SoundFont name information");
			}
		}

		public override string ToString()
		{
			return string.Format("Bank Name: {0}\r\nAuthor: {1}\r\nCopyright: {2}\r\nCreation Date: {3}\r\nTools: {4}\r\nComments: {5}\r\nSound Engine: {6}\r\nSoundFont Version: {7}\r\nTarget Product: {8}\r\nData ROM: {9}\r\nROM Version: {10}", BankName, Author, Copyright, CreationDate, Tools, "TODO-fix comments", WaveTableSoundEngine, SoundFontVersion, TargetProduct, DataROM, ROMVersion);
		}
	}
	public class Instrument
	{
		internal ushort startInstrumentZoneIndex;

		internal ushort endInstrumentZoneIndex;

		public string Name { get; set; }

		public Zone[] Zones { get; set; }

		public override string ToString()
		{
			return Name;
		}
	}
	internal class InstrumentBuilder : StructureBuilder<Instrument>
	{
		private Instrument lastInstrument;

		public override int Length => 22;

		public Instrument[] Instruments => data.ToArray();

		public override Instrument Read(BinaryReader br)
		{
			Instrument instrument = new Instrument();
			string text = Encoding.UTF8.GetString(br.ReadBytes(20), 0, 20);
			if (text.IndexOf('\0') >= 0)
			{
				text = text.Substring(0, text.IndexOf('\0'));
			}
			instrument.Name = text;
			instrument.startInstrumentZoneIndex = br.ReadUInt16();
			if (lastInstrument != null)
			{
				lastInstrument.endInstrumentZoneIndex = (ushort)(instrument.startInstrumentZoneIndex - 1);
			}
			data.Add(instrument);
			lastInstrument = instrument;
			return instrument;
		}

		public override void Write(BinaryWriter bw, Instrument instrument)
		{
		}

		public void LoadZones(Zone[] zones)
		{
			for (int i = 0; i < data.Count - 1; i++)
			{
				Instrument instrument = data[i];
				instrument.Zones = new Zone[instrument.endInstrumentZoneIndex - instrument.startInstrumentZoneIndex + 1];
				Array.Copy(zones, instrument.startInstrumentZoneIndex, instrument.Zones, 0, instrument.Zones.Length);
			}
			data.RemoveAt(data.Count - 1);
		}
	}
	public enum TransformEnum
	{
		Linear
	}
	public class Modulator
	{
		public ModulatorType SourceModulationData { get; set; }

		public GeneratorEnum DestinationGenerator { get; set; }

		public short Amount { get; set; }

		public ModulatorType SourceModulationAmount { get; set; }

		public TransformEnum SourceTransform { get; set; }

		public override string ToString()
		{
			return $"Modulator {SourceModulationData} {DestinationGenerator} {Amount} {SourceModulationAmount} {SourceTransform}";
		}
	}
	internal class ModulatorBuilder : StructureBuilder<Modulator>
	{
		public override int Length => 10;

		public Modulator[] Modulators => data.ToArray();

		public override Modulator Read(BinaryReader br)
		{
			Modulator modulator = new Modulator();
			modulator.SourceModulationData = new ModulatorType(br.ReadUInt16());
			modulator.DestinationGenerator = (GeneratorEnum)br.ReadUInt16();
			modulator.Amount = br.ReadInt16();
			modulator.SourceModulationAmount = new ModulatorType(br.ReadUInt16());
			modulator.SourceTransform = (TransformEnum)br.ReadUInt16();
			data.Add(modulator);
			return modulator;
		}

		public override void Write(BinaryWriter bw, Modulator o)
		{
		}
	}
	public enum ControllerSourceEnum
	{
		NoController = 0,
		NoteOnVelocity = 2,
		NoteOnKeyNumber = 3,
		PolyPressure = 10,
		ChannelPressure = 13,
		PitchWheel = 14,
		PitchWheelSensitivity = 16
	}
	public enum SourceTypeEnum
	{
		Linear,
		Concave,
		Convex,
		Switch
	}
	public class ModulatorType
	{
		private bool polarity;

		private bool direction;

		private bool midiContinuousController;

		private ControllerSourceEnum controllerSource;

		private SourceTypeEnum sourceType;

		private ushort midiContinuousControllerNumber;

		internal ModulatorType(ushort raw)
		{
			polarity = (raw & 0x200) == 512;
			direction = (raw & 0x100) == 256;
			midiContinuousController = (raw & 0x80) == 128;
			sourceType = (SourceTypeEnum)((raw & 0xFC00) >> 10);
			controllerSource = (ControllerSourceEnum)(raw & 0x7F);
			midiContinuousControllerNumber = (ushort)(raw & 0x7Fu);
		}

		public override string ToString()
		{
			if (midiContinuousController)
			{
				return $"{sourceType} CC{midiContinuousControllerNumber}";
			}
			return $"{sourceType} {controllerSource}";
		}
	}
	public class Preset
	{
		internal ushort startPresetZoneIndex;

		internal ushort endPresetZoneIndex;

		internal uint library;

		internal uint genre;

		internal uint morphology;

		public string Name { get; set; }

		public ushort PatchNumber { get; set; }

		public ushort Bank { get; set; }

		public Zone[] Zones { get; set; }

		public override string ToString()
		{
			return $"{Bank}-{PatchNumber} {Name}";
		}
	}
	internal class PresetBuilder : StructureBuilder<Preset>
	{
		private Preset lastPreset;

		public override int Length => 38;

		public Preset[] Presets => data.ToArray();

		public override Preset Read(BinaryReader br)
		{
			Preset preset = new Preset();
			string text = Encoding.UTF8.GetString(br.ReadBytes(20), 0, 20);
			if (text.IndexOf('\0') >= 0)
			{
				text = text.Substring(0, text.IndexOf('\0'));
			}
			preset.Name = text;
			preset.PatchNumber = br.ReadUInt16();
			preset.Bank = br.ReadUInt16();
			preset.startPresetZoneIndex = br.ReadUInt16();
			preset.library = br.ReadUInt32();
			preset.genre = br.ReadUInt32();
			preset.morphology = br.ReadUInt32();
			if (lastPreset != null)
			{
				lastPreset.endPresetZoneIndex = (ushort)(preset.startPresetZoneIndex - 1);
			}
			data.Add(preset);
			lastPreset = preset;
			return preset;
		}

		public override void Write(BinaryWriter bw, Preset preset)
		{
		}

		public void LoadZones(Zone[] presetZones)
		{
			for (int i = 0; i < data.Count - 1; i++)
			{
				Preset preset = data[i];
				preset.Zones = new Zone[preset.endPresetZoneIndex - preset.startPresetZoneIndex + 1];
				Array.Copy(presetZones, preset.startPresetZoneIndex, preset.Zones, 0, preset.Zones.Length);
			}
			data.RemoveAt(data.Count - 1);
		}
	}
	public class PresetsChunk
	{
		private PresetBuilder presetHeaders = new PresetBuilder();

		private ZoneBuilder presetZones = new ZoneBuilder();

		private ModulatorBuilder presetZoneModulators = new ModulatorBuilder();

		private GeneratorBuilder presetZoneGenerators = new GeneratorBuilder();

		private InstrumentBuilder instruments = new InstrumentBuilder();

		private ZoneBuilder instrumentZones = new ZoneBuilder();

		private ModulatorBuilder instrumentZoneModulators = new ModulatorBuilder();

		private GeneratorBuilder instrumentZoneGenerators = new GeneratorBuilder();

		private SampleHeaderBuilder sampleHeaders = new SampleHeaderBuilder();

		public Preset[] Presets => presetHeaders.Presets;

		public Instrument[] Instruments => instruments.Instruments;

		public SampleHeader[] SampleHeaders => sampleHeaders.SampleHeaders;

		internal PresetsChunk(RiffChunk chunk)
		{
			string text = chunk.ReadChunkID();
			if (text != "pdta")
			{
				throw new InvalidDataException($"Not a presets data chunk ({text})");
			}
			RiffChunk nextSubChunk;
			while ((nextSubChunk = chunk.GetNextSubChunk()) != null)
			{
				switch (nextSubChunk.ChunkID)
				{
				case "phdr":
				case "PHDR":
					nextSubChunk.GetDataAsStructureArray(presetHeaders);
					break;
				case "pbag":
				case "PBAG":
					nextSubChunk.GetDataAsStructureArray(presetZones);
					break;
				case "pmod":
				case "PMOD":
					nextSubChunk.GetDataAsStructureArray(presetZoneModulators);
					break;
				case "pgen":
				case "PGEN":
					nextSubChunk.GetDataAsStructureArray(presetZoneGenerators);
					break;
				case "inst":
				case "INST":
					nextSubChunk.GetDataAsStructureArray(instruments);
					break;
				case "ibag":
				case "IBAG":
					nextSubChunk.GetDataAsStructureArray(instrumentZones);
					break;
				case "imod":
				case "IMOD":
					nextSubChunk.GetDataAsStructureArray(instrumentZoneModulators);
					break;
				case "igen":
				case "IGEN":
					nextSubChunk.GetDataAsStructureArray(instrumentZoneGenerators);
					break;
				case "shdr":
				case "SHDR":
					nextSubChunk.GetDataAsStructureArray(sampleHeaders);
					break;
				default:
					throw new InvalidDataException($"Unknown chunk type {nextSubChunk.ChunkID}");
				}
			}
			instrumentZoneGenerators.Load(sampleHeaders.SampleHeaders);
			instrumentZones.Load(instrumentZoneModulators.Modulators, instrumentZoneGenerators.Generators);
			instruments.LoadZones(instrumentZones.Zones);
			presetZoneGenerators.Load(instruments.Instruments);
			presetZones.Load(presetZoneModulators.Modulators, presetZoneGenerators.Generators);
			presetHeaders.LoadZones(presetZones.Zones);
			sampleHeaders.RemoveEOS();
		}

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("Preset Headers:\r\n");
			Preset[] presets = presetHeaders.Presets;
			foreach (Preset arg in presets)
			{
				stringBuilder.AppendFormat("{0}\r\n", arg);
			}
			stringBuilder.Append("Instruments:\r\n");
			Instrument[] array = instruments.Instruments;
			foreach (Instrument arg2 in array)
			{
				stringBuilder.AppendFormat("{0}\r\n", arg2);
			}
			return stringBuilder.ToString();
		}
	}
	internal class RiffChunk
	{
		private string chunkID;

		private BinaryReader riffFile;

		public string ChunkID
		{
			get
			{
				return chunkID;
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("ChunkID may not be null");
				}
				if (value.Length != 4)
				{
					throw new ArgumentException("ChunkID must be four characters");
				}
				chunkID = value;
			}
		}

		public uint ChunkSize { get; private set; }

		public long DataOffset { get; private set; }

		public static RiffChunk GetTopLevelChunk(BinaryReader file)
		{
			RiffChunk riffChunk = new RiffChunk(file);
			riffChunk.ReadChunk();
			return riffChunk;
		}

		private RiffChunk(BinaryReader file)
		{
			riffFile = file;
			chunkID = "????";
			ChunkSize = 0u;
			DataOffset = 0L;
		}

		public string ReadChunkID()
		{
			byte[] array = riffFile.ReadBytes(4);
			if (array.Length != 4)
			{
				throw new InvalidDataException("Couldn't read Chunk ID");
			}
			return ByteEncoding.Instance.GetString(array, 0, array.Length);
		}

		private void ReadChunk()
		{
			chunkID = ReadChunkID();
			ChunkSize = riffFile.ReadUInt32();
			DataOffset = riffFile.BaseStream.Position;
		}

		public RiffChunk GetNextSubChunk()
		{
			if (riffFile.BaseStream.Position + 8 < DataOffset + ChunkSize)
			{
				RiffChunk riffChunk = new RiffChunk(riffFile);
				riffChunk.ReadChunk();
				return riffChunk;
			}
			return null;
		}

		public byte[] GetData()
		{
			riffFile.BaseStream.Position = DataOffset;
			byte[] array = riffFile.ReadBytes((int)ChunkSize);
			if (array.Length != ChunkSize)
			{
				throw new InvalidDataException($"Couldn't read chunk's data Chunk: {this}, read {array.Length} bytes");
			}
			return array;
		}

		public string GetDataAsString()
		{
			byte[] data = GetData();
			if (data == null)
			{
				return null;
			}
			return ByteEncoding.Instance.GetString(data, 0, data.Length);
		}

		public T GetDataAsStructure<T>(StructureBuilder<T> s)
		{
			riffFile.BaseStream.Position = DataOffset;
			if (s.Length != ChunkSize)
			{
				throw new InvalidDataException($"Chunk size is: {ChunkSize} so can't read structure of: {s.Length}");
			}
			return s.Read(riffFile);
		}

		public T[] GetDataAsStructureArray<T>(StructureBuilder<T> s)
		{
			riffFile.BaseStream.Position = DataOffset;
			if (ChunkSize % s.Length != 0L)
			{
				throw new InvalidDataException($"Chunk size is: {ChunkSize} not a multiple of structure size: {s.Length}");
			}
			int num = (int)(ChunkSize / s.Length);
			T[] array = new T[num];
			for (int i = 0; i < num; i++)
			{
				array[i] = s.Read(riffFile);
			}
			return array;
		}

		public override string ToString()
		{
			return $"RiffChunk ID: {ChunkID} Size: {ChunkSize} Data Offset: {DataOffset}";
		}
	}
	internal class SampleDataChunk
	{
		public byte[] SampleData { get; private set; }

		public SampleDataChunk(RiffChunk chunk)
		{
			string text = chunk.ReadChunkID();
			if (text != "sdta")
			{
				throw new InvalidDataException("Not a sample data chunk (" + text + ")");
			}
			SampleData = chunk.GetData();
		}
	}
	public class SampleHeader
	{
		public string SampleName;

		public uint Start;

		public uint End;

		public uint StartLoop;

		public uint EndLoop;

		public uint SampleRate;

		public byte OriginalPitch;

		public sbyte PitchCorrection;

		public ushort SampleLink;

		public SFSampleLink SFSampleLink;

		public override string ToString()
		{
			return SampleName;
		}
	}
	internal class SampleHeaderBuilder : StructureBuilder<SampleHeader>
	{
		public override int Length => 46;

		public SampleHeader[] SampleHeaders => data.ToArray();

		public override SampleHeader Read(BinaryReader br)
		{
			SampleHeader sampleHeader = new SampleHeader();
			byte[] array = br.ReadBytes(20);
			sampleHeader.SampleName = ByteEncoding.Instance.GetString(array, 0, array.Length);
			sampleHeader.Start = br.ReadUInt32();
			sampleHeader.End = br.ReadUInt32();
			sampleHeader.StartLoop = br.ReadUInt32();
			sampleHeader.EndLoop = br.ReadUInt32();
			sampleHeader.SampleRate = br.ReadUInt32();
			sampleHeader.OriginalPitch = br.ReadByte();
			sampleHeader.PitchCorrection = br.ReadSByte();
			sampleHeader.SampleLink = br.ReadUInt16();
			sampleHeader.SFSampleLink = (SFSampleLink)br.ReadUInt16();
			data.Add(sampleHeader);
			return sampleHeader;
		}

		public override void Write(BinaryWriter bw, SampleHeader sampleHeader)
		{
		}

		internal void RemoveEOS()
		{
			data.RemoveAt(data.Count - 1);
		}
	}
	public enum SampleMode
	{
		NoLoop,
		LoopContinuously,
		ReservedNoLoop,
		LoopAndContinue
	}
	public enum SFSampleLink : ushort
	{
		MonoSample = 1,
		RightSample = 2,
		LeftSample = 4,
		LinkedSample = 8,
		RomMonoSample = 32769,
		RomRightSample = 32770,
		RomLeftSample = 32772,
		RomLinkedSample = 32776
	}
	public class SFVersion
	{
		public short Major { get; set; }

		public short Minor { get; set; }
	}
	internal class SFVersionBuilder : StructureBuilder<SFVersion>
	{
		public override int Length => 4;

		public override SFVersion Read(BinaryReader br)
		{
			SFVersion sFVersion = new SFVersion();
			sFVersion.Major = br.ReadInt16();
			sFVersion.Minor = br.ReadInt16();
			data.Add(sFVersion);
			return sFVersion;
		}

		public override void Write(BinaryWriter bw, SFVersion v)
		{
			bw.Write(v.Major);
			bw.Write(v.Minor);
		}
	}
	public class SoundFont
	{
		private InfoChunk info;

		private PresetsChunk presetsChunk;

		private SampleDataChunk sampleData;

		public InfoChunk FileInfo => info;

		public Preset[] Presets => presetsChunk.Presets;

		public Instrument[] Instruments => presetsChunk.Instruments;

		public SampleHeader[] SampleHeaders => presetsChunk.SampleHeaders;

		public byte[] SampleData => sampleData.SampleData;

		public SoundFont(string fileName)
			: this(new FileStream(fileName, FileMode.Open, FileAccess.Read))
		{
		}

		public SoundFont(Stream sfFile)
		{
			using (sfFile)
			{
				RiffChunk topLevelChunk = RiffChunk.GetTopLevelChunk(new BinaryReader(sfFile));
				if (topLevelChunk.ChunkID == "RIFF")
				{
					string text = topLevelChunk.ReadChunkID();
					if (text != "sfbk")
					{
						throw new InvalidDataException($"Not a SoundFont ({text})");
					}
					RiffChunk nextSubChunk = topLevelChunk.GetNextSubChunk();
					if (nextSubChunk.ChunkID == "LIST")
					{
						info = new InfoChunk(nextSubChunk);
						RiffChunk nextSubChunk2 = topLevelChunk.GetNextSubChunk();
						sampleData = new SampleDataChunk(nextSubChunk2);
						nextSubChunk2 = topLevelChunk.GetNextSubChunk();
						presetsChunk = new PresetsChunk(nextSubChunk2);
						return;
					}
					throw new InvalidDataException($"Not info list found ({nextSubChunk.ChunkID})");
				}
				throw new InvalidDataException("Not a RIFF file");
			}
		}

		public override string ToString()
		{
			return $"Info Chunk:\r\n{info}\r\nPresets Chunk:\r\n{presetsChunk}";
		}
	}
	internal abstract class StructureBuilder<T>
	{
		protected List<T> data;

		public abstract int Length { get; }

		public T[] Data => data.ToArray();

		public StructureBuilder()
		{
			Reset();
		}

		public abstract T Read(BinaryReader br);

		public abstract void Write(BinaryWriter bw, T o);

		public void Reset()
		{
			data = new List<T>();
		}
	}
	public class Zone
	{
		internal ushort generatorIndex;

		internal ushort modulatorIndex;

		internal ushort generatorCount;

		internal ushort modulatorCount;

		public Modulator[] Modulators { get; set; }

		public Generator[] Generators { get; set; }

		public override string ToString()
		{
			return $"Zone {generatorCount} Gens:{generatorIndex} {modulatorCount} Mods:{modulatorIndex}";
		}
	}
	internal class ZoneBuilder : StructureBuilder<Zone>
	{
		private Zone lastZone;

		public Zone[] Zones => data.ToArray();

		public override int Length => 4;

		public override Zone Read(BinaryReader br)
		{
			Zone zone = new Zone();
			zone.generatorIndex = br.ReadUInt16();
			zone.modulatorIndex = br.ReadUInt16();
			if (lastZone != null)
			{
				lastZone.generatorCount = (ushort)(zone.generatorIndex - lastZone.generatorIndex);
				lastZone.modulatorCount = (ushort)(zone.modulatorIndex - lastZone.modulatorIndex);
			}
			data.Add(zone);
			lastZone = zone;
			return zone;
		}

		public override void Write(BinaryWriter bw, Zone zone)
		{
		}

		public void Load(Modulator[] modulators, Generator[] generators)
		{
			for (int i = 0; i < data.Count - 1; i++)
			{
				Zone zone = data[i];
				zone.Generators = new Generator[zone.generatorCount];
				Array.Copy(generators, zone.generatorIndex, zone.Generators, 0, zone.generatorCount);
				zone.Modulators = new Modulator[zone.modulatorCount];
				Array.Copy(modulators, zone.modulatorIndex, zone.Modulators, 0, zone.modulatorCount);
			}
			data.RemoveAt(data.Count - 1);
		}
	}
}
namespace NAudio.Wave
{
	public enum ChannelMode
	{
		Stereo,
		JointStereo,
		DualChannel,
		Mono
	}
	public class Id3v2Tag
	{
		private long tagStartPosition;

		private long tagEndPosition;

		private byte[] rawData;

		public byte[] RawData => rawData;

		public static Id3v2Tag ReadTag(Stream input)
		{
			try
			{
				return new Id3v2Tag(input);
			}
			catch (FormatException)
			{
				return null;
			}
		}

		public static Id3v2Tag Create(IEnumerable<KeyValuePair<string, string>> tags)
		{
			return ReadTag(CreateId3v2TagStream(tags));
		}

		private static byte[] FrameSizeToBytes(int n)
		{
			byte[] bytes = BitConverter.GetBytes(n);
			Array.Reverse((Array)bytes);
			return bytes;
		}

		private static byte[] CreateId3v2Frame(string key, string value)
		{
			if (string.IsNullOrEmpty(key))
			{
				throw new ArgumentNullException("key");
			}
			if (string.IsNullOrEmpty(value))
			{
				throw new ArgumentNullException("value");
			}
			if (key.Length != 4)
			{
				throw new ArgumentOutOfRangeException("key", "key " + key + " must be 4 characters long");
			}
			byte[] array = new byte[2] { 255, 254 };
			byte[] array2 = new byte[3];
			byte[] array3 = new byte[2];
			byte[] array4 = ((!(key == "COMM")) ? ByteArrayExtensions.Concat(new byte[1] { 1 }, array, Encoding.Unicode.GetBytes(value)) : ByteArrayExtensions.Concat(new byte[1] { 1 }, array2, array3, array, Encoding.Unicode.GetBytes(value)));
			return ByteArrayExtensions.Concat(Encoding.UTF8.GetBytes(key), FrameSizeToBytes(array4.Length), new byte[2], array4);
		}

		private static byte[] GetId3TagHeaderSize(int size)
		{
			byte[] array = new byte[4];
			for (int num = array.Length - 1; num >= 0; num--)
			{
				array[num] = (byte)(size % 128);
				size /= 128;
			}
			return array;
		}

		private static byte[] CreateId3v2TagHeader(IEnumerable<byte[]> frames)
		{
			int num = 0;
			foreach (byte[] frame in frames)
			{
				num += frame.Length;
			}
			return ByteArrayExtensions.Concat(Encoding.UTF8.GetBytes("ID3"), new byte[2] { 3, 0 }, new byte[1], GetId3TagHeaderSize(num));
		}

		private static Stream CreateId3v2TagStream(IEnumerable<KeyValuePair<string, string>> tags)
		{
			List<byte[]> list = new List<byte[]>();
			foreach (KeyValuePair<string, string> tag in tags)
			{
				list.Add(CreateId3v2Frame(tag.Key, tag.Value));
			}
			byte[] array = CreateId3v2TagHeader(list);
			MemoryStream memoryStream = new MemoryStream();
			memoryStream.Write(array, 0, array.Length);
			foreach (byte[] item in list)
			{
				memoryStream.Write(item, 0, item.Length);
			}
			memoryStream.Position = 0L;
			return memoryStream;
		}

		private Id3v2Tag(Stream input)
		{
			tagStartPosition = input.Position;
			BinaryReader binaryReader = new BinaryReader(input);
			byte[] array = binaryReader.ReadBytes(10);
			if (array.Length >= 3 && array[0] == 73 && array[1] == 68 && array[2] == 51)
			{
				if ((array[5] & 0x40) == 64)
				{
					byte[] array2 = binaryReader.ReadBytes(4);
					_ = array2[0] * 2097152 + array2[1] * 16384 + array2[2] * 128;
					_ = array2[3];
				}
				int num = array[6] * 2097152;
				num += array[7] * 16384;
				num += array[8] * 128;
				num += array[9];
				binaryReader.ReadBytes(num);
				if ((array[5] & 0x10) == 16)
				{
					binaryReader.ReadBytes(10);
				}
				tagEndPosition = input.Position;
				input.Position = tagStartPosition;
				rawData = binaryReader.ReadBytes((int)(tagEndPosition - tagStartPosition));
				return;
			}
			input.Position = tagStartPosition;
			throw new FormatException("Not an ID3v2 tag");
		}
	}
	public interface IMp3FrameDecompressor : IDisposable
	{
		WaveFormat OutputFormat { get; }

		int DecompressFrame(Mp3Frame frame, byte[] dest, int destOffset);

		void Reset();
	}
	public class Mp3Frame
	{
		private static readonly int[,,] bitRates = new int[2, 3, 15]
		{
			{
				{
					0, 32, 64, 96, 128, 160, 192, 224, 256, 288,
					320, 352, 384, 416, 448
				},
				{
					0, 32, 48, 56, 64, 80, 96, 112, 128, 160,
					192, 224, 256, 320, 384
				},
				{
					0, 32, 40, 48, 56, 64, 80, 96, 112, 128,
					160, 192, 224, 256, 320
				}
			},
			{
				{
					0, 32, 48, 56, 64, 80, 96, 112, 128, 144,
					160, 176, 192, 224, 256
				},
				{
					0, 8, 16, 24, 32, 40, 48, 56, 64, 80,
					96, 112, 128, 144, 160
				},
				{
					0, 8, 16, 24, 32, 40, 48, 56, 64, 80,
					96, 112, 128, 144, 160
				}
			}
		};

		private static readonly int[,] samplesPerFrame = new int[2, 3]
		{
			{ 384, 1152, 1152 },
			{ 384, 1152, 576 }
		};

		private static readonly int[] sampleRatesVersion1 = new int[3] { 44100, 48000, 32000 };

		private static readonly int[] sampleRatesVersion2 = new int[3] { 22050, 24000, 16000 };

		private static readonly int[] sampleRatesVersion25 = new int[3] { 11025, 12000, 8000 };

		private const int MaxFrameLength = 16384;

		public int SampleRate { get; private set; }

		public int FrameLength { get; private set; }

		public int BitRate { get; private set; }

		public byte[] RawData { get; private set; }

		public MpegVersion MpegVersion { get; private set; }

		public MpegLayer MpegLayer { get; private set; }

		public ChannelMode ChannelMode { get; private set; }

		public int SampleCount { get; private set; }

		public int ChannelExtension { get; private set; }

		public int BitRateIndex { get; private set; }

		public bool Copyright { get; private set; }

		public bool CrcPresent { get; private set; }

		public long FileOffset { get; private set; }

		public static Mp3Frame LoadFromStream(Stream input)
		{
			return LoadFromStream(input, readData: true);
		}

		public static Mp3Frame LoadFromStream(Stream input, bool readData)
		{
			Mp3Frame mp3Frame = new Mp3Frame();
			mp3Frame.FileOffset = input.Position;
			byte[] array = new byte[4];
			if (input.Read(array, 0, array.Length) < array.Length)
			{
				return null;
			}
			while (!IsValidHeader(array, mp3Frame))
			{
				array[0] = array[1];
				array[1] = array[2];
				array[2] = array[3];
				if (input.Read(array, 3, 1) < 1)
				{
					return null;
				}
				mp3Frame.FileOffset++;
			}
			int num = mp3Frame.FrameLength - 4;
			if (readData)
			{
				mp3Frame.RawData = new byte[mp3Frame.FrameLength];
				Array.Copy(array, mp3Frame.RawData, 4);
				if (input.Read(mp3Frame.RawData, 4, num) < num)
				{
					throw new EndOfStreamException("Unexpected end of stream before frame complete");
				}
			}
			else
			{
				input.Position += num;
			}
			return mp3Frame;
		}

		private Mp3Frame()
		{
		}

		private static bool IsValidHeader(byte[] headerBytes, Mp3Frame frame)
		{
			if (headerBytes[0] == byte.MaxValue && (headerBytes[1] & 0xE0) == 224)
			{
				frame.MpegVersion = (MpegVersion)((headerBytes[1] & 0x18) >> 3);
				if (frame.MpegVersion == MpegVersion.Reserved)
				{
					return false;
				}
				frame.MpegLayer = (MpegLayer)((headerBytes[1] & 6) >> 1);
				if (frame.MpegLayer == MpegLayer.Reserved)
				{
					return false;
				}
				int num = ((frame.MpegLayer != MpegLayer.Layer1) ? ((frame.MpegLayer == MpegLayer.Layer2) ? 1 : 2) : 0);
				frame.CrcPresent = (headerBytes[1] & 1) == 0;
				frame.BitRateIndex = (headerBytes[2] & 0xF0) >> 4;
				if (frame.BitRateIndex == 15)
				{
					return false;
				}
				int num2 = ((frame.MpegVersion != MpegVersion.Version1) ? 1 : 0);
				frame.BitRate = bitRates[num2, num, frame.BitRateIndex] * 1000;
				if (frame.BitRate == 0)
				{
					return false;
				}
				int num3 = (headerBytes[2] & 0xC) >> 2;
				if (num3 == 3)
				{
					return false;
				}
				if (frame.MpegVersion == MpegVersion.Version1)
				{
					frame.SampleRate = sampleRatesVersion1[num3];
				}
				else if (frame.MpegVersion == MpegVersion.Version2)
				{
					frame.SampleRate = sampleRatesVersion2[num3];
				}
				else
				{
					frame.SampleRate = sampleRatesVersion25[num3];
				}
				bool flag = (headerBytes[2] & 2) == 2;
				_ = headerBytes[2];
				frame.ChannelMode = (ChannelMode)((headerBytes[3] & 0xC0) >> 6);
				frame.ChannelExtension = (headerBytes[3] & 0x30) >> 4;
				if (frame.ChannelExtension != 0 && frame.ChannelMode != ChannelMode.JointStereo)
				{
					return false;
				}
				frame.Copyright = (headerBytes[3] & 8) == 8;
				_ = headerBytes[3];
				_ = headerBytes[3];
				int num4 = (flag ? 1 : 0);
				frame.SampleCount = samplesPerFrame[num2, num];
				int num5 = frame.SampleCount / 8;
				if (frame.MpegLayer == MpegLayer.Layer1)
				{
					frame.FrameLength = (num5 * frame.BitRate / frame.SampleRate + num4) * 4;
				}
				else
				{
					frame.FrameLength = num5 * frame.BitRate / frame.SampleRate + num4;
				}
				if (frame.FrameLength > 16384)
				{
					return false;
				}
				return true;
			}
			return false;
		}
	}
	public enum MpegLayer
	{
		Reserved,
		Layer3,
		Layer2,
		Layer1
	}
	public enum MpegVersion
	{
		Version25,
		Reserved,
		Version2,
		Version1
	}
	public class XingHeader
	{
		[Flags]
		private enum XingHeaderOptions
		{
			Frames = 1,
			Bytes = 2,
			Toc = 4,
			VbrScale = 8
		}

		private static int[] sr_table = new int[4] { 44100, 48000, 32000, 99999 };

		private int vbrScale = -1;

		private int startOffset;

		private int endOffset;

		private int tocOffset = -1;

		private int framesOffset = -1;

		private int bytesOffset = -1;

		private Mp3Frame frame;

		public int Frames
		{
			get
			{
				if (framesOffset == -1)
				{
					return -1;
				}
				return ReadBigEndian(frame.RawData, framesOffset);
			}
			set
			{
				if (framesOffset == -1)
				{
					throw new InvalidOperationException("Frames flag is not set");
				}
				WriteBigEndian(frame.RawData, framesOffset, value);
			}
		}

		public int Bytes
		{
			get
			{
				if (bytesOffset == -1)
				{
					return -1;
				}
				return ReadBigEndian(frame.RawData, bytesOffset);
			}
			set
			{
				if (framesOffset == -1)
				{
					throw new InvalidOperationException("Bytes flag is not set");
				}
				WriteBigEndian(frame.RawData, bytesOffset, value);
			}
		}

		public int VbrScale => vbrScale;

		public Mp3Frame Mp3Frame => frame;

		private static int ReadBigEndian(byte[] buffer, int offset)
		{
			return (((((buffer[offset] << 8) | buffer[offset + 1]) << 8) | buffer[offset + 2]) << 8) | buffer[offset + 3];
		}

		private void WriteBigEndian(byte[] buffer, int offset, int value)
		{
			byte[] bytes = BitConverter.GetBytes(value);
			for (int i = 0; i < 4; i++)
			{
				buffer[offset + 3 - i] = bytes[i];
			}
		}

		public static XingHeader LoadXingHeader(Mp3Frame frame)
		{
			XingHeader xingHeader = new XingHeader();
			xingHeader.frame = frame;
			int num = 0;
			if (frame.MpegVersion == MpegVersion.Version1)
			{
				num = ((frame.ChannelMode == ChannelMode.Mono) ? 21 : 36);
			}
			else
			{
				if (frame.MpegVersion != MpegVersion.Version2)
				{
					return null;
				}
				num = ((frame.ChannelMode == ChannelMode.Mono) ? 13 : 21);
			}
			if (frame.RawData[num] == 88 && frame.RawData[num + 1] == 105 && frame.RawData[num + 2] == 110 && frame.RawData[num + 3] == 103)
			{
				xingHeader.startOffset = num;
				num += 4;
			}
			else
			{
				if (frame.RawData[num] != 73 || frame.RawData[num + 1] != 110 || frame.RawData[num + 2] != 102 || frame.RawData[num + 3] != 111)
				{
					return null;
				}
				xingHeader.startOffset = num;
				num += 4;
			}
			int num2 = ReadBigEndian(frame.RawData, num);
			num += 4;
			if (((uint)num2 & (true ? 1u : 0u)) != 0)
			{
				xingHeader.framesOffset = num;
				num += 4;
			}
			if (((uint)num2 & 2u) != 0)
			{
				xingHeader.bytesOffset = num;
				num += 4;
			}
			if (((uint)num2 & 4u) != 0)
			{
				xingHeader.tocOffset = num;
				num += 100;
			}
			if (((uint)num2 & 8u) != 0)
			{
				xingHeader.vbrScale = ReadBigEndian(frame.RawData, num);
				num += 4;
			}
			xingHeader.endOffset = num;
			return xingHeader;
		}

		private XingHeader()
		{
		}
	}
	public static class WaveExtensionMethods
	{
		public static ISampleProvider ToSampleProvider(this IWaveProvider waveProvider)
		{
			return SampleProviderConverters.ConvertWaveProviderIntoSampleProvider(waveProvider);
		}

		public static void Init(this IWavePlayer wavePlayer, ISampleProvider sampleProvider, bool convertTo16Bit = false)
		{
			IWaveProvider waveProvider2;
			if (!convertTo16Bit)
			{
				IWaveProvider waveProvider = new SampleToWaveProvider(sampleProvider);
				waveProvider2 = waveProvider;
			}
			else
			{
				IWaveProvider waveProvider = new SampleToWaveProvider16(sampleProvider);
				waveProvider2 = waveProvider;
			}
			IWaveProvider waveProvider3 = waveProvider2;
			wavePlayer.Init(waveProvider3);
		}

		public static WaveFormat AsStandardWaveFormat(this WaveFormat waveFormat)
		{
			if (!(waveFormat is WaveFormatExtensible waveFormatExtensible))
			{
				return waveFormat;
			}
			return waveFormatExtensible.ToStandardWaveFormat();
		}

		public static IWaveProvider ToWaveProvider(this ISampleProvider sampleProvider)
		{
			return new SampleToWaveProvider(sampleProvider);
		}

		public static IWaveProvider ToWaveProvider16(this ISampleProvider sampleProvider)
		{
			return new SampleToWaveProvider16(sampleProvider);
		}

		public static ISampleProvider FollowedBy(this ISampleProvider sampleProvider, ISampleProvider next)
		{
			return new ConcatenatingSampleProvider(new ISampleProvider[2] { sampleProvider, next });
		}

		public static ISampleProvider FollowedBy(this ISampleProvider sampleProvider, TimeSpan silenceDuration, ISampleProvider next)
		{
			OffsetSampleProvider offsetSampleProvider = new OffsetSampleProvider(sampleProvider)
			{
				LeadOut = silenceDuration
			};
			return new ConcatenatingSampleProvider(new ISampleProvider[2] { offsetSampleProvider, next });
		}

		public static ISampleProvider Skip(this ISampleProvider sampleProvider, TimeSpan skipDuration)
		{
			return new OffsetSampleProvider(sampleProvider)
			{
				SkipOver = skipDuration
			};
		}

		public static ISampleProvider Take(this ISampleProvider sampleProvider, TimeSpan takeDuration)
		{
			return new OffsetSampleProvider(sampleProvider)
			{
				Take = takeDuration
			};
		}

		public static ISampleProvider ToMono(this ISampleProvider sourceProvider, float leftVol = 0.5f, float rightVol = 0.5f)
		{
			if (sourceProvider.WaveFormat.Channels == 1)
			{
				return sourceProvider;
			}
			return new StereoToMonoSampleProvider(sourceProvider)
			{
				LeftVolume = leftVol,
				RightVolume = rightVol
			};
		}

		public static ISampleProvider ToStereo(this ISampleProvider sourceProvider, float leftVol = 1f, float rightVol = 1f)
		{
			if (sourceProvider.WaveFormat.Channels == 2)
			{
				return sourceProvider;
			}
			return new MonoToStereoSampleProvider(sourceProvider)
			{
				LeftVolume = leftVol,
				RightVolume = rightVol
			};
		}
	}
	[StructLayout(LayoutKind.Sequential, Pack = 2)]
	public class AdpcmWaveFormat : WaveFormat
	{
		private short samplesPerBlock;

		private short numCoeff;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)]
		private short[] coefficients;

		public int SamplesPerBlock => samplesPerBlock;

		public int NumCoefficients => numCoeff;

		public short[] Coefficients => coefficients;

		private AdpcmWaveFormat()
			: this(8000, 1)
		{
		}

		public AdpcmWaveFormat(int sampleRate, int channels)
			: base(sampleRate, 0, channels)
		{
			waveFormatTag = WaveFormatEncoding.Adpcm;
			extraSize = 32;
			switch (base.sampleRate)
			{
			case 8000:
			case 11025:
				blockAlign = 256;
				break;
			case 22050:
				blockAlign = 512;
				break;
			default:
				blockAlign = 1024;
				break;
			}
			bitsPerSample = 4;
			samplesPerBlock = (short)((blockAlign - 7 * channels) * 8 / (bitsPerSample * channels) + 2);
			averageBytesPerSecond = base.SampleRate * blockAlign / samplesPerBlock;
			numCoeff = 7;
			coefficients = new short[14]
			{
				256, 0, 512, -256, 0, 0, 192, 64, 240, 0,
				460, -208, 392, -232
			};
		}

		public override void Serialize(BinaryWriter writer)
		{
			base.Serialize(writer);
			writer.Write(samplesPerBlock);
			writer.Write(numCoeff);
			short[] array = coefficients;
			foreach (short value in array)
			{
				writer.Write(value);
			}
		}

		public override string ToString()
		{
			return $"Microsoft ADPCM {base.SampleRate} Hz {channels} channels {bitsPerSample} bits per sample {samplesPerBlock} samples per block";
		}
	}
	[StructLayout(LayoutKind.Sequential, Pack = 2)]
	public class Gsm610WaveFormat : WaveFormat
	{
		private readonly short samplesPerBlock;

		public short SamplesPerBlock => samplesPerBlock;

		public Gsm610WaveFormat()
		{
			waveFormatTag = WaveFormatEncoding.Gsm610;
			channels = 1;
			averageBytesPerSecond = 1625;
			bitsPerSample = 0;
			blockAlign = 65;
			sampleRate = 8000;
			extraSize = 2;
			samplesPerBlock = 320;
		}

		public override void Serialize(BinaryWriter writer)
		{
			base.Serialize(writer);
			writer.Write(samplesPerBlock);
		}
	}
	[StructLayout(LayoutKind.Sequential, Pack = 2)]
	public class ImaAdpcmWaveFormat : WaveFormat
	{
		private short samplesPerBlock;

		private ImaAdpcmWaveFormat()
		{
		}

		public ImaAdpcmWaveFormat(int sampleRate, int channels, int bitsPerSample)
		{
			waveFormatTag = WaveFormatEncoding.DviAdpcm;
			base.sampleRate = sampleRate;
			base.channels = (short)channels;
			base.bitsPerSample = (short)bitsPerSample;
			extraSize = 2;
			blockAlign = 0;
			averageBytesPerSecond = 0;
			samplesPerBlock = 0;
		}
	}
	[StructLayout(LayoutKind.Sequential, Pack = 2)]
	public class Mp3WaveFormat : WaveFormat
	{
		public Mp3WaveFormatId id;

		public Mp3WaveFormatFlags flags;

		public ushort blockSize;

		public ushort framesPerBlock;

		public ushort codecDelay;

		private const short Mp3WaveFormatExtraBytes = 12;

		public Mp3WaveFormat(int sampleRate, int channels, int blockSize, int bitRate)
		{
			waveFormatTag = WaveFormatEncoding.MpegLayer3;
			base.channels = (short)channels;
			averageBytesPerSecond = bitRate / 8;
			bitsPerSample = 0;
			blockAlign = 1;
			base.sampleRate = sampleRate;
			extraSize = 12;
			id = Mp3WaveFormatId.Mpeg;
			flags = Mp3WaveFormatFlags.PaddingIso;
			this.blockSize = (ushort)blockSize;
			framesPerBlock = 1;
			codecDelay = 0;
		}
	}
	[Flags]
	public enum Mp3WaveFormatFlags
	{
		PaddingIso = 0,
		PaddingOn = 1,
		PaddingOff = 2
	}
	public enum Mp3WaveFormatId : ushort
	{
		Unknown,
		Mpeg,
		ConstantFrameSize
	}
	[StructLayout(LayoutKind.Sequential, Pack = 2)]
	internal class OggWaveFormat : WaveFormat
	{
		public uint dwVorbisACMVersion;

		public uint dwLibVorbisVersion;
	}
	[StructLayout(LayoutKind.Sequential, Pack = 2)]
	public class TrueSpeechWaveFormat : WaveFormat
	{
		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
		private short[] unknown;

		public TrueSpeechWaveFormat()
		{
			waveFormatTag = WaveFormatEncoding.DspGroupTrueSpeech;
			channels = 1;
			averageBytesPerSecond = 1067;
			bitsPerSample = 1;
			blockAlign = 32;
			sampleRate = 8000;
			extraSize = 32;
			unknown = new short[16];
			unknown[0] = 1;
			unknown[1] = 240;
		}

		public override void Serialize(BinaryWriter writer)
		{
			base.Serialize(writer);
			short[] array = unknown;
			foreach (short value in array)
			{
				writer.Write(value);
			}
		}
	}
	[StructLayout(LayoutKind.Sequential, Pack = 2)]
	public class WaveFormat
	{
		protected WaveFormatEncoding waveFormatTag;

		protected short channels;

		protected int sampleRate;

		protected int averageBytesPerSecond;

		protected short blockAlign;

		protected short bitsPerSample;

		protected short extraSize;

		public WaveFormatEncoding Encoding => waveFormatTag;

		public int Channels => channels;

		public int SampleRate => sampleRate;

		public int AverageBytesPerSecond => averageBytesPerSecond;

		public virtual int BlockAlign => blockAlign;

		public int BitsPerSample => bitsPerSample;

		public int ExtraSize => extraSize;

		public WaveFormat()
			: this(44100, 16, 2)
		{
		}

		public WaveFormat(int sampleRate, int channels)
			: this(sampleRate, 16, channels)
		{
		}

		public int ConvertLatencyToByteSize(int milliseconds)
		{
			int num = (int)((double)AverageBytesPerSecond / 1000.0 * (double)milliseconds);
			if (num % BlockAlign != 0)
			{
				num = num + BlockAlign - num % BlockAlign;
			}
			return num;
		}

		public static WaveFormat CreateCustomFormat(WaveFormatEncoding tag, int sampleRate, int channels, int averageBytesPerSecond, int blockAlign, int bitsPerSample)
		{
			return new WaveFormat
			{
				waveFormatTag = tag,
				channels = (short)channels,
				sampleRate = sampleRate,
				averageBytesPerSecond = averageBytesPerSecond,
				blockAlign = (short)blockAlign,
				bitsPerSample = (short)bitsPerSample,
				extraSize = 0
			};
		}

		public static WaveFormat CreateALawFormat(int sampleRate, int channels)
		{
			return CreateCustomFormat(WaveFormatEncoding.ALaw, sampleRate, channels, sampleRate * channels, channels, 8);
		}

		public static WaveFormat CreateMuLawFormat(int sampleRate, int channels)
		{
			return CreateCustomFormat(WaveFormatEncoding.MuLaw, sampleRate, channels, sampleRate * channels, channels, 8);
		}

		public WaveFormat(int rate, int bits, int channels)
		{
			if (channels < 1)
			{
				throw new ArgumentOutOfRangeException("channels", "Channels must be 1 or greater");
			}
			waveFormatTag = WaveFormatEncoding.Pcm;
			this.channels = (short)channels;
			sampleRate = rate;
			bitsPerSample = (short)bits;
			extraSize = 0;
			blockAlign = (short)(channels * (bits / 8));
			averageBytesPerSecond = sampleRate * blockAlign;
		}

		public static WaveFormat CreateIeeeFloatWaveFormat(int sampleRate, int channels)
		{
			WaveFormat waveFormat = new WaveFormat();
			waveFormat.waveFormatTag = WaveFormatEncoding.IeeeFloat;
			waveFormat.channels = (short)channels;
			waveFormat.bitsPerSample = 32;
			waveFormat.sampleRate = sampleRate;
			waveFormat.blockAlign = (short)(4 * channels);
			waveFormat.averageBytesPerSecond = sampleRate * waveFormat.blockAlign;
			waveFormat.extraSize = 0;
			return waveFormat;
		}

		public static WaveFormat MarshalFromPtr(IntPtr pointer)
		{
			WaveFormat waveFormat = Marshal.PtrToStructure<WaveFormat>(pointer);
			switch (waveFormat.Encoding)
			{
			case WaveFormatEncoding.Pcm:
				waveFormat.extraSize = 0;
				break;
			case WaveFormatEncoding.Extensible:
				waveFormat = Marshal.PtrToStructure<WaveFormatExtensible>(pointer);
				break;
			case WaveFormatEncoding.Adpcm:
				waveFormat = Marshal.PtrToStructure<AdpcmWaveFormat>(pointer);
				break;
			case WaveFormatEncoding.Gsm610:
				waveFormat = Marshal.PtrToStructure<Gsm610WaveFormat>(pointer);
				break;
			default:
				if (waveFormat.ExtraSize > 0)
				{
					waveFormat = Marshal.PtrToStructure<WaveFormatExtraData>(pointer);
				}
				break;
			}
			return waveFormat;
		}

		public static IntPtr MarshalToPtr(WaveFormat format)
		{
			IntPtr intPtr = Marshal.AllocHGlobal(Marshal.SizeOf(format));
			Marshal.StructureToPtr(format, intPtr, fDeleteOld: false);
			return intPtr;
		}

		public static WaveFormat FromFormatChunk(BinaryReader br, int formatChunkLength)
		{
			WaveFormatExtraData waveFormatExtraData = new WaveFormatExtraData();
			waveFormatExtraData.ReadWaveFormat(br, formatChunkLength);
			waveFormatExtraData.ReadExtraData(br);
			return waveFormatExtraData;
		}

		private void ReadWaveFormat(BinaryReader br, int formatChunkLength)
		{
			if (formatChunkLength < 16)
			{
				throw new InvalidDataException("Invalid WaveFormat Structure");
			}
			waveFormatTag = (WaveFormatEncoding)br.ReadUInt16();
			channels = br.ReadInt16();
			sampleRate = br.ReadInt32();
			averageBytesPerSecond = br.ReadInt32();
			blockAlign = br.ReadInt16();
			bitsPerSample = br.ReadInt16();
			if (formatChunkLength > 16)
			{
				extraSize = br.ReadInt16();
				if (extraSize != formatChunkLength - 18)
				{
					extraSize = (short)(formatChunkLength - 18);
				}
			}
		}

		public WaveFormat(BinaryReader br)
		{
			int formatChunkLength = br.ReadInt32();
			ReadWaveFormat(br, formatChunkLength);
		}

		public override string ToString()
		{
			switch (waveFormatTag)
			{
			case WaveFormatEncoding.Pcm:
			case WaveFormatEncoding.Extensible:
				return $"{bitsPerSample} bit PCM: {sampleRate}Hz {channels} channels";
			case WaveFormatEncoding.IeeeFloat:
				return $"{bitsPerSample} bit IEEFloat: {sampleRate}Hz {channels} channels";
			default:
				return waveFormatTag.ToString();
			}
		}

		public override bool Equals(object obj)
		{
			if (obj is WaveFormat waveFormat)
			{
				if (waveFormatTag == waveFormat.waveFormatTag && channels == waveFormat.channels && sampleRate == waveFormat.sampleRate && averageBytesPerSecond == waveFormat.averageBytesPerSecond && blockAlign == waveFormat.blockAlign)
				{
					return bitsPerSample == waveFormat.bitsPerSample;
				}
				return false;
			}
			return false;
		}

		public override int GetHashCode()
		{
			return (int)waveFormatTag ^ (int)channels ^ sampleRate ^ averageBytesPerSecond ^ blockAlign ^ bitsPerSample;
		}

		public virtual void Serialize(BinaryWriter writer)
		{
			writer.Write(18 + extraSize);
			writer.Write((short)Encoding);
			writer.Write((short)Channels);
			writer.Write(SampleRate);
			writer.Write(AverageBytesPerSecond);
			writer.Write((short)BlockAlign);
			writer.Write((short)BitsPerSample);
			writer.Write(extraSize);
		}
	}
	public sealed class WaveFormatCustomMarshaler : ICustomMarshaler
	{
		private static WaveFormatCustomMarshaler marshaler;

		public static ICustomMarshaler GetInstance(string cookie)
		{
			if (marshaler == null)
			{
				marshaler = new WaveFormatCustomMarshaler();
			}
			return marshaler;
		}

		public void CleanUpManagedData(object ManagedObj)
		{
		}

		public void CleanUpNativeData(IntPtr pNativeData)
		{
			Marshal.FreeHGlobal(pNativeData);
		}

		public int GetNativeDataSize()
		{
			throw new NotImplementedException();
		}

		public IntPtr MarshalManagedToNative(object ManagedObj)
		{
			return WaveFormat.MarshalToPtr((WaveFormat)ManagedObj);
		}

		public object MarshalNativeToManaged(IntPtr pNativeData)
		{
			return WaveFormat.MarshalFromPtr(pNativeData);
		}
	}
	public enum WaveFormatEncoding : ushort
	{
		Unknown = 0,
		Pcm = 1,
		Adpcm = 2,
		IeeeFloat = 3,
		Vselp = 4,
		IbmCvsd = 5,
		ALaw = 6,
		MuLaw = 7,
		Dts = 8,
		Drm = 9,
		WmaVoice9 = 10,
		OkiAdpcm = 16,
		DviAdpcm = 17,
		ImaAdpcm = 17,
		MediaspaceAdpcm = 18,
		SierraAdpcm = 19,
		G723Adpcm = 20,
		DigiStd = 21,
		DigiFix = 22,
		DialogicOkiAdpcm = 23,
		MediaVisionAdpcm = 24,
		CUCodec = 25,
		YamahaAdpcm = 32,
		SonarC = 33,
		DspGroupTrueSpeech = 34,
		EchoSpeechCorporation1 = 35,
		AudioFileAf36 = 36,
		Aptx = 37,
		AudioFileAf10 = 38,
		Prosody1612 = 39,
		Lrc = 40,
		DolbyAc2 = 48,
		Gsm610 = 49,
		MsnAudio = 50,
		AntexAdpcme = 51,
		ControlResVqlpc = 52,
		DigiReal = 53,
		DigiAdpcm = 54,
		ControlResCr10 = 55,
		WAVE_FORMAT_NMS_VBXADPCM = 56,
		WAVE_FORMAT_CS_IMAADPCM = 57,
		WAVE_FORMAT_ECHOSC3 = 58,
		WAVE_FORMAT_ROCKWELL_ADPCM = 59,
		WAVE_FORMAT_ROCKWELL_DIGITALK = 60,
		WAVE_FORMAT_XEBEC = 61,
		WAVE_FORMAT_G721_ADPCM = 64,
		WAVE_FORMAT_G728_CELP = 65,
		WAVE_FORMAT_MSG723 = 66,
		Mpeg = 80,
		WAVE_FORMAT_RT24 = 82,
		WAVE_FORMAT_PAC = 83,
		MpegLayer3 = 85,
		WAVE_FORMAT_LUCENT_G723 = 89,
		WAVE_FORMAT_CIRRUS = 96,
		WAVE_FORMAT_ESPCM = 97,
		WAVE_FORMAT_VOXWARE = 98,
		WAVE_FORMAT_CANOPUS_ATRAC = 99,
		WAVE_FORMAT_G726_ADPCM = 100,
		WAVE_FORMAT_G722_ADPCM = 101,
		WAVE_FORMAT_DSAT_DISPLAY = 103,
		WAVE_FORMAT_VOXWARE_BYTE_ALIGNED = 105,
		WAVE_FORMAT_VOXWARE_AC8 = 112,
		WAVE_FORMAT_VOXWARE_AC10 = 113,
		WAVE_FORMAT_VOXWARE_AC16 = 114,
		WAVE_FORMAT_VOXWARE_AC20 = 115,
		WAVE_FORMAT_VOXWARE_RT24 = 116,
		WAVE_FORMAT_VOXWARE_RT29 = 117,
		WAVE_FORMAT_VOXWARE_RT29HW = 118,
		WAVE_FORMAT_VOXWARE_VR12 = 119,
		WAVE_FORMAT_VOXWARE_VR18 = 120,
		WAVE_FORMAT_VOXWARE_TQ40 = 121,
		WAVE_FORMAT_SOFTSOUND = 128,
		WAVE_FORMAT_VOXWARE_TQ60 = 129,
		WAVE_FORMAT_MSRT24 = 130,
		WAVE_FORMAT_G729A = 131,
		WAVE_FORMAT_MVI_MVI2 = 132,
		WAVE_FORMAT_DF_G726 = 133,
		WAVE_FORMAT_DF_GSM610 = 134,
		WAVE_FORMAT_ISIAUDIO = 136,
		WAVE_FORMAT_ONLIVE = 137,
		WAVE_FORMAT_SBC24 = 145,
		WAVE_FORMAT_DOLBY_AC3_SPDIF = 146,
		WAVE_FORMAT_MEDIASONIC_G723 = 147,
		WAVE_FORMAT_PROSODY_8KBPS = 148,
		WAVE_FORMAT_ZYXEL_ADPCM = 151,
		WAVE_FORMAT_PHILIPS_LPCBB = 152,
		WAVE_FORMAT_PACKED = 153,
		WAVE_FORMAT_MALDEN_PHONYTALK = 160,
		Gsm = 161,
		G729 = 162,
		G723 = 163,
		Acelp = 164,
		RawAac = 255,
		WAVE_FORMAT_RHETOREX_ADPCM = 256,
		WAVE_FORMAT_IRAT = 257,
		WAVE_FORMAT_VIVO_G723 = 273,
		WAVE_FORMAT_VIVO_SIREN = 274,
		WAVE_FORMAT_DIGITAL_G723 = 291,
		WAVE_FORMAT_SANYO_LD_ADPCM = 293,
		WAVE_FORMAT_SIPROLAB_ACEPLNET = 304,
		WAVE_FORMAT_SIPROLAB_ACELP4800 = 305,
		WAVE_FORMAT_SIPROLAB_ACELP8V3 = 306,
		WAVE_FORMAT_SIPROLAB_G729 = 307,
		WAVE_FORMAT_SIPROLAB_G729A = 308,
		WAVE_FORMAT_SIPROLAB_KELVIN = 309,
		WAVE_FORMAT_G726ADPCM = 320,
		WAVE_FORMAT_QUALCOMM_PUREVOICE = 336,
		WAVE_FORMAT_QUALCOMM_HALFRATE = 337,
		WAVE_FORMAT_TUBGSM = 341,
		WAVE_FORMAT_MSAUDIO1 = 352,
		WindowsMediaAudio = 353,
		WindowsMediaAudioProfessional = 354,
		WindowsMediaAudioLosseless = 355,
		WindowsMediaAudioSpdif = 356,
		WAVE_FORMAT_UNISYS_NAP_ADPCM = 368,
		WAVE_FORMAT_UNISYS_NAP_ULAW = 369,
		WAVE_FORMAT_UNISYS_NAP_ALAW = 370,
		WAVE_FORMAT_UNISYS_NAP_16K = 371,
		WAVE_FORMAT_CREATIVE_ADPCM = 512,
		WAVE_FORMAT_CREATIVE_FASTSPEECH8 = 514,
		WAVE_FORMAT_CREATIVE_FASTSPEECH10 = 515,
		WAVE_FORMAT_UHER_ADPCM = 528,
		WAVE_FORMAT_QUARTERDECK = 544,
		WAVE_FORMAT_ILINK_VC = 560,
		WAVE_FORMAT_RAW_SPORT = 576,
		WAVE_FORMAT_ESST_AC3 = 577,
		WAVE_FORMAT_IPI_HSX = 592,
		WAVE_FORMAT_IPI_RPELP = 593,
		WAVE_FORMAT_CS2 = 608,
		WAVE_FORMAT_SONY_SCX = 624,
		WAVE_FORMAT_FM_TOWNS_SND = 768,
		WAVE_FORMAT_BTV_DIGITAL = 1024,
		WAVE_FORMAT_QDESIGN_MUSIC = 1104,
		WAVE_FORMAT_VME_VMPCM = 1664,
		WAVE_FORMAT_TPC = 1665,
		WAVE_FORMAT_OLIGSM = 4096,
		WAVE_FORMAT_OLIADPCM = 4097,
		WAVE_FORMAT_OLICELP = 4098,
		WAVE_FORMAT_OLISBC = 4099,
		WAVE_FORMAT_OLIOPR = 4100,
		WAVE_FORMAT_LH_CODEC = 4352,
		WAVE_FORMAT_NORRIS = 5120,
		WAVE_FORMAT_SOUNDSPACE_MUSICOMPRESS = 5376,
		MPEG_ADTS_AAC = 5632,
		MPEG_RAW_AAC = 5633,
		MPEG_LOAS = 5634,
		NOKIA_MPEG_ADTS_AAC = 5640,
		NOKIA_MPEG_RAW_AAC = 5641,
		VODAFONE_MPEG_ADTS_AAC = 5642,
		VODAFONE_MPEG_RAW_AAC = 5643,
		MPEG_HEAAC = 5648,
		WAVE_FORMAT_DVM = 8192,
		Vorbis1 = 26447,
		Vorbis2 = 26448,
		Vorbis3 = 26449,
		Vorbis1P = 26479,
		Vorbis2P = 26480,
		Vorbis3P = 26481,
		Extensible = 65534,
		WAVE_FORMAT_DEVELOPMENT = ushort.MaxValue
	}
	[StructLayout(LayoutKind.Sequential, Pack = 2)]
	public class WaveFormatExtensible : WaveFormat
	{
		private short wValidBitsPerSample;

		private int dwChannelMask;

		private Guid subFormat;

		public Guid SubFormat => subFormat;

		private WaveFormatExtensible()
		{
		}

		public WaveFormatExtensible(int rate, int bits, int channels)
			: base(rate, bits, channels)
		{
			waveFormatTag = WaveFormatEncoding.Extensible;
			extraSize = 22;
			wValidBitsPerSample = (short)bits;
			for (int i = 0; i < channels; i++)
			{
				dwChannelMask |= 1 << i;
			}
			if (bits == 32)
			{
				subFormat = AudioMediaSubtypes.MEDIASUBTYPE_IEEE_FLOAT;
			}
			else
			{
				subFormat = AudioMediaSubtypes.MEDIASUBTYPE_PCM;
			}
		}

		public WaveFormat ToStandardWaveFormat()
		{
			if (subFormat == AudioMediaSubtypes.MEDIASUBTYPE_IEEE_FLOAT && bitsPerSample == 32)
			{
				return WaveFormat.CreateIeeeFloatWaveFormat(sampleRate, channels);
			}
			if (subFormat == AudioMediaSubtypes.MEDIASUBTYPE_PCM)
			{
				return new WaveFormat(sampleRate, bitsPerSample, channels);
			}
			return this;
		}

		public override void Serialize(BinaryWriter writer)
		{
			base.Serialize(writer);
			writer.Write(wValidBitsPerSample);
			writer.Write(dwChannelMask);
			byte[] array = subFormat.ToByteArray();
			writer.Write(array, 0, array.Length);
		}

		public override string ToString()
		{
			return "WAVE_FORMAT_EXTENSIBLE " + AudioMediaSubtypes.GetAudioSubtypeName(subFormat) + " " + $"{base.SampleRate}Hz {base.Channels} channels {base.BitsPerSample} bit";
		}
	}
	[StructLayout(LayoutKind.Sequential, Pack = 2)]
	public class WaveFormatExtraData : WaveFormat
	{
		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
		private byte[] extraData = new byte[100];

		public byte[] ExtraData => extraData;

		internal WaveFormatExtraData()
		{
		}

		public WaveFormatExtraData(BinaryReader reader)
			: base(reader)
		{
			ReadExtraData(reader);
		}

		internal void ReadExtraData(BinaryReader reader)
		{
			if (extraSize > 0)
			{
				reader.Read(extraData, 0, extraSize);
			}
		}

		public override void Serialize(BinaryWriter writer)
		{
			base.Serialize(writer);
			if (extraSize > 0)
			{
				writer.Write(extraData, 0, extraSize);
			}
		}
	}
	public interface IWaveIn : IDisposable
	{
		WaveFormat WaveFormat { get; set; }

		event EventHandler<WaveInEventArgs> DataAvailable;

		event EventHandler<StoppedEventArgs> RecordingStopped;

		void StartRecording();

		void StopRecording();
	}
	public class WaveInEventArgs : EventArgs
	{
		private byte[] buffer;

		private int bytes;

		public byte[] Buffer => buffer;

		public int BytesRecorded => bytes;

		public WaveInEventArgs(byte[] buffer, int bytes)
		{
			this.buffer = buffer;
			this.bytes = bytes;
		}
	}
	public class AiffFileWriter : Stream
	{
		private Stream outStream;

		private BinaryWriter writer;

		private long dataSizePos;

		private long commSampleCountPos;

		private long dataChunkSize = 8L;

		private WaveFormat format;

		private string filename;

		private byte[] value24 = new byte[3];

		public string Filename => filename;

		public override long Length => dataChunkSize;

		public WaveFormat WaveFormat => format;

		public override bool CanRead => false;

		public override bool CanWrite => true;

		public override bool CanSeek => false;

		public override long Position
		{
			get
			{
				return dataChunkSize;
			}
			set
			{
				throw new InvalidOperationException("Repositioning an AiffFileWriter is not supported");
			}
		}

		public static void CreateAiffFile(string filename, WaveStream sourceProvider)
		{
			using AiffFileWriter aiffFileWriter = new AiffFileWriter(filename, sourceProvider.WaveFormat);
			byte[] array = new byte[16384];
			while (sourceProvider.Position < sourceProvider.Length)
			{
				int count = Math.Min((int)(sourceProvider.Length - sourceProvider.Position), array.Length);
				int num = sourceProvider.Read(array, 0, count);
				if (num == 0)
				{
					break;
				}
				aiffFileWriter.Write(array, 0, num);
			}
		}

		public AiffFileWriter(Stream outStream, WaveFormat format)
		{
			this.outStream = outStream;
			this.format = format;
			writer = new BinaryWriter(outStream, Encoding.UTF8);
			writer.Write(Encoding.UTF8.GetBytes("FORM"));
			writer.Write(0);
			writer.Write(Encoding.UTF8.GetBytes("AIFF"));
			CreateCommChunk();
			WriteSsndChunkHeader();
		}

		public AiffFileWriter(string filename, WaveFormat format)
			: this(new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.Read), format)
		{
			this.filename = filename;
		}

		private void WriteSsndChunkHeader()
		{
			writer.Write(Encoding.UTF8.GetBytes("SSND"));
			dataSizePos = outStream.Position;
			writer.Write(0);
			writer.Write(0);
			writer.Write(SwapEndian(format.BlockAlign));
		}

		private byte[] SwapEndian(short n)
		{
			return new byte[2]
			{
				(byte)(n >> 8),
				(byte)((uint)n & 0xFFu)
			};
		}

		private byte[] SwapEndian(int n)
		{
			return new byte[4]
			{
				(byte)((uint)(n >> 24) & 0xFFu),
				(byte)((uint)(n >> 16) & 0xFFu),
				(byte)((uint)(n >> 8) & 0xFFu),
				(byte)((uint)n & 0xFFu)
			};
		}

		private void CreateCommChunk()
		{
			writer.Write(Encoding.UTF8.GetBytes("COMM"));
			writer.Write(SwapEndian(18));
			writer.Write(SwapEndian((short)format.Channels));
			commSampleCountPos = outStream.Position;
			writer.Write(0);
			writer.Write(SwapEndian((short)format.BitsPerSample));
			writer.Write(IEEE.ConvertToIeeeExtended(format.SampleRate));
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			throw new InvalidOperationException("Cannot read from an AiffFileWriter");
		}

		public override long Seek(long offset, SeekOrigin origin)
		{
			throw new InvalidOperationException("Cannot seek within an AiffFileWriter");
		}

		public override void SetLength(long value)
		{
			throw new InvalidOperationException("Cannot set length of an AiffFileWriter");
		}

		public override void Write(byte[] data, int offset, int count)
		{
			byte[] array = new byte[data.Length];
			int num = format.BitsPerSample / 8;
			for (int i = 0; i < data.Length; i++)
			{
				int num2 = (int)Math.Floor((double)i / (double)num) * num + (num - i % num - 1);
				array[i] = data[num2];
			}
			outStream.Write(array, offset, count);
			dataChunkSize += count;
		}

		public void WriteSample(float sample)
		{
			if (WaveFormat.BitsPerSample == 16)
			{
				writer.Write(SwapEndian((short)(32767f * sample)));
				dataChunkSize += 2L;
			}
			else if (WaveFormat.BitsPerSample == 24)
			{
				byte[] bytes = BitConverter.GetBytes((int)(2.1474836E+09f * sample));
				value24[2] = bytes[1];
				value24[1] = bytes[2];
				value24[0] = bytes[3];
				writer.Write(value24);
				dataChunkSize += 3L;
			}
			else
			{
				if (WaveFormat.BitsPerSample != 32 || WaveFormat.Encoding != WaveFormatEncoding.Extensible)
				{
					throw new InvalidOperationException("Only 16, 24 or 32 bit PCM or IEEE float audio data supported");
				}
				writer.Write(SwapEndian(65535 * (int)sample));
				dataChunkSize += 4L;
			}
		}

		public void WriteSamples(float[] samples, int offset, int count)
		{
			for (int i = 0; i < count; i++)
			{
				WriteSample(samples[offset + i]);
			}
		}

		public void WriteSamples(short[] samples, int offset, int count)
		{
			if (WaveFormat.BitsPerSample == 16)
			{
				for (int i = 0; i < count; i++)
				{
					writer.Write(SwapEndian(samples[i + offset]));
				}
				dataChunkSize += count * 2;
			}
			else if (WaveFormat.BitsPerSample == 24)
			{
				for (int j = 0; j < count; j++)
				{
					byte[] bytes = BitConverter.GetBytes(65535 * samples[j + offset]);
					value24[2] = bytes[1];
					value24[1] = bytes[2];
					value24[0] = bytes[3];
					writer.Write(value24);
				}
				dataChunkSize += count * 3;
			}
			else
			{
				if (WaveFormat.BitsPerSample != 32 || WaveFormat.Encoding != WaveFormatEncoding.Extensible)
				{
					throw new InvalidOperationException("Only 16, 24 or 32 bit PCM audio data supported");
				}
				for (int k = 0; k < count; k++)
				{
					writer.Write(SwapEndian(65535 * samples[k + offset]));
				}
				dataChunkSize += count * 4;
			}
		}

		public override void Flush()
		{
			writer.Flush();
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing && outStream != null)
			{
				try
				{
					UpdateHeader(writer);
				}
				finally
				{
					outStream.Dispose();
					outStream = null;
				}
			}
		}

		protected virtual void UpdateHeader(BinaryWriter writer)
		{
			Flush();
			writer.Seek(4, SeekOrigin.Begin);
			writer.Write(SwapEndian((int)(outStream.Length - 8)));
			UpdateCommChunk(writer);
			UpdateSsndChunk(writer);
		}

		private void UpdateCommChunk(BinaryWriter writer)
		{
			writer.Seek((int)commSampleCountPos, SeekOrigin.Begin);
			writer.Write(SwapEndian((int)(dataChunkSize * 8 / format.BitsPerSample / format.Channels)));
		}

		private void UpdateSsndChunk(BinaryWriter writer)
		{
			writer.Seek((int)dataSizePos, SeekOrigin.Begin);
			writer.Write(SwapEndian((int)dataChunkSize));
		}

		~AiffFileWriter()
		{
			Dispose(disposing: false);
		}
	}
	public class BextChunkInfo
	{
		public string Description { get; set; }

		public string Originator { get; set; }

		public string OriginatorReference { get; set; }

		public DateTime OriginationDateTime { get; set; }

		public string OriginationDate => OriginationDateTime.ToString("yyyy-MM-dd");

		public string OriginationTime => OriginationDateTime.ToString("HH:mm:ss");

		public long TimeReference { get; set; }

		public ushort Version => 1;

		public string UniqueMaterialIdentifier { get; set; }

		public byte[] Reserved { get; }

		public string CodingHistory { get; set; }

		public BextChunkInfo()
		{
			Reserved = new byte[190];
		}
	}
	public class BwfWriter : IDisposable
	{
		private readonly WaveFormat format;

		private readonly BinaryWriter writer;

		private readonly long dataChunkSizePosition;

		private long dataLength;

		private bool isDisposed;

		public BwfWriter(string filename, WaveFormat format, BextChunkInfo bextChunkInfo)
		{
			this.format = format;
			writer = new BinaryWriter(File.OpenWrite(filename));
			writer.Write(Encoding.UTF8.GetBytes("RIFF"));
			writer.Write(0);
			writer.Write(Encoding.UTF8.GetBytes("WAVE"));
			writer.Write(Encoding.UTF8.GetBytes("JUNK"));
			writer.Write(28);
			writer.Write(0L);
			writer.Write(0L);
			writer.Write(0L);
			writer.Write(0);
			writer.Write(Encoding.UTF8.GetBytes("bext"));
			byte[] bytes = Encoding.ASCII.GetBytes(bextChunkInfo.CodingHistory ?? "");
			int num = 602 + bytes.Length;
			if (num % 2 != 0)
			{
				num++;
			}
			writer.Write(num);
			_ = writer.BaseStream.Position;
			writer.Write(GetAsBytes(bextChunkInfo.Description, 256));
			writer.Write(GetAsBytes(bextChunkInfo.Originator, 32));
			writer.Write(GetAsBytes(bextChunkInfo.OriginatorReference, 32));
			writer.Write(GetAsBytes(bextChunkInfo.OriginationDate, 10));
			writer.Write(GetAsBytes(bextChunkInfo.OriginationTime, 8));
			writer.Write(bextChunkInfo.TimeReference);
			writer.Write(bextChunkInfo.Version);
			writer.Write(GetAsBytes(bextChunkInfo.UniqueMaterialIdentifier, 64));
			writer.Write(bextChunkInfo.Reserved);
			writer.Write(bytes);
			if (bytes.Length % 2 != 0)
			{
				writer.Write((byte)0);
			}
			writer.Write(Encoding.UTF8.GetBytes("fmt "));
			format.Serialize(writer);
			writer.Write(Encoding.UTF8.GetBytes("data"));
			dataChunkSizePosition = writer.BaseStream.Position;
			writer.Write(-1);
		}

		public void Write(byte[] buffer, int offset, int count)
		{
			if (isDisposed)
			{
				throw new ObjectDisposedException("This BWF Writer already disposed");
			}
			writer.Write(buffer, offset, count);
			dataLength += count;
		}

		public void Flush()
		{
			if (isDisposed)
			{
				throw new ObjectDisposedException("This BWF Writer already disposed");
			}
			writer.Flush();
			FixUpChunkSizes(restorePosition: true);
		}

		private void FixUpChunkSizes(bool restorePosition)
		{
			long position = writer.BaseStream.Position;
			bool num = dataLength > int.MaxValue;
			long num2 = writer.BaseStream.Length - 8;
			if (num)
			{
				int num3 = format.BitsPerSample / 8 * format.Channels;
				writer.BaseStream.Position = 0L;
				writer.Write(Encoding.UTF8.GetBytes("RF64"));
				writer.Write(-1);
				writer.BaseStream.Position += 4L;
				writer.Write(Encoding.UTF8.GetBytes("ds64"));
				writer.BaseStream.Position += 4L;
				writer.Write(num2);
				writer.Write(dataLength);
				writer.Write(dataLength / num3);
			}
			else
			{
				writer.BaseStream.Position = 4L;
				writer.Write((uint)num2);
				writer.BaseStream.Position = dataChunkSizePosition;
				writer.Write((uint)dataLength);
			}
			if (restorePosition)
			{
				writer.BaseStream.Position = position;
			}
		}

		public void Dispose()
		{
			if (!isDisposed)
			{
				FixUpChunkSizes(restorePosition: false);
				writer.Dispose();
				isDisposed = true;
			}
		}

		private static byte[] GetAsBytes(string message, int byteSize)
		{
			byte[] array = new byte[byteSize];
			byte[] bytes = Encoding.ASCII.GetBytes(message ?? "");
			Array.Copy(bytes, array, Math.Min(bytes.Length, byteSize));
			return array;
		}
	}
	public class CueWaveFileWriter : WaveFileWriter
	{
		private CueList cues;

		public CueWaveFileWriter(string fileName, WaveFormat waveFormat)
			: base(fileName, waveFormat)
		{
		}

		public void AddCue(int position, string label)
		{
			if (cues == null)
			{
				cues = new CueList();
			}
			cues.Add(new Cue(position, label));
		}

		private void WriteCues(BinaryWriter w)
		{
			if (cues != null)
			{
				int count = cues.GetRiffChunks().Length;
				w.Seek(0, SeekOrigin.End);
				if (w.BaseStream.Length % 2 == 1)
				{
					w.Write((byte)0);
				}
				w.Write(cues.GetRiffChunks(), 0, count);
				w.Seek(4, SeekOrigin.Begin);
				w.Write((int)(w.BaseStream.Length - 8));
			}
		}

		protected override void UpdateHeader(BinaryWriter writer)
		{
			base.UpdateHeader(writer);
			WriteCues(writer);
		}
	}
	public class DirectSoundOut : IWavePlayer, IDisposable
	{
		[StructLayout(LayoutKind.Sequential, Pack = 2)]
		internal class BufferDescription
		{
			public int dwSize;

			[MarshalAs(UnmanagedType.U4)]
			public DirectSoundBufferCaps dwFlags;

			public uint dwBufferBytes;

			public int dwReserved;

			public IntPtr lpwfxFormat;

			public Guid guidAlgo;
		}

		[StructLayout(LayoutKind.Sequential, Pack = 2)]
		internal class BufferCaps
		{
			public int dwSize;

			public int dwFlags;

			public int dwBufferBytes;

			public int dwUnlockTransferRate;

			public int dwPlayCpuOverhead;
		}

		internal enum DirectSoundCooperativeLevel : uint
		{
			DSSCL_NORMAL = 1u,
			DSSCL_PRIORITY,
			DSSCL_EXCLUSIVE,
			DSSCL_WRITEPRIMARY
		}

		[Flags]
		internal enum DirectSoundPlayFlags : uint
		{
			DSBPLAY_LOOPING = 1u,
			DSBPLAY_LOCHARDWARE = 2u,
			DSBPLAY_LOCSOFTWARE = 4u,
			DSBPLAY_TERMINATEBY_TIME = 8u,
			DSBPLAY_TERMINATEBY_DISTANCE = 0x10u,
			DSBPLAY_TERMINATEBY_PRIORITY = 0x20u
		}

		internal enum DirectSoundBufferLockFlag : uint
		{
			None,
			FromWriteCursor,
			EntireBuffer
		}

		[Flags]
		internal enum DirectSoundBufferStatus : uint
		{
			DSBSTATUS_PLAYING = 1u,
			DSBSTATUS_BUFFERLOST = 2u,
			DSBSTATUS_LOOPING = 4u,
			DSBSTATUS_LOCHARDWARE = 8u,
			DSBSTATUS_LOCSOFTWARE = 0x10u,
			DSBSTATUS_TERMINATED = 0x20u
		}

		[Flags]
		internal enum DirectSoundBufferCaps : uint
		{
			DSBCAPS_PRIMARYBUFFER = 1u,
			DSBCAPS_STATIC = 2u,
			DSBCAPS_LOCHARDWARE = 4u,
			DSBCAPS_LOCSOFTWARE = 8u,
			DSBCAPS_CTRL3D = 0x10u,
			DSBCAPS_CTRLFREQUENCY = 0x20u,
			DSBCAPS_CTRLPAN = 0x40u,
			DSBCAPS_CTRLVOLUME = 0x80u,
			DSBCAPS_CTRLPOSITIONNOTIFY = 0x100u,
			DSBCAPS_CTRLFX = 0x200u,
			DSBCAPS_STICKYFOCUS = 0x4000u,
			DSBCAPS_GLOBALFOCUS = 0x8000u,
			DSBCAPS_GETCURRENTPOSITION2 = 0x10000u,
			DSBCAPS_MUTE3DATMAXDISTANCE = 0x20000u,
			DSBCAPS_LOCDEFER = 0x40000u
		}

		internal struct DirectSoundBufferPositionNotify
		{
			public uint dwOffset;

			public IntPtr hEventNotify;
		}

		[ComImport]
		[Guid("279AFA83-4981-11CE-A521-0020AF0BE560")]
		[SuppressUnmanagedCodeSecurity]
		[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
		internal interface IDirectSound
		{
			void CreateSoundBuffer([In] BufferDescription desc, [MarshalAs(UnmanagedType.Interface)] out object dsDSoundBuffer, IntPtr pUnkOuter);

			void GetCaps(IntPtr caps);

			void DuplicateSoundBuffer([In][MarshalAs(UnmanagedType.Interface)] IDirectSoundBuffer bufferOriginal, [In][MarshalAs(UnmanagedType.Interface)] IDirectSoundBuffer bufferDuplicate);

			void SetCooperativeLevel(IntPtr HWND, [In][MarshalAs(UnmanagedType.U4)] DirectSoundCooperativeLevel dwLevel);

			void Compact();

			void GetSpeakerConfig(IntPtr pdwSpeakerConfig);

			void SetSpeakerConfig(uint pdwSpeakerConfig);

			void Initialize([In][MarshalAs(UnmanagedType.LPStruct)] Guid guid);
		}

		[ComImport]
		[Guid("279AFA85-4981-11CE-A521-0020AF0BE560")]
		[SuppressUnmanagedCodeSecurity]
		[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
		internal interface IDirectSoundBuffer
		{
			void GetCaps([MarshalAs(UnmanagedType.LPStruct)] BufferCaps pBufferCaps);

			void GetCurrentPosition(out uint currentPlayCursor, out uint currentWriteCursor);

			void GetFormat();

			[return: MarshalAs(UnmanagedType.I4)]
			int GetVolume();

			void GetPan(out uint pan);

			[return: MarshalAs(UnmanagedType.I4)]
			int GetFrequency();

			[return: MarshalAs(UnmanagedType.U4)]
			DirectSoundBufferStatus GetStatus();

			void Initialize([In][MarshalAs(UnmanagedType.Interface)] IDirectSound directSound, [In] BufferDescription desc);

			void Lock(int dwOffset, uint dwBytes, out IntPtr audioPtr1, out int audioBytes1, out IntPtr audioPtr2, out int audioBytes2, [MarshalAs(UnmanagedType.U4)] DirectSoundBufferLockFlag dwFlags);

			void Play(uint dwReserved1, uint dwPriority, [In][MarshalAs(UnmanagedType.U4)] DirectSoundPlayFlags dwFlags);

			void SetCurrentPosition(uint dwNewPosition);

			void SetFormat([In] WaveFormat pcfxFormat);

			void SetVolume(int volume);

			void SetPan(uint pan);

			void SetFrequency(uint frequency);

			void Stop();

			void Unlock(IntPtr pvAudioPtr1, int dwAudioBytes1, IntPtr pvAudioPtr2, int dwAudioBytes2);

			void Restore();
		}

		[ComImport]
		[Guid("b0210783-89cd-11d0-af08-00a0c925cd16")]
		[SuppressUnmanagedCodeSecurity]
		[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
		internal interface IDirectSoundNotify
		{
			void SetNotificationPositions(uint dwPositionNotifies, [In][MarshalAs(UnmanagedType.LPArray)] DirectSoundBufferPositionNotify[] pcPositionNotifies);
		}

		private delegate bool DSEnumCallback(IntPtr lpGuid, IntPtr lpcstrDescription, IntPtr lpcstrModule, IntPtr lpContext);

		private PlaybackState playbackState;

		private WaveFormat waveFormat;

		private int samplesTotalSize;

		private int samplesFrameSize;

		private int nextSamplesWriteIndex;

		private int desiredLatency;

		private Guid device;

		private byte[] samples;

		private IWaveProvider waveStream;

		private IDirectSound directSound;

		private IDirectSoundBuffer primarySoundBuffer;

		private IDirectSoundBuffer sec

Mods/RealRadio/NAudio.Midi.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using NAudio.Utils;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("Mark Heath")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("© Mark Heath 2023")]
[assembly: AssemblyFileVersion("2.2.1.0")]
[assembly: AssemblyInformationalVersion("2.2.1")]
[assembly: AssemblyProduct("NAudio.Midi")]
[assembly: AssemblyTitle("NAudio.Midi")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/naudio/NAudio")]
[assembly: AssemblyVersion("2.2.1.0")]
namespace NAudio.Midi
{
	public class ChannelAfterTouchEvent : MidiEvent
	{
		private byte afterTouchPressure;

		public int AfterTouchPressure
		{
			get
			{
				return afterTouchPressure;
			}
			set
			{
				if (value < 0 || value > 127)
				{
					throw new ArgumentOutOfRangeException("value", "After touch pressure must be in the range 0-127");
				}
				afterTouchPressure = (byte)value;
			}
		}

		public ChannelAfterTouchEvent(BinaryReader br)
		{
			afterTouchPressure = br.ReadByte();
			if ((afterTouchPressure & 0x80u) != 0)
			{
				throw new FormatException("Invalid afterTouchPressure");
			}
		}

		public ChannelAfterTouchEvent(long absoluteTime, int channel, int afterTouchPressure)
			: base(absoluteTime, channel, MidiCommandCode.ChannelAfterTouch)
		{
			AfterTouchPressure = afterTouchPressure;
		}

		public override void Export(ref long absoluteTime, BinaryWriter writer)
		{
			base.Export(ref absoluteTime, writer);
			writer.Write(afterTouchPressure);
		}

		public override int GetAsShortMessage()
		{
			return base.GetAsShortMessage() + (afterTouchPressure << 8);
		}

		public override string ToString()
		{
			return $"{base.ToString()} {afterTouchPressure}";
		}
	}
	public class ControlChangeEvent : MidiEvent
	{
		private MidiController controller;

		private byte controllerValue;

		public MidiController Controller
		{
			get
			{
				return controller;
			}
			set
			{
				if ((int)value < 0 || (int)value > 127)
				{
					throw new ArgumentOutOfRangeException("value", "Controller number must be in the range 0-127");
				}
				controller = value;
			}
		}

		public int ControllerValue
		{
			get
			{
				return controllerValue;
			}
			set
			{
				if (value < 0 || value > 127)
				{
					throw new ArgumentOutOfRangeException("value", "Controller Value must be in the range 0-127");
				}
				controllerValue = (byte)value;
			}
		}

		public ControlChangeEvent(BinaryReader br)
		{
			byte b = br.ReadByte();
			controllerValue = br.ReadByte();
			if ((b & 0x80u) != 0)
			{
				throw new InvalidDataException("Invalid controller");
			}
			controller = (MidiController)b;
			if ((controllerValue & 0x80u) != 0)
			{
				throw new InvalidDataException($"Invalid controllerValue {controllerValue} for controller {controller}, Pos 0x{br.BaseStream.Position:X}");
			}
		}

		public ControlChangeEvent(long absoluteTime, int channel, MidiController controller, int controllerValue)
			: base(absoluteTime, channel, MidiCommandCode.ControlChange)
		{
			Controller = controller;
			ControllerValue = controllerValue;
		}

		public override string ToString()
		{
			return $"{base.ToString()} Controller {controller} Value {controllerValue}";
		}

		public override int GetAsShortMessage()
		{
			byte b = (byte)controller;
			return base.GetAsShortMessage() + (b << 8) + (controllerValue << 16);
		}

		public override void Export(ref long absoluteTime, BinaryWriter writer)
		{
			base.Export(ref absoluteTime, writer);
			writer.Write((byte)controller);
			writer.Write(controllerValue);
		}
	}
	public class KeySignatureEvent : MetaEvent
	{
		private readonly byte sharpsFlats;

		private readonly byte majorMinor;

		public int SharpsFlats => (sbyte)sharpsFlats;

		public int MajorMinor => majorMinor;

		public KeySignatureEvent(BinaryReader br, int length)
		{
			if (length != 2)
			{
				throw new FormatException("Invalid key signature length");
			}
			sharpsFlats = br.ReadByte();
			majorMinor = br.ReadByte();
		}

		public KeySignatureEvent(int sharpsFlats, int majorMinor, long absoluteTime)
			: base(MetaEventType.KeySignature, 2, absoluteTime)
		{
			this.sharpsFlats = (byte)sharpsFlats;
			this.majorMinor = (byte)majorMinor;
		}

		public override MidiEvent Clone()
		{
			return (KeySignatureEvent)MemberwiseClone();
		}

		public override string ToString()
		{
			return $"{base.ToString()} {SharpsFlats} {majorMinor}";
		}

		public override void Export(ref long absoluteTime, BinaryWriter writer)
		{
			base.Export(ref absoluteTime, writer);
			writer.Write(sharpsFlats);
			writer.Write(majorMinor);
		}
	}
	public class MetaEvent : MidiEvent
	{
		private MetaEventType metaEvent;

		internal int metaDataLength;

		public MetaEventType MetaEventType => metaEvent;

		protected MetaEvent()
		{
		}

		public MetaEvent(MetaEventType metaEventType, int metaDataLength, long absoluteTime)
			: base(absoluteTime, 1, MidiCommandCode.MetaEvent)
		{
			metaEvent = metaEventType;
			this.metaDataLength = metaDataLength;
		}

		public override MidiEvent Clone()
		{
			return new MetaEvent(metaEvent, metaDataLength, base.AbsoluteTime);
		}

		public static MetaEvent ReadMetaEvent(BinaryReader br)
		{
			MetaEventType metaEventType = (MetaEventType)br.ReadByte();
			int num = MidiEvent.ReadVarInt(br);
			MetaEvent metaEvent = new MetaEvent();
			if (metaEventType <= MetaEventType.SetTempo)
			{
				if (metaEventType <= MetaEventType.DeviceName)
				{
					if (metaEventType != 0)
					{
						if (metaEventType - 1 > MetaEventType.ProgramName)
						{
							goto IL_00a6;
						}
						metaEvent = new TextEvent(br, num);
					}
					else
					{
						metaEvent = new TrackSequenceNumberEvent(br, num);
					}
				}
				else if (metaEventType != MetaEventType.EndTrack)
				{
					if (metaEventType != MetaEventType.SetTempo)
					{
						goto IL_00a6;
					}
					metaEvent = new TempoEvent(br, num);
				}
				else if (num != 0)
				{
					throw new FormatException("End track length");
				}
			}
			else if (metaEventType <= MetaEventType.TimeSignature)
			{
				if (metaEventType != MetaEventType.SmpteOffset)
				{
					if (metaEventType != MetaEventType.TimeSignature)
					{
						goto IL_00a6;
					}
					metaEvent = new TimeSignatureEvent(br, num);
				}
				else
				{
					metaEvent = new SmpteOffsetEvent(br, num);
				}
			}
			else if (metaEventType != MetaEventType.KeySignature)
			{
				if (metaEventType != MetaEventType.SequencerSpecific)
				{
					goto IL_00a6;
				}
				metaEvent = new SequencerSpecificEvent(br, num);
			}
			else
			{
				metaEvent = new KeySignatureEvent(br, num);
			}
			metaEvent.metaEvent = metaEventType;
			metaEvent.metaDataLength = num;
			return metaEvent;
			IL_00a6:
			byte[] array = br.ReadBytes(num);
			if (array.Length != num)
			{
				throw new FormatException("Failed to read metaevent's data fully");
			}
			return new RawMetaEvent(metaEventType, 0L, array);
		}

		public override string ToString()
		{
			return $"{base.AbsoluteTime} {metaEvent}";
		}

		public override void Export(ref long absoluteTime, BinaryWriter writer)
		{
			base.Export(ref absoluteTime, writer);
			writer.Write((byte)metaEvent);
			MidiEvent.WriteVarInt(writer, metaDataLength);
		}
	}
	public enum MetaEventType : byte
	{
		TrackSequenceNumber = 0,
		TextEvent = 1,
		Copyright = 2,
		SequenceTrackName = 3,
		TrackInstrumentName = 4,
		Lyric = 5,
		Marker = 6,
		CuePoint = 7,
		ProgramName = 8,
		DeviceName = 9,
		MidiChannel = 32,
		MidiPort = 33,
		EndTrack = 47,
		SetTempo = 81,
		SmpteOffset = 84,
		TimeSignature = 88,
		KeySignature = 89,
		SequencerSpecific = 127
	}
	public enum MidiCommandCode : byte
	{
		NoteOff = 128,
		NoteOn = 144,
		KeyAfterTouch = 160,
		ControlChange = 176,
		PatchChange = 192,
		ChannelAfterTouch = 208,
		PitchWheelChange = 224,
		Sysex = 240,
		Eox = 247,
		TimingClock = 248,
		StartSequence = 250,
		ContinueSequence = 251,
		StopSequence = 252,
		AutoSensing = 254,
		MetaEvent = byte.MaxValue
	}
	public enum MidiController : byte
	{
		BankSelect = 0,
		Modulation = 1,
		BreathController = 2,
		FootController = 4,
		MainVolume = 7,
		Pan = 10,
		Expression = 11,
		BankSelectLsb = 32,
		Sustain = 64,
		Portamento = 65,
		Sostenuto = 66,
		SoftPedal = 67,
		LegatoFootswitch = 68,
		ResetAllControllers = 121,
		AllNotesOff = 123
	}
	public class MidiEvent : ICloneable
	{
		private MidiCommandCode commandCode;

		private int channel;

		private int deltaTime;

		private long absoluteTime;

		public virtual int Channel
		{
			get
			{
				return channel;
			}
			set
			{
				if (value < 1 || value > 16)
				{
					throw new ArgumentOutOfRangeException("value", value, $"Channel must be 1-16 (Got {value})");
				}
				channel = value;
			}
		}

		public int DeltaTime => deltaTime;

		public long AbsoluteTime
		{
			get
			{
				return absoluteTime;
			}
			set
			{
				absoluteTime = value;
			}
		}

		public MidiCommandCode CommandCode => commandCode;

		public static MidiEvent FromRawMessage(int rawMessage)
		{
			long num = 0L;
			int num2 = rawMessage & 0xFF;
			int num3 = (rawMessage >> 8) & 0xFF;
			int num4 = (rawMessage >> 16) & 0xFF;
			int num5 = 1;
			MidiCommandCode midiCommandCode;
			if ((num2 & 0xF0) == 240)
			{
				midiCommandCode = (MidiCommandCode)num2;
			}
			else
			{
				midiCommandCode = (MidiCommandCode)((uint)num2 & 0xF0u);
				num5 = (num2 & 0xF) + 1;
			}
			switch (midiCommandCode)
			{
			case MidiCommandCode.NoteOff:
			case MidiCommandCode.NoteOn:
			case MidiCommandCode.KeyAfterTouch:
				if (num4 > 0 && midiCommandCode == MidiCommandCode.NoteOn)
				{
					return new NoteOnEvent(num, num5, num3, num4, 0);
				}
				return new NoteEvent(num, num5, midiCommandCode, num3, num4);
			case MidiCommandCode.ControlChange:
				return new ControlChangeEvent(num, num5, (MidiController)num3, num4);
			case MidiCommandCode.PatchChange:
				return new PatchChangeEvent(num, num5, num3);
			case MidiCommandCode.ChannelAfterTouch:
				return new ChannelAfterTouchEvent(num, num5, num3);
			case MidiCommandCode.PitchWheelChange:
				return new PitchWheelChangeEvent(num, num5, num3 + (num4 << 7));
			case MidiCommandCode.TimingClock:
			case MidiCommandCode.StartSequence:
			case MidiCommandCode.ContinueSequence:
			case MidiCommandCode.StopSequence:
			case MidiCommandCode.AutoSensing:
				return new MidiEvent(num, num5, midiCommandCode);
			default:
				throw new FormatException($"Unsupported MIDI Command Code for Raw Message {midiCommandCode}");
			}
		}

		public static MidiEvent ReadNextEvent(BinaryReader br, MidiEvent previous)
		{
			int num = ReadVarInt(br);
			int num2 = 1;
			byte b = br.ReadByte();
			MidiCommandCode midiCommandCode;
			if ((b & 0x80) == 0)
			{
				midiCommandCode = previous.CommandCode;
				num2 = previous.Channel;
				br.BaseStream.Position--;
			}
			else if ((b & 0xF0) == 240)
			{
				midiCommandCode = (MidiCommandCode)b;
			}
			else
			{
				midiCommandCode = (MidiCommandCode)(b & 0xF0u);
				num2 = (b & 0xF) + 1;
			}
			MidiEvent midiEvent;
			switch (midiCommandCode)
			{
			case MidiCommandCode.NoteOn:
				midiEvent = new NoteOnEvent(br);
				break;
			case MidiCommandCode.NoteOff:
			case MidiCommandCode.KeyAfterTouch:
				midiEvent = new NoteEvent(br);
				break;
			case MidiCommandCode.ControlChange:
				midiEvent = new ControlChangeEvent(br);
				break;
			case MidiCommandCode.PatchChange:
				midiEvent = new PatchChangeEvent(br);
				break;
			case MidiCommandCode.ChannelAfterTouch:
				midiEvent = new ChannelAfterTouchEvent(br);
				break;
			case MidiCommandCode.PitchWheelChange:
				midiEvent = new PitchWheelChangeEvent(br);
				break;
			case MidiCommandCode.TimingClock:
			case MidiCommandCode.StartSequence:
			case MidiCommandCode.ContinueSequence:
			case MidiCommandCode.StopSequence:
				midiEvent = new MidiEvent();
				break;
			case MidiCommandCode.Sysex:
				midiEvent = SysexEvent.ReadSysexEvent(br);
				break;
			case MidiCommandCode.MetaEvent:
				midiEvent = MetaEvent.ReadMetaEvent(br);
				break;
			default:
				throw new FormatException($"Unsupported MIDI Command Code {(byte)midiCommandCode:X2}");
			}
			midiEvent.channel = num2;
			midiEvent.deltaTime = num;
			midiEvent.commandCode = midiCommandCode;
			return midiEvent;
		}

		public virtual int GetAsShortMessage()
		{
			return channel - 1 + (int)commandCode;
		}

		protected MidiEvent()
		{
		}

		public MidiEvent(long absoluteTime, int channel, MidiCommandCode commandCode)
		{
			this.absoluteTime = absoluteTime;
			Channel = channel;
			this.commandCode = commandCode;
		}

		public virtual MidiEvent Clone()
		{
			return (MidiEvent)MemberwiseClone();
		}

		object ICloneable.Clone()
		{
			return Clone();
		}

		public static bool IsNoteOff(MidiEvent midiEvent)
		{
			if (midiEvent != null)
			{
				if (midiEvent.CommandCode == MidiCommandCode.NoteOn)
				{
					return ((NoteEvent)midiEvent).Velocity == 0;
				}
				return midiEvent.CommandCode == MidiCommandCode.NoteOff;
			}
			return false;
		}

		public static bool IsNoteOn(MidiEvent midiEvent)
		{
			if (midiEvent != null && midiEvent.CommandCode == MidiCommandCode.NoteOn)
			{
				return ((NoteEvent)midiEvent).Velocity > 0;
			}
			return false;
		}

		public static bool IsEndTrack(MidiEvent midiEvent)
		{
			if (midiEvent != null && midiEvent is MetaEvent metaEvent)
			{
				return metaEvent.MetaEventType == MetaEventType.EndTrack;
			}
			return false;
		}

		public override string ToString()
		{
			if ((int)commandCode >= 240)
			{
				return $"{absoluteTime} {commandCode}";
			}
			return $"{absoluteTime} {commandCode} Ch: {channel}";
		}

		public static int ReadVarInt(BinaryReader br)
		{
			int num = 0;
			for (int i = 0; i < 4; i++)
			{
				byte b = br.ReadByte();
				num <<= 7;
				num += b & 0x7F;
				if ((b & 0x80) == 0)
				{
					return num;
				}
			}
			throw new FormatException("Invalid Var Int");
		}

		public static void WriteVarInt(BinaryWriter writer, int value)
		{
			if (value < 0)
			{
				throw new ArgumentOutOfRangeException("value", value, "Cannot write a negative Var Int");
			}
			if (value > 268435455)
			{
				throw new ArgumentOutOfRangeException("value", value, "Maximum allowed Var Int is 0x0FFFFFFF");
			}
			int num = 0;
			byte[] array = new byte[4];
			do
			{
				array[num++] = (byte)((uint)value & 0x7Fu);
				value >>= 7;
			}
			while (value > 0);
			while (num > 0)
			{
				num--;
				if (num > 0)
				{
					writer.Write((byte)(array[num] | 0x80u));
				}
				else
				{
					writer.Write(array[num]);
				}
			}
		}

		public virtual void Export(ref long absoluteTime, BinaryWriter writer)
		{
			if (this.absoluteTime < absoluteTime)
			{
				throw new FormatException("Can't export unsorted MIDI events");
			}
			WriteVarInt(writer, (int)(this.absoluteTime - absoluteTime));
			absoluteTime = this.absoluteTime;
			int num = (int)commandCode;
			if (commandCode != MidiCommandCode.MetaEvent)
			{
				num += channel - 1;
			}
			writer.Write((byte)num);
		}
	}
	public class MidiEventCollection : IEnumerable<IList<MidiEvent>>, IEnumerable
	{
		private int midiFileType;

		private readonly List<IList<MidiEvent>> trackEvents;

		public int Tracks => trackEvents.Count;

		public long StartAbsoluteTime { get; set; }

		public int DeltaTicksPerQuarterNote { get; }

		public IList<MidiEvent> this[int trackNumber] => trackEvents[trackNumber];

		public int MidiFileType
		{
			get
			{
				return midiFileType;
			}
			set
			{
				if (midiFileType != value)
				{
					midiFileType = value;
					if (value == 0)
					{
						FlattenToOneTrack();
					}
					else
					{
						ExplodeToManyTracks();
					}
				}
			}
		}

		public MidiEventCollection(int midiFileType, int deltaTicksPerQuarterNote)
		{
			this.midiFileType = midiFileType;
			DeltaTicksPerQuarterNote = deltaTicksPerQuarterNote;
			StartAbsoluteTime = 0L;
			trackEvents = new List<IList<MidiEvent>>();
		}

		public IList<MidiEvent> GetTrackEvents(int trackNumber)
		{
			return trackEvents[trackNumber];
		}

		public IList<MidiEvent> AddTrack()
		{
			return AddTrack(null);
		}

		public IList<MidiEvent> AddTrack(IList<MidiEvent> initialEvents)
		{
			List<MidiEvent> list = new List<MidiEvent>();
			if (initialEvents != null)
			{
				list.AddRange(initialEvents);
			}
			trackEvents.Add(list);
			return list;
		}

		public void RemoveTrack(int track)
		{
			trackEvents.RemoveAt(track);
		}

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

		public void AddEvent(MidiEvent midiEvent, int originalTrack)
		{
			if (midiFileType == 0)
			{
				EnsureTracks(1);
				trackEvents[0].Add(midiEvent);
			}
			else if (originalTrack == 0)
			{
				switch (midiEvent.CommandCode)
				{
				case MidiCommandCode.NoteOff:
				case MidiCommandCode.NoteOn:
				case MidiCommandCode.KeyAfterTouch:
				case MidiCommandCode.ControlChange:
				case MidiCommandCode.PatchChange:
				case MidiCommandCode.ChannelAfterTouch:
				case MidiCommandCode.PitchWheelChange:
					EnsureTracks(midiEvent.Channel + 1);
					trackEvents[midiEvent.Channel].Add(midiEvent);
					break;
				default:
					EnsureTracks(1);
					trackEvents[0].Add(midiEvent);
					break;
				}
			}
			else
			{
				EnsureTracks(originalTrack + 1);
				trackEvents[originalTrack].Add(midiEvent);
			}
		}

		private void EnsureTracks(int count)
		{
			for (int i = trackEvents.Count; i < count; i++)
			{
				trackEvents.Add(new List<MidiEvent>());
			}
		}

		private void ExplodeToManyTracks()
		{
			IList<MidiEvent> list = trackEvents[0];
			Clear();
			foreach (MidiEvent item in list)
			{
				AddEvent(item, 0);
			}
			PrepareForExport();
		}

		private void FlattenToOneTrack()
		{
			bool flag = false;
			for (int i = 1; i < trackEvents.Count; i++)
			{
				foreach (MidiEvent item in trackEvents[i])
				{
					if (!MidiEvent.IsEndTrack(item))
					{
						trackEvents[0].Add(item);
						flag = true;
					}
				}
			}
			for (int num = trackEvents.Count - 1; num > 0; num--)
			{
				RemoveTrack(num);
			}
			if (flag)
			{
				PrepareForExport();
			}
		}

		public void PrepareForExport()
		{
			MidiEventComparer comparer = new MidiEventComparer();
			foreach (IList<MidiEvent> trackEvent in trackEvents)
			{
				MergeSort.Sort(trackEvent, comparer);
				int num = 0;
				while (num < trackEvent.Count - 1)
				{
					if (MidiEvent.IsEndTrack(trackEvent[num]))
					{
						trackEvent.RemoveAt(num);
					}
					else
					{
						num++;
					}
				}
			}
			int num2 = 0;
			while (num2 < trackEvents.Count)
			{
				IList<MidiEvent> list = trackEvents[num2];
				if (list.Count == 0)
				{
					RemoveTrack(num2);
					continue;
				}
				if (list.Count == 1 && MidiEvent.IsEndTrack(list[0]))
				{
					RemoveTrack(num2);
					continue;
				}
				if (!MidiEvent.IsEndTrack(list[list.Count - 1]))
				{
					list.Add(new MetaEvent(MetaEventType.EndTrack, 0, list[list.Count - 1].AbsoluteTime));
				}
				num2++;
			}
		}

		public IEnumerator<IList<MidiEvent>> GetEnumerator()
		{
			return trackEvents.GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return trackEvents.GetEnumerator();
		}
	}
	public class MidiEventComparer : IComparer<MidiEvent>
	{
		public int Compare(MidiEvent x, MidiEvent y)
		{
			long num = x.AbsoluteTime;
			long num2 = y.AbsoluteTime;
			if (num == num2)
			{
				MetaEvent metaEvent = x as MetaEvent;
				MetaEvent metaEvent2 = y as MetaEvent;
				if (metaEvent != null)
				{
					num = ((metaEvent.MetaEventType != MetaEventType.EndTrack) ? long.MinValue : long.MaxValue);
				}
				if (metaEvent2 != null)
				{
					num2 = ((metaEvent2.MetaEventType != MetaEventType.EndTrack) ? long.MinValue : long.MaxValue);
				}
			}
			return num.CompareTo(num2);
		}
	}
	public class MidiFile
	{
		private readonly MidiEventCollection events;

		private readonly ushort fileFormat;

		private readonly ushort deltaTicksPerQuarterNote;

		private readonly bool strictChecking;

		public int FileFormat => fileFormat;

		public MidiEventCollection Events => events;

		public int Tracks => events.Tracks;

		public int DeltaTicksPerQuarterNote => deltaTicksPerQuarterNote;

		public MidiFile(string filename)
			: this(filename, strictChecking: true)
		{
		}

		public MidiFile(string filename, bool strictChecking)
			: this(File.OpenRead(filename), strictChecking, ownInputStream: true)
		{
		}

		public MidiFile(Stream inputStream, bool strictChecking)
			: this(inputStream, strictChecking, ownInputStream: false)
		{
		}

		private MidiFile(Stream inputStream, bool strictChecking, bool ownInputStream)
		{
			this.strictChecking = strictChecking;
			BinaryReader binaryReader = new BinaryReader(inputStream);
			try
			{
				if (Encoding.UTF8.GetString(binaryReader.ReadBytes(4)) != "MThd")
				{
					throw new FormatException("Not a MIDI file - header chunk missing");
				}
				uint num = SwapUInt32(binaryReader.ReadUInt32());
				if (num != 6)
				{
					throw new FormatException("Unexpected header chunk length");
				}
				fileFormat = SwapUInt16(binaryReader.ReadUInt16());
				int num2 = SwapUInt16(binaryReader.ReadUInt16());
				deltaTicksPerQuarterNote = SwapUInt16(binaryReader.ReadUInt16());
				events = new MidiEventCollection((fileFormat != 0) ? 1 : 0, deltaTicksPerQuarterNote);
				for (int i = 0; i < num2; i++)
				{
					events.AddTrack();
				}
				long num3 = 0L;
				for (int j = 0; j < num2; j++)
				{
					if (fileFormat == 1)
					{
						num3 = 0L;
					}
					if (Encoding.UTF8.GetString(binaryReader.ReadBytes(4)) != "MTrk")
					{
						throw new FormatException("Invalid chunk header");
					}
					num = SwapUInt32(binaryReader.ReadUInt32());
					long position = binaryReader.BaseStream.Position;
					MidiEvent midiEvent = null;
					List<NoteOnEvent> list = new List<NoteOnEvent>();
					while (binaryReader.BaseStream.Position < position + num)
					{
						try
						{
							midiEvent = MidiEvent.ReadNextEvent(binaryReader, midiEvent);
						}
						catch (InvalidDataException)
						{
							if (strictChecking)
							{
								throw;
							}
							continue;
						}
						catch (FormatException)
						{
							if (strictChecking)
							{
								throw;
							}
							continue;
						}
						num3 = (midiEvent.AbsoluteTime = num3 + midiEvent.DeltaTime);
						events[j].Add(midiEvent);
						if (midiEvent.CommandCode == MidiCommandCode.NoteOn)
						{
							NoteEvent noteEvent = (NoteEvent)midiEvent;
							if (noteEvent.Velocity > 0)
							{
								list.Add((NoteOnEvent)noteEvent);
							}
							else
							{
								FindNoteOn(noteEvent, list);
							}
						}
						else if (midiEvent.CommandCode == MidiCommandCode.NoteOff)
						{
							FindNoteOn((NoteEvent)midiEvent, list);
						}
						else if (midiEvent.CommandCode == MidiCommandCode.MetaEvent && ((MetaEvent)midiEvent).MetaEventType == MetaEventType.EndTrack && strictChecking && binaryReader.BaseStream.Position < position + num)
						{
							throw new FormatException($"End Track event was not the last MIDI event on track {j}");
						}
					}
					if (list.Count > 0 && strictChecking)
					{
						throw new FormatException($"Note ons without note offs {list.Count} (file format {fileFormat})");
					}
					if (binaryReader.BaseStream.Position != position + num)
					{
						throw new FormatException($"Read too far {num}+{position}!={binaryReader.BaseStream.Position}");
					}
				}
			}
			finally
			{
				if (ownInputStream)
				{
					binaryReader.Dispose();
				}
			}
		}

		private void FindNoteOn(NoteEvent offEvent, List<NoteOnEvent> outstandingNoteOns)
		{
			bool flag = false;
			foreach (NoteOnEvent outstandingNoteOn in outstandingNoteOns)
			{
				if (outstandingNoteOn.Channel == offEvent.Channel && outstandingNoteOn.NoteNumber == offEvent.NoteNumber)
				{
					outstandingNoteOn.OffEvent = offEvent;
					outstandingNoteOns.Remove(outstandingNoteOn);
					flag = true;
					break;
				}
			}
			if (!flag && strictChecking)
			{
				throw new FormatException($"Got an off without an on {offEvent}");
			}
		}

		private static uint SwapUInt32(uint i)
		{
			return ((i & 0xFF000000u) >> 24) | ((i & 0xFF0000) >> 8) | ((i & 0xFF00) << 8) | ((i & 0xFF) << 24);
		}

		private static ushort SwapUInt16(ushort i)
		{
			return (ushort)(((i & 0xFF00) >> 8) | ((i & 0xFF) << 8));
		}

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendFormat("Format {0}, Tracks {1}, Delta Ticks Per Quarter Note {2}\r\n", fileFormat, Tracks, deltaTicksPerQuarterNote);
			for (int i = 0; i < Tracks; i++)
			{
				foreach (MidiEvent item in events[i])
				{
					stringBuilder.AppendFormat("{0}\r\n", item);
				}
			}
			return stringBuilder.ToString();
		}

		public static void Export(string filename, MidiEventCollection events)
		{
			if (events.MidiFileType == 0 && events.Tracks > 1)
			{
				throw new ArgumentException("Can't export more than one track to a type 0 file");
			}
			using BinaryWriter binaryWriter = new BinaryWriter(File.Create(filename));
			binaryWriter.Write(Encoding.UTF8.GetBytes("MThd"));
			binaryWriter.Write(SwapUInt32(6u));
			binaryWriter.Write(SwapUInt16((ushort)events.MidiFileType));
			binaryWriter.Write(SwapUInt16((ushort)events.Tracks));
			binaryWriter.Write(SwapUInt16((ushort)events.DeltaTicksPerQuarterNote));
			for (int i = 0; i < events.Tracks; i++)
			{
				IList<MidiEvent> list = events[i];
				binaryWriter.Write(Encoding.UTF8.GetBytes("MTrk"));
				long position = binaryWriter.BaseStream.Position;
				binaryWriter.Write(SwapUInt32(0u));
				long absoluteTime = events.StartAbsoluteTime;
				MergeSort.Sort(list, new MidiEventComparer());
				_ = list.Count;
				_ = 0;
				foreach (MidiEvent item in list)
				{
					item.Export(ref absoluteTime, binaryWriter);
				}
				uint num = (uint)((int)(binaryWriter.BaseStream.Position - position) - 4);
				binaryWriter.BaseStream.Position = position;
				binaryWriter.Write(SwapUInt32(num));
				binaryWriter.BaseStream.Position += num;
			}
		}
	}
	public class MidiIn : IDisposable
	{
		private IntPtr hMidiIn = IntPtr.Zero;

		private bool disposeIsRunning;

		private bool disposed;

		private MidiInterop.MidiInCallback callback;

		private IntPtr[] SysexBufferHeaders = new IntPtr[0];

		public static int NumberOfDevices => MidiInterop.midiInGetNumDevs();

		public event EventHandler<MidiInMessageEventArgs> MessageReceived;

		public event EventHandler<MidiInMessageEventArgs> ErrorReceived;

		public event EventHandler<MidiInSysexMessageEventArgs> SysexMessageReceived;

		public MidiIn(int deviceNo)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			callback = Callback;
			MmException.Try(MidiInterop.midiInOpen(out hMidiIn, (IntPtr)deviceNo, callback, IntPtr.Zero, 196608), "midiInOpen");
		}

		public void Close()
		{
			Dispose();
		}

		public void Dispose()
		{
			GC.KeepAlive(callback);
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}

		public void Start()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			MmException.Try(MidiInterop.midiInStart(hMidiIn), "midiInStart");
		}

		public void Stop()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			MmException.Try(MidiInterop.midiInStop(hMidiIn), "midiInStop");
		}

		public void Reset()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			MmException.Try(MidiInterop.midiInReset(hMidiIn), "midiInReset");
		}

		public void CreateSysexBuffers(int bufferSize, int numberOfBuffers)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			SysexBufferHeaders = new IntPtr[numberOfBuffers];
			int cb = Marshal.SizeOf(typeof(MidiInterop.MIDIHDR));
			for (int i = 0; i < numberOfBuffers; i++)
			{
				MidiInterop.MIDIHDR structure = default(MidiInterop.MIDIHDR);
				structure.dwBufferLength = bufferSize;
				structure.dwBytesRecorded = 0;
				structure.lpData = Marshal.AllocHGlobal(bufferSize);
				structure.dwFlags = 0;
				IntPtr intPtr = Marshal.AllocHGlobal(cb);
				Marshal.StructureToPtr(structure, intPtr, fDeleteOld: false);
				MmException.Try(MidiInterop.midiInPrepareHeader(hMidiIn, intPtr, Marshal.SizeOf(typeof(MidiInterop.MIDIHDR))), "midiInPrepareHeader");
				MmException.Try(MidiInterop.midiInAddBuffer(hMidiIn, intPtr, Marshal.SizeOf(typeof(MidiInterop.MIDIHDR))), "midiInAddBuffer");
				SysexBufferHeaders[i] = intPtr;
			}
		}

		private void Callback(IntPtr midiInHandle, MidiInterop.MidiInMessage message, IntPtr userData, IntPtr messageParameter1, IntPtr messageParameter2)
		{
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			switch (message)
			{
			case MidiInterop.MidiInMessage.Data:
				if (this.MessageReceived != null)
				{
					this.MessageReceived(this, new MidiInMessageEventArgs(messageParameter1.ToInt32(), messageParameter2.ToInt32()));
				}
				break;
			case MidiInterop.MidiInMessage.Error:
				if (this.ErrorReceived != null)
				{
					this.ErrorReceived(this, new MidiInMessageEventArgs(messageParameter1.ToInt32(), messageParameter2.ToInt32()));
				}
				break;
			case MidiInterop.MidiInMessage.LongData:
				if (this.SysexMessageReceived != null)
				{
					MidiInterop.MIDIHDR mIDIHDR = (MidiInterop.MIDIHDR)Marshal.PtrToStructure(messageParameter1, typeof(MidiInterop.MIDIHDR));
					byte[] array = new byte[mIDIHDR.dwBytesRecorded];
					Marshal.Copy(mIDIHDR.lpData, array, 0, mIDIHDR.dwBytesRecorded);
					if (array.Length != 0)
					{
						this.SysexMessageReceived(this, new MidiInSysexMessageEventArgs(array, messageParameter2.ToInt32()));
					}
					if (!disposeIsRunning)
					{
						MidiInterop.midiInAddBuffer(hMidiIn, messageParameter1, Marshal.SizeOf(typeof(MidiInterop.MIDIHDR)));
					}
				}
				break;
			case MidiInterop.MidiInMessage.Open:
			case MidiInterop.MidiInMessage.Close:
			case MidiInterop.MidiInMessage.LongError:
			case (MidiInterop.MidiInMessage)967:
			case (MidiInterop.MidiInMessage)968:
			case (MidiInterop.MidiInMessage)969:
			case (MidiInterop.MidiInMessage)970:
			case (MidiInterop.MidiInMessage)971:
			case MidiInterop.MidiInMessage.MoreData:
				break;
			}
		}

		public static MidiInCapabilities DeviceInfo(int midiInDeviceNumber)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			MidiInCapabilities capabilities = default(MidiInCapabilities);
			int size = Marshal.SizeOf(capabilities);
			MmException.Try(MidiInterop.midiInGetDevCaps((IntPtr)midiInDeviceNumber, out capabilities, size), "midiInGetDevCaps");
			return capabilities;
		}

		protected virtual void Dispose(bool disposing)
		{
			//IL_00a8: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			if (!disposed)
			{
				disposeIsRunning = true;
				if (SysexBufferHeaders.Length != 0)
				{
					MmException.Try(MidiInterop.midiInReset(hMidiIn), "midiInReset");
					IntPtr[] sysexBufferHeaders = SysexBufferHeaders;
					foreach (IntPtr intPtr in sysexBufferHeaders)
					{
						MidiInterop.MIDIHDR obj = (MidiInterop.MIDIHDR)Marshal.PtrToStructure(intPtr, typeof(MidiInterop.MIDIHDR));
						MmException.Try(MidiInterop.midiInUnprepareHeader(hMidiIn, intPtr, Marshal.SizeOf(typeof(MidiInterop.MIDIHDR))), "midiInPrepareHeader");
						Marshal.FreeHGlobal(obj.lpData);
						Marshal.FreeHGlobal(intPtr);
					}
					SysexBufferHeaders = new IntPtr[0];
				}
				MidiInterop.midiInClose(hMidiIn);
			}
			disposed = true;
			disposeIsRunning = false;
		}

		~MidiIn()
		{
			Dispose(disposing: false);
		}
	}
	[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
	public struct MidiInCapabilities
	{
		private ushort manufacturerId;

		private ushort productId;

		private uint driverVersion;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
		private string productName;

		private int support;

		private const int MaxProductNameLength = 32;

		public Manufacturers Manufacturer => (Manufacturers)manufacturerId;

		public int ProductId => productId;

		public string ProductName => productName;
	}
	public class MidiInMessageEventArgs : EventArgs
	{
		public int RawMessage { get; private set; }

		public MidiEvent MidiEvent { get; private set; }

		public int Timestamp { get; private set; }

		public MidiInMessageEventArgs(int message, int timestamp)
		{
			RawMessage = message;
			Timestamp = timestamp;
			try
			{
				MidiEvent = MidiEvent.FromRawMessage(message);
			}
			catch (Exception)
			{
			}
		}
	}
	public class MidiInSysexMessageEventArgs : EventArgs
	{
		public byte[] SysexBytes { get; private set; }

		public int Timestamp { get; private set; }

		public MidiInSysexMessageEventArgs(byte[] sysexBytes, int timestamp)
		{
			SysexBytes = sysexBytes;
			Timestamp = timestamp;
		}
	}
	internal class MidiInterop
	{
		public enum MidiInMessage
		{
			Open = 961,
			Close = 962,
			Data = 963,
			LongData = 964,
			Error = 965,
			LongError = 966,
			MoreData = 972
		}

		public enum MidiOutMessage
		{
			Open = 967,
			Close,
			Done
		}

		public delegate void MidiInCallback(IntPtr midiInHandle, MidiInMessage message, IntPtr userData, IntPtr messageParameter1, IntPtr messageParameter2);

		public delegate void MidiOutCallback(IntPtr midiInHandle, MidiOutMessage message, IntPtr userData, IntPtr messageParameter1, IntPtr messageParameter2);

		public struct MMTIME
		{
			public int wType;

			public int u;
		}

		public struct MIDIEVENT
		{
			public int dwDeltaTime;

			public int dwStreamID;

			public int dwEvent;

			[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
			public int dwParms;
		}

		public struct MIDIHDR
		{
			public IntPtr lpData;

			public int dwBufferLength;

			public int dwBytesRecorded;

			public IntPtr dwUser;

			public int dwFlags;

			public IntPtr lpNext;

			public IntPtr reserved;

			public int dwOffset;

			[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
			public IntPtr[] dwReserved;
		}

		public struct MIDIPROPTEMPO
		{
			public int cbStruct;

			public int dwTempo;
		}

		public const int CALLBACK_FUNCTION = 196608;

		public const int CALLBACK_NULL = 0;

		[DllImport("winmm.dll")]
		public static extern MmResult midiConnect(IntPtr hMidiIn, IntPtr hMidiOut, IntPtr pReserved);

		[DllImport("winmm.dll")]
		public static extern MmResult midiDisconnect(IntPtr hMidiIn, IntPtr hMidiOut, IntPtr pReserved);

		[DllImport("winmm.dll")]
		public static extern MmResult midiInAddBuffer(IntPtr hMidiIn, IntPtr lpMidiInHdr, int uSize);

		[DllImport("winmm.dll")]
		public static extern MmResult midiInClose(IntPtr hMidiIn);

		[DllImport("winmm.dll", CharSet = CharSet.Auto)]
		public static extern MmResult midiInGetDevCaps(IntPtr deviceId, out MidiInCapabilities capabilities, int size);

		[DllImport("winmm.dll")]
		public static extern MmResult midiInGetErrorText(int err, string lpText, int uSize);

		[DllImport("winmm.dll")]
		public static extern MmResult midiInGetID(IntPtr hMidiIn, out int lpuDeviceId);

		[DllImport("winmm.dll")]
		public static extern int midiInGetNumDevs();

		[DllImport("winmm.dll")]
		public static extern MmResult midiInMessage(IntPtr hMidiIn, int msg, IntPtr dw1, IntPtr dw2);

		[DllImport("winmm.dll")]
		public static extern MmResult midiInOpen(out IntPtr hMidiIn, IntPtr uDeviceID, MidiInCallback callback, IntPtr dwInstance, int dwFlags);

		[DllImport("winmm.dll", EntryPoint = "midiInOpen")]
		public static extern MmResult midiInOpenWindow(out IntPtr hMidiIn, IntPtr uDeviceID, IntPtr callbackWindowHandle, IntPtr dwInstance, int dwFlags);

		[DllImport("winmm.dll")]
		public static extern MmResult midiInPrepareHeader(IntPtr hMidiIn, IntPtr lpMidiInHdr, int uSize);

		[DllImport("winmm.dll")]
		public static extern MmResult midiInReset(IntPtr hMidiIn);

		[DllImport("winmm.dll")]
		public static extern MmResult midiInStart(IntPtr hMidiIn);

		[DllImport("winmm.dll")]
		public static extern MmResult midiInStop(IntPtr hMidiIn);

		[DllImport("winmm.dll")]
		public static extern MmResult midiInUnprepareHeader(IntPtr hMidiIn, IntPtr lpMidiInHdr, int uSize);

		[DllImport("winmm.dll")]
		public static extern MmResult midiOutCacheDrumPatches(IntPtr hMidiOut, int uPatch, IntPtr lpKeyArray, int uFlags);

		[DllImport("winmm.dll")]
		public static extern MmResult midiOutCachePatches(IntPtr hMidiOut, int uBank, IntPtr lpPatchArray, int uFlags);

		[DllImport("winmm.dll")]
		public static extern MmResult midiOutClose(IntPtr hMidiOut);

		[DllImport("winmm.dll", CharSet = CharSet.Auto)]
		public static extern MmResult midiOutGetDevCaps(IntPtr deviceNumber, out MidiOutCapabilities caps, int uSize);

		[DllImport("winmm.dll")]
		public static extern MmResult midiOutGetErrorText(IntPtr err, string lpText, int uSize);

		[DllImport("winmm.dll")]
		public static extern MmResult midiOutGetID(IntPtr hMidiOut, out int lpuDeviceID);

		[DllImport("winmm.dll")]
		public static extern int midiOutGetNumDevs();

		[DllImport("winmm.dll")]
		public static extern MmResult midiOutGetVolume(IntPtr uDeviceID, ref int lpdwVolume);

		[DllImport("winmm.dll")]
		public static extern MmResult midiOutLongMsg(IntPtr hMidiOut, ref MIDIHDR lpMidiOutHdr, int uSize);

		[DllImport("winmm.dll")]
		public static extern MmResult midiOutMessage(IntPtr hMidiOut, int msg, IntPtr dw1, IntPtr dw2);

		[DllImport("winmm.dll")]
		public static extern MmResult midiOutOpen(out IntPtr lphMidiOut, IntPtr uDeviceID, MidiOutCallback dwCallback, IntPtr dwInstance, int dwFlags);

		[DllImport("winmm.dll")]
		public static extern MmResult midiOutPrepareHeader(IntPtr hMidiOut, ref MIDIHDR lpMidiOutHdr, int uSize);

		[DllImport("winmm.dll")]
		public static extern MmResult midiOutReset(IntPtr hMidiOut);

		[DllImport("winmm.dll")]
		public static extern MmResult midiOutSetVolume(IntPtr hMidiOut, int dwVolume);

		[DllImport("winmm.dll")]
		public static extern MmResult midiOutShortMsg(IntPtr hMidiOut, int dwMsg);

		[DllImport("winmm.dll")]
		public static extern MmResult midiOutUnprepareHeader(IntPtr hMidiOut, ref MIDIHDR lpMidiOutHdr, int uSize);

		[DllImport("winmm.dll")]
		public static extern MmResult midiStreamClose(IntPtr hMidiStream);

		[DllImport("winmm.dll")]
		public static extern MmResult midiStreamOpen(out IntPtr hMidiStream, IntPtr puDeviceID, int cMidi, IntPtr dwCallback, IntPtr dwInstance, int fdwOpen);

		[DllImport("winmm.dll")]
		public static extern MmResult midiStreamOut(IntPtr hMidiStream, ref MIDIHDR pmh, int cbmh);

		[DllImport("winmm.dll")]
		public static extern MmResult midiStreamPause(IntPtr hMidiStream);

		[DllImport("winmm.dll")]
		public static extern MmResult midiStreamPosition(IntPtr hMidiStream, ref MMTIME lpmmt, int cbmmt);

		[DllImport("winmm.dll")]
		public static extern MmResult midiStreamProperty(IntPtr hMidiStream, IntPtr lppropdata, int dwProperty);

		[DllImport("winmm.dll")]
		public static extern MmResult midiStreamRestart(IntPtr hMidiStream);

		[DllImport("winmm.dll")]
		public static extern MmResult midiStreamStop(IntPtr hMidiStream);
	}
	public class MidiMessage
	{
		private int rawData;

		public int RawData => rawData;

		public MidiMessage(int status, int data1, int data2)
		{
			rawData = status + (data1 << 8) + (data2 << 16);
		}

		public MidiMessage(int rawData)
		{
			this.rawData = rawData;
		}

		public static MidiMessage StartNote(int note, int volume, int channel)
		{
			ValidateNoteParameters(note, volume, channel);
			return new MidiMessage(144 + channel - 1, note, volume);
		}

		private static void ValidateNoteParameters(int note, int volume, int channel)
		{
			ValidateChannel(channel);
			if (note < 0 || note > 127)
			{
				throw new ArgumentOutOfRangeException("note", "Note number must be in the range 0-127");
			}
			if (volume < 0 || volume > 127)
			{
				throw new ArgumentOutOfRangeException("volume", "Velocity must be in the range 0-127");
			}
		}

		private static void ValidateChannel(int channel)
		{
			if (channel < 1 || channel > 16)
			{
				throw new ArgumentOutOfRangeException("channel", channel, $"Channel must be 1-16 (Got {channel})");
			}
		}

		public static MidiMessage StopNote(int note, int volume, int channel)
		{
			ValidateNoteParameters(note, volume, channel);
			return new MidiMessage(128 + channel - 1, note, volume);
		}

		public static MidiMessage ChangePatch(int patch, int channel)
		{
			ValidateChannel(channel);
			return new MidiMessage(192 + channel - 1, patch, 0);
		}

		public static MidiMessage ChangeControl(int controller, int value, int channel)
		{
			ValidateChannel(channel);
			return new MidiMessage(176 + channel - 1, controller, value);
		}
	}
	public class MidiOut : IDisposable
	{
		private IntPtr hMidiOut = IntPtr.Zero;

		private bool disposed;

		private MidiInterop.MidiOutCallback callback;

		public static int NumberOfDevices => MidiInterop.midiOutGetNumDevs();

		public int Volume
		{
			get
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				int lpdwVolume = 0;
				MmException.Try(MidiInterop.midiOutGetVolume(hMidiOut, ref lpdwVolume), "midiOutGetVolume");
				return lpdwVolume;
			}
			set
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				MmException.Try(MidiInterop.midiOutSetVolume(hMidiOut, value), "midiOutSetVolume");
			}
		}

		public static MidiOutCapabilities DeviceInfo(int midiOutDeviceNumber)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			MidiOutCapabilities caps = default(MidiOutCapabilities);
			int uSize = Marshal.SizeOf(caps);
			MmException.Try(MidiInterop.midiOutGetDevCaps((IntPtr)midiOutDeviceNumber, out caps, uSize), "midiOutGetDevCaps");
			return caps;
		}

		public MidiOut(int deviceNo)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			callback = Callback;
			MmException.Try(MidiInterop.midiOutOpen(out hMidiOut, (IntPtr)deviceNo, callback, IntPtr.Zero, 196608), "midiOutOpen");
		}

		public void Close()
		{
			Dispose();
		}

		public void Dispose()
		{
			GC.KeepAlive(callback);
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}

		public void Reset()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			MmException.Try(MidiInterop.midiOutReset(hMidiOut), "midiOutReset");
		}

		public void SendDriverMessage(int message, int param1, int param2)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			MmException.Try(MidiInterop.midiOutMessage(hMidiOut, message, (IntPtr)param1, (IntPtr)param2), "midiOutMessage");
		}

		public void Send(int message)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			MmException.Try(MidiInterop.midiOutShortMsg(hMidiOut, message), "midiOutShortMsg");
		}

		protected virtual void Dispose(bool disposing)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (!disposed)
			{
				MidiInterop.midiOutClose(hMidiOut);
			}
			disposed = true;
		}

		private void Callback(IntPtr midiInHandle, MidiInterop.MidiOutMessage message, IntPtr userData, IntPtr messageParameter1, IntPtr messageParameter2)
		{
		}

		public void SendBuffer(byte[] byteBuffer)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			MidiInterop.MIDIHDR lpMidiOutHdr = default(MidiInterop.MIDIHDR);
			lpMidiOutHdr.lpData = Marshal.AllocHGlobal(byteBuffer.Length);
			Marshal.Copy(byteBuffer, 0, lpMidiOutHdr.lpData, byteBuffer.Length);
			lpMidiOutHdr.dwBufferLength = byteBuffer.Length;
			lpMidiOutHdr.dwBytesRecorded = byteBuffer.Length;
			int uSize = Marshal.SizeOf(lpMidiOutHdr);
			MidiInterop.midiOutPrepareHeader(hMidiOut, ref lpMidiOutHdr, uSize);
			if ((int)MidiInterop.midiOutLongMsg(hMidiOut, ref lpMidiOutHdr, uSize) != 0)
			{
				MidiInterop.midiOutUnprepareHeader(hMidiOut, ref lpMidiOutHdr, uSize);
			}
			Marshal.FreeHGlobal(lpMidiOutHdr.lpData);
		}

		~MidiOut()
		{
			Dispose(disposing: false);
		}
	}
	[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
	public struct MidiOutCapabilities
	{
		[Flags]
		private enum MidiOutCapabilityFlags
		{
			Volume = 1,
			LeftRightVolume = 2,
			PatchCaching = 4,
			Stream = 8
		}

		private short manufacturerId;

		private short productId;

		private int driverVersion;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
		private string productName;

		private short wTechnology;

		private short wVoices;

		private short wNotes;

		private ushort wChannelMask;

		private MidiOutCapabilityFlags dwSupport;

		private const int MaxProductNameLength = 32;

		public Manufacturers Manufacturer => (Manufacturers)manufacturerId;

		public short ProductId => productId;

		public string ProductName => productName;

		public int Voices => wVoices;

		public int Notes => wNotes;

		public bool SupportsAllChannels => wChannelMask == ushort.MaxValue;

		public bool SupportsPatchCaching => (dwSupport & MidiOutCapabilityFlags.PatchCaching) != 0;

		public bool SupportsSeparateLeftAndRightVolume => (dwSupport & MidiOutCapabilityFlags.LeftRightVolume) != 0;

		public bool SupportsMidiStreamOut => (dwSupport & MidiOutCapabilityFlags.Stream) != 0;

		public bool SupportsVolumeControl => (dwSupport & MidiOutCapabilityFlags.Volume) != 0;

		public MidiOutTechnology Technology => (MidiOutTechnology)wTechnology;

		public bool SupportsChannel(int channel)
		{
			return (wChannelMask & (1 << channel - 1)) > 0;
		}
	}
	public enum MidiOutTechnology
	{
		MidiPort = 1,
		Synth,
		SquareWaveSynth,
		FMSynth,
		MidiMapper,
		WaveTableSynth,
		SoftwareSynth
	}
	public class NoteEvent : MidiEvent
	{
		private int noteNumber;

		private int velocity;

		private static readonly string[] NoteNames = new string[12]
		{
			"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A",
			"A#", "B"
		};

		public virtual int NoteNumber
		{
			get
			{
				return noteNumber;
			}
			set
			{
				if (value < 0 || value > 127)
				{
					throw new ArgumentOutOfRangeException("value", "Note number must be in the range 0-127");
				}
				noteNumber = value;
			}
		}

		public int Velocity
		{
			get
			{
				return velocity;
			}
			set
			{
				if (value < 0 || value > 127)
				{
					throw new ArgumentOutOfRangeException("value", "Velocity must be in the range 0-127");
				}
				velocity = value;
			}
		}

		public string NoteName
		{
			get
			{
				if (Channel == 16 || Channel == 10)
				{
					return noteNumber switch
					{
						35 => "Acoustic Bass Drum", 
						36 => "Bass Drum 1", 
						37 => "Side Stick", 
						38 => "Acoustic Snare", 
						39 => "Hand Clap", 
						40 => "Electric Snare", 
						41 => "Low Floor Tom", 
						42 => "Closed Hi-Hat", 
						43 => "High Floor Tom", 
						44 => "Pedal Hi-Hat", 
						45 => "Low Tom", 
						46 => "Open Hi-Hat", 
						47 => "Low-Mid Tom", 
						48 => "Hi-Mid Tom", 
						49 => "Crash Cymbal 1", 
						50 => "High Tom", 
						51 => "Ride Cymbal 1", 
						52 => "Chinese Cymbal", 
						53 => "Ride Bell", 
						54 => "Tambourine", 
						55 => "Splash Cymbal", 
						56 => "Cowbell", 
						57 => "Crash Cymbal 2", 
						58 => "Vibraslap", 
						59 => "Ride Cymbal 2", 
						60 => "Hi Bongo", 
						61 => "Low Bongo", 
						62 => "Mute Hi Conga", 
						63 => "Open Hi Conga", 
						64 => "Low Conga", 
						65 => "High Timbale", 
						66 => "Low Timbale", 
						67 => "High Agogo", 
						68 => "Low Agogo", 
						69 => "Cabasa", 
						70 => "Maracas", 
						71 => "Short Whistle", 
						72 => "Long Whistle", 
						73 => "Short Guiro", 
						74 => "Long Guiro", 
						75 => "Claves", 
						76 => "Hi Wood Block", 
						77 => "Low Wood Block", 
						78 => "Mute Cuica", 
						79 => "Open Cuica", 
						80 => "Mute Triangle", 
						81 => "Open Triangle", 
						_ => $"Drum {noteNumber}", 
					};
				}
				int num = noteNumber / 12;
				return $"{NoteNames[noteNumber % 12]}{num}";
			}
		}

		public NoteEvent(BinaryReader br)
		{
			NoteNumber = br.ReadByte();
			velocity = br.ReadByte();
			if (velocity > 127)
			{
				velocity = 127;
			}
		}

		public NoteEvent(long absoluteTime, int channel, MidiCommandCode commandCode, int noteNumber, int velocity)
			: base(absoluteTime, channel, commandCode)
		{
			NoteNumber = noteNumber;
			Velocity = velocity;
		}

		public override int GetAsShortMessage()
		{
			return base.GetAsShortMessage() + (noteNumber << 8) + (velocity << 16);
		}

		public override string ToString()
		{
			return $"{base.ToString()} {NoteName} Vel:{Velocity}";
		}

		public override void Export(ref long absoluteTime, BinaryWriter writer)
		{
			base.Export(ref absoluteTime, writer);
			writer.Write((byte)noteNumber);
			writer.Write((byte)velocity);
		}
	}
	public class NoteOnEvent : NoteEvent
	{
		private NoteEvent offEvent;

		public NoteEvent OffEvent
		{
			get
			{
				return offEvent;
			}
			set
			{
				if (!MidiEvent.IsNoteOff(value))
				{
					throw new ArgumentException("OffEvent must be a valid MIDI note off event");
				}
				if (value.NoteNumber != NoteNumber)
				{
					throw new ArgumentException("Note Off Event must be for the same note number");
				}
				if (value.Channel != Channel)
				{
					throw new ArgumentException("Note Off Event must be for the same channel");
				}
				offEvent = value;
			}
		}

		public override int NoteNumber
		{
			get
			{
				return base.NoteNumber;
			}
			set
			{
				base.NoteNumber = value;
				if (OffEvent != null)
				{
					OffEvent.NoteNumber = NoteNumber;
				}
			}
		}

		public override int Channel
		{
			get
			{
				return base.Channel;
			}
			set
			{
				base.Channel = value;
				if (OffEvent != null)
				{
					OffEvent.Channel = Channel;
				}
			}
		}

		public int NoteLength
		{
			get
			{
				return (int)(offEvent.AbsoluteTime - base.AbsoluteTime);
			}
			set
			{
				if (value < 0)
				{
					throw new ArgumentException("NoteLength must be 0 or greater");
				}
				offEvent.AbsoluteTime = base.AbsoluteTime + value;
			}
		}

		public NoteOnEvent(BinaryReader br)
			: base(br)
		{
		}

		public NoteOnEvent(long absoluteTime, int channel, int noteNumber, int velocity, int duration)
			: base(absoluteTime, channel, MidiCommandCode.NoteOn, noteNumber, velocity)
		{
			OffEvent = new NoteEvent(absoluteTime, channel, MidiCommandCode.NoteOff, noteNumber, 0);
			NoteLength = duration;
		}

		public override MidiEvent Clone()
		{
			return new NoteOnEvent(base.AbsoluteTime, Channel, NoteNumber, base.Velocity, NoteLength);
		}

		public override string ToString()
		{
			if (base.Velocity == 0 && OffEvent == null)
			{
				return $"{base.ToString()} (Note Off)";
			}
			return string.Format("{0} Len: {1}", base.ToString(), (OffEvent == null) ? "?" : NoteLength.ToString());
		}
	}
	public class PatchChangeEvent : MidiEvent
	{
		private byte patch;

		private static readonly string[] patchNames = new string[128]
		{
			"Acoustic Grand", "Bright Acoustic", "Electric Grand", "Honky-Tonk", "Electric Piano 1", "Electric Piano 2", "Harpsichord", "Clav", "Celesta", "Glockenspiel",
			"Music Box", "Vibraphone", "Marimba", "Xylophone", "Tubular Bells", "Dulcimer", "Drawbar Organ", "Percussive Organ", "Rock Organ", "Church Organ",
			"Reed Organ", "Accoridan", "Harmonica", "Tango Accordian", "Acoustic Guitar(nylon)", "Acoustic Guitar(steel)", "Electric Guitar(jazz)", "Electric Guitar(clean)", "Electric Guitar(muted)", "Overdriven Guitar",
			"Distortion Guitar", "Guitar Harmonics", "Acoustic Bass", "Electric Bass(finger)", "Electric Bass(pick)", "Fretless Bass", "Slap Bass 1", "Slap Bass 2", "Synth Bass 1", "Synth Bass 2",
			"Violin", "Viola", "Cello", "Contrabass", "Tremolo Strings", "Pizzicato Strings", "Orchestral Strings", "Timpani", "String Ensemble 1", "String Ensemble 2",
			"SynthStrings 1", "SynthStrings 2", "Choir Aahs", "Voice Oohs", "Synth Voice", "Orchestra Hit", "Trumpet", "Trombone", "Tuba", "Muted Trumpet",
			"French Horn", "Brass Section", "SynthBrass 1", "SynthBrass 2", "Soprano Sax", "Alto Sax", "Tenor Sax", "Baritone Sax", "Oboe", "English Horn",
			"Bassoon", "Clarinet", "Piccolo", "Flute", "Recorder", "Pan Flute", "Blown Bottle", "Skakuhachi", "Whistle", "Ocarina",
			"Lead 1 (square)", "Lead 2 (sawtooth)", "Lead 3 (calliope)", "Lead 4 (chiff)", "Lead 5 (charang)", "Lead 6 (voice)", "Lead 7 (fifths)", "Lead 8 (bass+lead)", "Pad 1 (new age)", "Pad 2 (warm)",
			"Pad 3 (polysynth)", "Pad 4 (choir)", "Pad 5 (bowed)", "Pad 6 (metallic)", "Pad 7 (halo)", "Pad 8 (sweep)", "FX 1 (rain)", "FX 2 (soundtrack)", "FX 3 (crystal)", "FX 4 (atmosphere)",
			"FX 5 (brightness)", "FX 6 (goblins)", "FX 7 (echoes)", "FX 8 (sci-fi)", "Sitar", "Banjo", "Shamisen", "Koto", "Kalimba", "Bagpipe",
			"Fiddle", "Shanai", "Tinkle Bell", "Agogo", "Steel Drums", "Woodblock", "Taiko Drum", "Melodic Tom", "Synth Drum", "Reverse Cymbal",
			"Guitar Fret Noise", "Breath Noise", "Seashore", "Bird Tweet", "Telephone Ring", "Helicopter", "Applause", "Gunshot"
		};

		public int Patch
		{
			get
			{
				return patch;
			}
			set
			{
				if (value < 0 || value > 127)
				{
					throw new ArgumentOutOfRangeException("value", "Patch number must be in the range 0-127");
				}
				patch = (byte)value;
			}
		}

		public static string GetPatchName(int patchNumber)
		{
			return patchNames[patchNumber];
		}

		public PatchChangeEvent(BinaryReader br)
		{
			patch = br.ReadByte();
			if ((patch & 0x80u) != 0)
			{
				throw new FormatException("Invalid patch");
			}
		}

		public PatchChangeEvent(long absoluteTime, int channel, int patchNumber)
			: base(absoluteTime, channel, MidiCommandCode.PatchChange)
		{
			Patch = patchNumber;
		}

		public override string ToString()
		{
			return $"{base.ToString()} {GetPatchName(patch)}";
		}

		public override int GetAsShortMessage()
		{
			return base.GetAsShortMessage() + (patch << 8);
		}

		public override void Export(ref long absoluteTime, BinaryWriter writer)
		{
			base.Export(ref absoluteTime, writer);
			writer.Write(patch);
		}
	}
	public class PitchWheelChangeEvent : MidiEvent
	{
		private int pitch;

		public int Pitch
		{
			get
			{
				return pitch;
			}
			set
			{
				if (value < 0 || value >= 16384)
				{
					throw new ArgumentOutOfRangeException("value", "Pitch value must be in the range 0 - 0x3FFF");
				}
				pitch = value;
			}
		}

		public PitchWheelChangeEvent(BinaryReader br)
		{
			byte b = br.ReadByte();
			byte b2 = br.ReadByte();
			if ((b & 0x80u) != 0)
			{
				throw new FormatException("Invalid pitchwheelchange byte 1");
			}
			if ((b2 & 0x80u) != 0)
			{
				throw new FormatException("Invalid pitchwheelchange byte 2");
			}
			pitch = b + (b2 << 7);
		}

		public PitchWheelChangeEvent(long absoluteTime, int channel, int pitchWheel)
			: base(absoluteTime, channel, MidiCommandCode.PitchWheelChange)
		{
			Pitch = pitchWheel;
		}

		public override string ToString()
		{
			return $"{base.ToString()} Pitch {pitch} ({pitch - 8192})";
		}

		public override int GetAsShortMessage()
		{
			return base.GetAsShortMessage() + ((pitch & 0x7F) << 8) + (((pitch >> 7) & 0x7F) << 16);
		}

		public override void Export(ref long absoluteTime, BinaryWriter writer)
		{
			base.Export(ref absoluteTime, writer);
			writer.Write((byte)((uint)pitch & 0x7Fu));
			writer.Write((byte)((uint)(pitch >> 7) & 0x7Fu));
		}
	}
	public class RawMetaEvent : MetaEvent
	{
		public byte[] Data { get; set; }

		public RawMetaEvent(MetaEventType metaEventType, long absoluteTime, byte[] data)
			: base(metaEventType, (data != null) ? data.Length : 0, absoluteTime)
		{
			Data = data;
		}

		public override MidiEvent Clone()
		{
			return new RawMetaEvent(base.MetaEventType, base.AbsoluteTime, (byte[])Data?.Clone());
		}

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder().Append(base.ToString());
			byte[] data = Data;
			foreach (byte b in data)
			{
				stringBuilder.AppendFormat(" {0:X2}", b);
			}
			return stringBuilder.ToString();
		}

		public override void Export(ref long absoluteTime, BinaryWriter writer)
		{
			base.Export(ref absoluteTime, writer);
			if (Data != null)
			{
				writer.Write(Data, 0, Data.Length);
			}
		}
	}
	public class SequencerSpecificEvent : MetaEvent
	{
		private byte[] data;

		public byte[] Data
		{
			get
			{
				return data;
			}
			set
			{
				data = value;
				metaDataLength = data.Length;
			}
		}

		public SequencerSpecificEvent(BinaryReader br, int length)
		{
			data = br.ReadBytes(length);
		}

		public SequencerSpecificEvent(byte[] data, long absoluteTime)
			: base(MetaEventType.SequencerSpecific, data.Length, absoluteTime)
		{
			this.data = data;
		}

		public override MidiEvent Clone()
		{
			return new SequencerSpecificEvent((byte[])data.Clone(), base.AbsoluteTime);
		}

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(base.ToString());
			stringBuilder.Append(" ");
			byte[] array = data;
			foreach (byte b in array)
			{
				stringBuilder.AppendFormat("{0:X2} ", b);
			}
			stringBuilder.Length--;
			return stringBuilder.ToString();
		}

		public override void Export(ref long absoluteTime, BinaryWriter writer)
		{
			base.Export(ref absoluteTime, writer);
			writer.Write(data);
		}
	}
	public class SmpteOffsetEvent : MetaEvent
	{
		private readonly byte hours;

		private readonly byte minutes;

		private readonly byte seconds;

		private readonly byte frames;

		private readonly byte subFrames;

		public int Hours => hours;

		public int Minutes => minutes;

		public int Seconds => seconds;

		public int Frames => frames;

		public int SubFrames => subFrames;

		public SmpteOffsetEvent(byte hours, byte minutes, byte seconds, byte frames, byte subFrames)
		{
			this.hours = hours;
			this.minutes = minutes;
			this.seconds = seconds;
			this.frames = frames;
			this.subFrames = subFrames;
		}

		public SmpteOffsetEvent(BinaryReader br, int length)
		{
			if (length != 5)
			{
				throw new FormatException($"Invalid SMPTE Offset length: Got {length}, expected 5");
			}
			hours = br.ReadByte();
			minutes = br.ReadByte();
			seconds = br.ReadByte();
			frames = br.ReadByte();
			subFrames = br.ReadByte();
		}

		public override MidiEvent Clone()
		{
			return (SmpteOffsetEvent)MemberwiseClone();
		}

		public override string ToString()
		{
			return $"{base.ToString()} {hours}:{minutes}:{seconds}:{frames}:{subFrames}";
		}

		public override void Export(ref long absoluteTime, BinaryWriter writer)
		{
			base.Export(ref absoluteTime, writer);
			writer.Write(hours);
			writer.Write(minutes);
			writer.Write(seconds);
			writer.Write(frames);
			writer.Write(subFrames);
		}
	}
	public class SysexEvent : MidiEvent
	{
		private byte[] data;

		public static SysexEvent ReadSysexEvent(BinaryReader br)
		{
			SysexEvent sysexEvent = new SysexEvent();
			List<byte> list = new List<byte>();
			bool flag = true;
			while (flag)
			{
				byte b = br.ReadByte();
				if (b == 247)
				{
					flag = false;
				}
				else
				{
					list.Add(b);
				}
			}
			sysexEvent.data = list.ToArray();
			return sysexEvent;
		}

		public override MidiEvent Clone()
		{
			return new SysexEvent
			{
				data = (byte[])data?.Clone()
			};
		}

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			byte[] array = data;
			foreach (byte b in array)
			{
				stringBuilder.AppendFormat("{0:X2} ", b);
			}
			return $"{base.AbsoluteTime} Sysex: {data.Length} bytes\r\n{stringBuilder.ToString()}";
		}

		public override void Export(ref long absoluteTime, BinaryWriter writer)
		{
			base.Export(ref absoluteTime, writer);
			writer.Write(data, 0, data.Length);
			writer.Write((byte)247);
		}
	}
	public class TempoEvent : MetaEvent
	{
		private int microsecondsPerQuarterNote;

		public int MicrosecondsPerQuarterNote
		{
			get
			{
				return microsecondsPerQuarterNote;
			}
			set
			{
				microsecondsPerQuarterNote = value;
			}
		}

		public double Tempo
		{
			get
			{
				return 60000000.0 / (double)microsecondsPerQuarterNote;
			}
			set
			{
				microsecondsPerQuarterNote = (int)(60000000.0 / value);
			}
		}

		public TempoEvent(BinaryReader br, int length)
		{
			if (length != 3)
			{
				throw new FormatException("Invalid tempo length");
			}
			microsecondsPerQuarterNote = (br.ReadByte() << 16) + (br.ReadByte() << 8) + br.ReadByte();
		}

		public TempoEvent(int microsecondsPerQuarterNote, long absoluteTime)
			: base(MetaEventType.SetTempo, 3, absoluteTime)
		{
			this.microsecondsPerQuarterNote = microsecondsPerQuarterNote;
		}

		public override MidiEvent Clone()
		{
			return (TempoEvent)MemberwiseClone();
		}

		public override string ToString()
		{
			return string.Format("{0} {2}bpm ({1})", base.ToString(), microsecondsPerQuarterNote, 60000000 / microsecondsPerQuarterNote);
		}

		public override void Export(ref long absoluteTime, BinaryWriter writer)
		{
			base.Export(ref absoluteTime, writer);
			writer.Write((byte)((uint)(microsecondsPerQuarterNote >> 16) & 0xFFu));
			writer.Write((byte)((uint)(microsecondsPerQuarterNote >> 8) & 0xFFu));
			writer.Write((byte)((uint)microsecondsPerQuarterNote & 0xFFu));
		}
	}
	public class TextEvent : MetaEvent
	{
		private byte[] data;

		public string Text
		{
			get
			{
				return ((Encoding)(object)ByteEncoding.Instance).GetString(data);
			}
			set
			{
				Encoding instance = (Encoding)(object)ByteEncoding.Instance;
				data = instance.GetBytes(value);
				metaDataLength = data.Length;
			}
		}

		public byte[] Data
		{
			get
			{
				return data;
			}
			set
			{
				data = value;
				metaDataLength = data.Length;
			}
		}

		public TextEvent(BinaryReader br, int length)
		{
			data = br.ReadBytes(length);
		}

		public TextEvent(string text, MetaEventType metaEventType, long absoluteTime)
			: base(metaEventType, text.Length, absoluteTime)
		{
			Text = text;
		}

		public override MidiEvent Clone()
		{
			return (TextEvent)MemberwiseClone();
		}

		public override string ToString()
		{
			return $"{base.ToString()} {Text}";
		}

		public override void Export(ref long absoluteTime, BinaryWriter writer)
		{
			base.Export(ref absoluteTime, writer);
			writer.Write(data);
		}
	}
	public class TimeSignatureEvent : MetaEvent
	{
		private byte numerator;

		private byte denominator;

		private byte ticksInMetronomeClick;

		private byte no32ndNotesInQuarterNote;

		public int Numerator => numerator;

		public int Denominator => denominator;

		public int TicksInMetronomeClick => ticksInMetronomeClick;

		public int No32ndNotesInQuarterNote => no32ndNotesInQuarterNote;

		public string TimeSignature
		{
			get
			{
				string arg = $"Unknown ({denominator})";
				switch (denominator)
				{
				case 1:
					arg = "2";
					break;
				case 2:
					arg = "4";
					break;
				case 3:
					arg = "8";
					break;
				case 4:
					arg = "16";
					break;
				case 5:
					arg = "32";
					break;
				}
				return $"{numerator}/{arg}";
			}
		}

		public TimeSignatureEvent(BinaryReader br, int length)
		{
			if (length != 4)
			{
				throw new FormatException($"Invalid time signature length: Got {length}, expected 4");
			}
			numerator = br.ReadByte();
			denominator = br.ReadByte();
			ticksInMetronomeClick = br.ReadByte();
			no32ndNotesInQuarterNote = br.ReadByte();
		}

		public TimeSignatureEvent(long absoluteTime, int numerator, int denominator, int ticksInMetronomeClick, int no32ndNotesInQuarterNote)
			: base(MetaEventType.TimeSignature, 4, absoluteTime)
		{
			this.numerator = (byte)numerator;
			this.denominator = (byte)denominator;
			this.ticksInMetronomeClick = (byte)ticksInMetronomeClick;
			this.no32ndNotesInQuarterNote = (byte)no32ndNotesInQuarterNote;
		}

		public override MidiEvent Clone()
		{
			return (TimeSignatureEvent)MemberwiseClone();
		}

		public override string ToString()
		{
			return $"{base.ToString()} {TimeSignature} TicksInClick:{ticksInMetronomeClick} 32ndsInQuarterNote:{no32ndNotesInQuarterNote}";
		}

		public override void Export(ref long absoluteTime, BinaryWriter writer)
		{
			base.Export(ref absoluteTime, writer);
			writer.Write(numerator);
			writer.Write(denominator);
			writer.Write(ticksInMetronomeClick);
			writer.Write(no32ndNotesInQuarterNote);
		}
	}
	public class TrackSequenceNumberEvent : MetaEvent
	{
		private ushort sequenceNumber;

		public TrackSequenceNumberEvent(ushort sequenceNumber)
		{
			this.sequenceNumber = sequenceNumber;
		}

		public TrackSequenceNumberEvent(BinaryReader br, int length)
		{
			if (length != 2)
			{
				throw new FormatException("Invalid sequence number length");
			}
			sequenceNumber = (ushort)((br.ReadByte() << 8) + br.ReadByte());
		}

		public override MidiEvent Clone()
		{
			return (TrackSequenceNumberEvent)MemberwiseClone();
		}

		public override string ToString()
		{
			return $"{base.ToString()} {sequenceNumber}";
		}

		public override void Export(ref long absoluteTime, BinaryWriter writer)
		{
			base.Export(ref absoluteTime, writer);
			writer.Write((byte)((uint)(sequenceNumber >> 8) & 0xFFu));
			writer.Write((byte)(sequenceNumber & 0xFFu));
		}
	}
}
namespace NAudio.Utils
{
	internal class MergeSort
	{
		private static void Sort<T>(IList<T> list, int lowIndex, int highIndex, IComparer<T> comparer)
		{
			if (lowIndex >= highIndex)
			{
				return;
			}
			int num = (lowIndex + highIndex) / 2;
			Sort(list, lowIndex, num, comparer);
			Sort(list, num + 1, highIndex, comparer);
			int num2 = num;
			int num3 = num + 1;
			while (lowIndex <= num2 && num3 <= highIndex)
			{
				if (comparer.Compare(list[lowIndex], list[num3]) <= 0)
				{
					lowIndex++;
					continue;
				}
				T value = list[num3];
				for (int num4 = num3 - 1; num4 >= lowIndex; num4--)
				{
					list[num4 + 1] = list[num4];
				}
				list[lowIndex] = value;
				lowIndex++;
				num2++;
				num3++;
			}
		}

		public static void Sort<T>(IList<T> list) where T : IComparable<T>
		{
			Sort(list, 0, list.Count - 1, Comparer<T>.Default);
		}

		public static void Sort<T>(IList<T> list, IComparer<T> comparer)
		{
			Sort(list, 0, list.Count - 1, comparer);
		}
	}
}

Mods/RealRadio/NAudio.Wasapi.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using NAudio.CoreAudioApi;
using NAudio.CoreAudioApi.Interfaces;
using NAudio.Dmo;
using NAudio.Dmo.Effect;
using NAudio.MediaFoundation;
using NAudio.Utils;
using NAudio.Wasapi.CoreAudioApi;
using NAudio.Wasapi.CoreAudioApi.Interfaces;
using NAudio.Wave;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("Mark Heath")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("© Mark Heath 2023")]
[assembly: AssemblyFileVersion("2.2.1.0")]
[assembly: AssemblyInformationalVersion("2.2.1")]
[assembly: AssemblyProduct("NAudio.Wasapi")]
[assembly: AssemblyTitle("NAudio.Wasapi")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/naudio/NAudio")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.2.1.0")]
[module: UnverifiableCode]
namespace NAudio.MediaFoundation
{
	public static class AudioSubtypes
	{
		[FieldDescription("AAC")]
		public static readonly Guid MFAudioFormat_AAC = new Guid("00001610-0000-0010-8000-00aa00389b71");

		[FieldDescription("ADTS")]
		public static readonly Guid MFAudioFormat_ADTS = new Guid("00001600-0000-0010-8000-00aa00389b71");

		[FieldDescription("Dolby AC3 SPDIF")]
		public static readonly Guid MFAudioFormat_Dolby_AC3_SPDIF = new Guid("00000092-0000-0010-8000-00aa00389b71");

		[FieldDescription("DRM")]
		public static readonly Guid MFAudioFormat_DRM = new Guid("00000009-0000-0010-8000-00aa00389b71");

		[FieldDescription("DTS")]
		public static readonly Guid MFAudioFormat_DTS = new Guid("00000008-0000-0010-8000-00aa00389b71");

		[FieldDescription("IEEE floating-point")]
		public static readonly Guid MFAudioFormat_Float = new Guid("00000003-0000-0010-8000-00aa00389b71");

		[FieldDescription("MP3")]
		public static readonly Guid MFAudioFormat_MP3 = new Guid("00000055-0000-0010-8000-00aa00389b71");

		[FieldDescription("MPEG")]
		public static readonly Guid MFAudioFormat_MPEG = new Guid("00000050-0000-0010-8000-00aa00389b71");

		[FieldDescription("WMA 9 Voice codec")]
		public static readonly Guid MFAudioFormat_MSP1 = new Guid("0000000a-0000-0010-8000-00aa00389b71");

		[FieldDescription("PCM")]
		public static readonly Guid MFAudioFormat_PCM = new Guid("00000001-0000-0010-8000-00aa00389b71");

		[FieldDescription("WMA SPDIF")]
		public static readonly Guid MFAudioFormat_WMASPDIF = new Guid("00000164-0000-0010-8000-00aa00389b71");

		[FieldDescription("WMAudio Lossless")]
		public static readonly Guid MFAudioFormat_WMAudio_Lossless = new Guid("00000163-0000-0010-8000-00aa00389b71");

		[FieldDescription("Windows Media Audio")]
		public static readonly Guid MFAudioFormat_WMAudioV8 = new Guid("00000161-0000-0010-8000-00aa00389b71");

		[FieldDescription("Windows Media Audio Professional")]
		public static readonly Guid MFAudioFormat_WMAudioV9 = new Guid("00000162-0000-0010-8000-00aa00389b71");

		[FieldDescription("Dolby AC3")]
		public static readonly Guid MFAudioFormat_Dolby_AC3 = new Guid("e06d802c-db46-11cf-b4d1-00805f6cbbea");

		public static readonly Guid MFAudioFormat_FLAC = new Guid("0000f1ac-0000-0010-8000-00aa00389b71");

		public static readonly Guid MFAudioFormat_ALAC = new Guid("63616c61-0000-0010-8000-00aa00389b71");

		[FieldDescription("MPEG-4 and AAC Audio Types")]
		public static readonly Guid MEDIASUBTYPE_RAW_AAC1 = new Guid("000000ff-0000-0010-8000-00aa00389b71");

		[FieldDescription("Dolby Audio Types")]
		public static readonly Guid MEDIASUBTYPE_DVM = new Guid("00002000-0000-0010-8000-00aa00389b71");

		[FieldDescription("Dolby Audio Types")]
		public static readonly Guid MEDIASUBTYPE_DOLBY_DDPLUS = new Guid("a7fb87af-2d02-42fb-a4d4-05cd93843bdd");

		[FieldDescription("μ-law")]
		public static readonly Guid KSDATAFORMAT_SUBTYPE_MULAW = new Guid("00000007-0000-0010-8000-00aa00389b71");

		[FieldDescription("ADPCM")]
		public static readonly Guid KSDATAFORMAT_SUBTYPE_ADPCM = new Guid("00000002-0000-0010-8000-00aa00389b71");

		[FieldDescription("Dolby Digital Plus for HDMI")]
		public static readonly Guid KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_DIGITAL_PLUS = new Guid("0000000a-0cea-0010-8000-00aa00389b71");

		[FieldDescription("MSAudio1")]
		public static readonly Guid MEDIASUBTYPE_MSAUDIO1 = new Guid("00000160-0000-0010-8000-00aa00389b71");

		[FieldDescription("IMA ADPCM")]
		public static readonly Guid ImaAdpcm = new Guid("00000011-0000-0010-8000-00aa00389b71");

		[FieldDescription("WMSP2")]
		public static readonly Guid WMMEDIASUBTYPE_WMSP2 = new Guid("0000000b-0000-0010-8000-00aa00389b71");
	}
	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("7FEE9E9A-4A89-47a6-899C-B6A53A70FB67")]
	public interface IMFActivate : IMFAttributes
	{
		new void GetItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][Out] IntPtr pValue);

		new void GetItemType([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pType);

		new void CompareItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr value, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

		new void Compare([MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, int matchType, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

		new void GetUINT32([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int punValue);

		new void GetUINT64([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out long punValue);

		new void GetDouble([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out double pfValue);

		new void GetGUID([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out Guid pguidValue);

		new void GetStringLength([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcchLength);

		new void GetString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out][MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, int cchBufSize, out int pcchLength);

		new void GetAllocatedString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, out int pcchLength);

		new void GetBlobSize([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcbBlobSize);

		new void GetBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out][MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, int cbBufSize, out int pcbBlobSize);

		new void GetAllocatedBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out IntPtr ip, out int pcbSize);

		new void GetUnknown([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);

		new void SetItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr value);

		new void DeleteItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey);

		new void DeleteAllItems();

		new void SetUINT32([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, int unValue);

		new void SetUINT64([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, long unValue);

		new void SetDouble([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, double fValue);

		new void SetGUID([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPStruct)] Guid guidValue);

		new void SetString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPWStr)] string wszValue);

		new void SetBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, int cbBufSize);

		new void SetUnknown([MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.IUnknown)] object pUnknown);

		new void LockStore();

		new void UnlockStore();

		new void GetCount(out int pcItems);

		new void GetItemByIndex(int unIndex, out Guid pGuidKey, [In][Out] IntPtr pValue);

		new void CopyAllItems([In][MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest);

		void ActivateObject([In][MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppv);

		void ShutdownObject();

		void DetachObject();
	}
	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("2CD2D921-C447-44A7-A13C-4ADABFC247E3")]
	public interface IMFAttributes
	{
		void GetItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][Out] IntPtr pValue);

		void GetItemType([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pType);

		void CompareItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr value, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

		void Compare([MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, int matchType, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

		void GetUINT32([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int punValue);

		void GetUINT64([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out long punValue);

		void GetDouble([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out double pfValue);

		void GetGUID([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out Guid pguidValue);

		void GetStringLength([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcchLength);

		void GetString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out][MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, int cchBufSize, out int pcchLength);

		void GetAllocatedString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, out int pcchLength);

		void GetBlobSize([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcbBlobSize);

		void GetBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out][MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, int cbBufSize, out int pcbBlobSize);

		void GetAllocatedBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out IntPtr ip, out int pcbSize);

		void GetUnknown([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);

		void SetItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr Value);

		void DeleteItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey);

		void DeleteAllItems();

		void SetUINT32([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, int unValue);

		void SetUINT64([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, long unValue);

		void SetDouble([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, double fValue);

		void SetGUID([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPStruct)] Guid guidValue);

		void SetString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPWStr)] string wszValue);

		void SetBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, int cbBufSize);

		void SetUnknown([MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.IUnknown)] object pUnknown);

		void LockStore();

		void UnlockStore();

		void GetCount(out int pcItems);

		void GetItemByIndex(int unIndex, out Guid pGuidKey, [In][Out] IntPtr pValue);

		void CopyAllItems([In][MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest);
	}
	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("ad4c1b00-4bf7-422f-9175-756693d9130d")]
	public interface IMFByteStream
	{
		void GetCapabilities(ref int pdwCapabiities);

		void GetLength(ref long pqwLength);

		void SetLength(long qwLength);

		void GetCurrentPosition(ref long pqwPosition);

		void SetCurrentPosition(long qwPosition);

		void IsEndOfStream([MarshalAs(UnmanagedType.Bool)] ref bool pfEndOfStream);

		void Read(IntPtr pb, int cb, ref int pcbRead);

		void BeginRead(IntPtr pb, int cb, IntPtr pCallback, IntPtr punkState);

		void EndRead(IntPtr pResult, ref int pcbRead);

		void Write(IntPtr pb, int cb, ref int pcbWritten);

		void BeginWrite(IntPtr pb, int cb, IntPtr pCallback, IntPtr punkState);

		void EndWrite(IntPtr pResult, ref int pcbWritten);

		void Seek(int SeekOrigin, long llSeekOffset, int dwSeekFlags, ref long pqwCurrentPosition);

		void Flush();

		void Close();
	}
	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("5BC8A76B-869A-46A3-9B03-FA218A66AEBE")]
	public interface IMFCollection
	{
		void GetElementCount(out int pcElements);

		void GetElement([In] int dwElementIndex, [MarshalAs(UnmanagedType.IUnknown)] out object ppUnkElement);

		void AddElement([In][MarshalAs(UnmanagedType.IUnknown)] object pUnkElement);

		void RemoveElement([In] int dwElementIndex, [MarshalAs(UnmanagedType.IUnknown)] out object ppUnkElement);

		void InsertElementAt([In] int dwIndex, [In][MarshalAs(UnmanagedType.IUnknown)] object pUnknown);

		void RemoveAllElements();
	}
	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("045FA593-8799-42b8-BC8D-8968C6453507")]
	public interface IMFMediaBuffer
	{
		void Lock(out IntPtr ppbBuffer, out int pcbMaxLength, out int pcbCurrentLength);

		void Unlock();

		void GetCurrentLength(out int pcbCurrentLength);

		void SetCurrentLength(int cbCurrentLength);

		void GetMaxLength(out int pcbMaxLength);
	}
	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("DF598932-F10C-4E39-BBA2-C308F101DAA3")]
	public interface IMFMediaEvent : IMFAttributes
	{
		new void GetItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][Out] IntPtr pValue);

		new void GetItemType([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pType);

		new void CompareItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr value, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

		new void Compare([MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, int matchType, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

		new void GetUINT32([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int punValue);

		new void GetUINT64([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out long punValue);

		new void GetDouble([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out double pfValue);

		new void GetGUID([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out Guid pguidValue);

		new void GetStringLength([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcchLength);

		new void GetString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out][MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, int cchBufSize, out int pcchLength);

		new void GetAllocatedString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, out int pcchLength);

		new void GetBlobSize([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcbBlobSize);

		new void GetBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out][MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, int cbBufSize, out int pcbBlobSize);

		new void GetAllocatedBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out IntPtr ip, out int pcbSize);

		new void GetUnknown([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);

		new void SetItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr value);

		new void DeleteItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey);

		new void DeleteAllItems();

		new void SetUINT32([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, int unValue);

		new void SetUINT64([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, long unValue);

		new void SetDouble([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, double fValue);

		new void SetGUID([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPStruct)] Guid guidValue);

		new void SetString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPWStr)] string wszValue);

		new void SetBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, int cbBufSize);

		new void SetUnknown([MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.IUnknown)] object pUnknown);

		new void LockStore();

		new void UnlockStore();

		new void GetCount(out int pcItems);

		new void GetItemByIndex(int unIndex, out Guid pGuidKey, [In][Out] IntPtr pValue);

		new void CopyAllItems([In][MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest);

		void GetType(out MediaEventType pmet);

		void GetExtendedType(out Guid pguidExtendedType);

		void GetStatus([MarshalAs(UnmanagedType.Error)] out int phrStatus);

		void GetValue([Out] IntPtr pvValue);
	}
	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("44AE0FA8-EA31-4109-8D2E-4CAE4997C555")]
	public interface IMFMediaType : IMFAttributes
	{
		new void GetItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][Out] IntPtr pValue);

		new void GetItemType([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pType);

		new void CompareItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr value, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

		new void Compare([MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, int matchType, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

		new void GetUINT32([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int punValue);

		new void GetUINT64([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out long punValue);

		new void GetDouble([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out double pfValue);

		new void GetGUID([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out Guid pguidValue);

		new void GetStringLength([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcchLength);

		new void GetString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out][MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, int cchBufSize, out int pcchLength);

		new void GetAllocatedString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, out int pcchLength);

		new void GetBlobSize([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcbBlobSize);

		new void GetBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out][MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, int cbBufSize, out int pcbBlobSize);

		new void GetAllocatedBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out IntPtr ip, out int pcbSize);

		new void GetUnknown([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);

		new void SetItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr value);

		new void DeleteItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey);

		new void DeleteAllItems();

		new void SetUINT32([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, int unValue);

		new void SetUINT64([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, long unValue);

		new void SetDouble([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, double fValue);

		new void SetGUID([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPStruct)] Guid guidValue);

		new void SetString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPWStr)] string wszValue);

		new void SetBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, int cbBufSize);

		new void SetUnknown([MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.IUnknown)] object pUnknown);

		new void LockStore();

		new void UnlockStore();

		new void GetCount(out int pcItems);

		new void GetItemByIndex(int unIndex, out Guid pGuidKey, [In][Out] IntPtr pValue);

		new void CopyAllItems([In][MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest);

		void GetMajorType(out Guid pguidMajorType);

		void IsCompressedFormat([MarshalAs(UnmanagedType.Bool)] out bool pfCompressed);

		[PreserveSig]
		int IsEqual([In][MarshalAs(UnmanagedType.Interface)] IMFMediaType pIMediaType, ref int pdwFlags);

		void GetRepresentation([In] Guid guidRepresentation, ref IntPtr ppvRepresentation);

		void FreeRepresentation([In] Guid guidRepresentation, [In] IntPtr pvRepresentation);
	}
	[ComImport]
	[Guid("E7FE2E12-661C-40DA-92F9-4F002AB67627")]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	public interface IMFReadWriteClassFactory
	{
		void CreateInstanceFromURL([In][MarshalAs(UnmanagedType.LPStruct)] Guid clsid, [In][MarshalAs(UnmanagedType.LPWStr)] string pwszURL, [In][MarshalAs(UnmanagedType.Interface)] IMFAttributes pAttributes, [In][MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppvObject);

		void CreateInstanceFromObject([In][MarshalAs(UnmanagedType.LPStruct)] Guid clsid, [In][MarshalAs(UnmanagedType.IUnknown)] object punkObject, [In][MarshalAs(UnmanagedType.Interface)] IMFAttributes pAttributes, [In][MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppvObject);
	}
	[ComImport]
	[Guid("48e2ed0f-98c2-4a37-bed5-166312ddd83f")]
	public class MFReadWriteClassFactory
	{
	}
	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("c40a00f2-b93a-4d80-ae8c-5a1c634f58e4")]
	public interface IMFSample : IMFAttributes
	{
		new void GetItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][Out] IntPtr pValue);

		new void GetItemType([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pType);

		new void CompareItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr value, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

		new void Compare([MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, int matchType, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

		new void GetUINT32([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int punValue);

		new void GetUINT64([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out long punValue);

		new void GetDouble([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out double pfValue);

		new void GetGUID([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out Guid pguidValue);

		new void GetStringLength([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcchLength);

		new void GetString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out][MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, int cchBufSize, out int pcchLength);

		new void GetAllocatedString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, out int pcchLength);

		new void GetBlobSize([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcbBlobSize);

		new void GetBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out][MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, int cbBufSize, out int pcbBlobSize);

		new void GetAllocatedBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out IntPtr ip, out int pcbSize);

		new void GetUnknown([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);

		new void SetItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr value);

		new void DeleteItem([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey);

		new void DeleteAllItems();

		new void SetUINT32([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, int unValue);

		new void SetUINT64([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, long unValue);

		new void SetDouble([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, double fValue);

		new void SetGUID([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPStruct)] Guid guidValue);

		new void SetString([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPWStr)] string wszValue);

		new void SetBlob([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, int cbBufSize);

		new void SetUnknown([MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In][MarshalAs(UnmanagedType.IUnknown)] object pUnknown);

		new void LockStore();

		new void UnlockStore();

		new void GetCount(out int pcItems);

		new void GetItemByIndex(int unIndex, out Guid pGuidKey, [In][Out] IntPtr pValue);

		new void CopyAllItems([In][MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest);

		void GetSampleFlags(out int pdwSampleFlags);

		void SetSampleFlags(int dwSampleFlags);

		void GetSampleTime(out long phnsSampletime);

		void SetSampleTime(long hnsSampleTime);

		void GetSampleDuration(out long phnsSampleDuration);

		void SetSampleDuration(long hnsSampleDuration);

		void GetBufferCount(out int pdwBufferCount);

		void GetBufferByIndex(int dwIndex, out IMFMediaBuffer ppBuffer);

		void ConvertToContiguousBuffer(out IMFMediaBuffer ppBuffer);

		void AddBuffer(IMFMediaBuffer pBuffer);

		void RemoveBufferByIndex(int dwIndex);

		void RemoveAllBuffers();

		void GetTotalLength(out int pcbTotalLength);

		void CopyToBuffer(IMFMediaBuffer pBuffer);
	}
	[ComImport]
	[Guid("3137f1cd-fe5e-4805-a5d8-fb477448cb3d")]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	public interface IMFSinkWriter
	{
		void AddStream([In][MarshalAs(UnmanagedType.Interface)] IMFMediaType pTargetMediaType, out int pdwStreamIndex);

		void SetInputMediaType([In] int dwStreamIndex, [In][MarshalAs(UnmanagedType.Interface)] IMFMediaType pInputMediaType, [In][MarshalAs(UnmanagedType.Interface)] IMFAttributes pEncodingParameters);

		void BeginWriting();

		void WriteSample([In] int dwStreamIndex, [In][MarshalAs(UnmanagedType.Interface)] IMFSample pSample);

		void SendStreamTick([In] int dwStreamIndex, [In] long llTimestamp);

		void PlaceMarker([In] int dwStreamIndex, [In] IntPtr pvContext);

		void NotifyEndOfSegment([In] int dwStreamIndex);

		void Flush([In] int dwStreamIndex);

		void DoFinalize();

		void GetServiceForStream([In] int dwStreamIndex, [In] ref Guid guidService, [In] ref Guid riid, out IntPtr ppvObject);

		void GetStatistics([In] int dwStreamIndex, [In][Out] MF_SINK_WRITER_STATISTICS pStats);
	}
	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("70ae66f2-c809-4e4f-8915-bdcb406b7993")]
	public interface IMFSourceReader
	{
		void GetStreamSelection([In] int dwStreamIndex, [MarshalAs(UnmanagedType.Bool)] out bool pSelected);

		void SetStreamSelection([In] int dwStreamIndex, [In][MarshalAs(UnmanagedType.Bool)] bool pSelected);

		void GetNativeMediaType([In] int dwStreamIndex, [In] int dwMediaTypeIndex, out IMFMediaType ppMediaType);

		void GetCurrentMediaType([In] int dwStreamIndex, out IMFMediaType ppMediaType);

		void SetCurrentMediaType([In] int dwStreamIndex, IntPtr pdwReserved, [In] IMFMediaType pMediaType);

		void SetCurrentPosition([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidTimeFormat, [In] IntPtr varPosition);

		void ReadSample([In] int dwStreamIndex, [In] int dwControlFlags, out int pdwActualStreamIndex, out MF_SOURCE_READER_FLAG pdwStreamFlags, out ulong pllTimestamp, out IMFSample ppSample);

		void Flush([In] int dwStreamIndex);

		void GetServiceForStream([In] int dwStreamIndex, [In][MarshalAs(UnmanagedType.LPStruct)] Guid guidService, [In][MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IntPtr ppvObject);

		[PreserveSig]
		int GetPresentationAttribute([In] int dwStreamIndex, [In][MarshalAs(UnmanagedType.LPStruct)] Guid guidAttribute, [Out] IntPtr pvarAttribute);
	}
	[Flags]
	public enum MF_SOURCE_READER_FLAG
	{
		None = 0,
		MF_SOURCE_READERF_ERROR = 1,
		MF_SOURCE_READERF_ENDOFSTREAM = 2,
		MF_SOURCE_READERF_NEWSTREAM = 4,
		MF_SOURCE_READERF_NATIVEMEDIATYPECHANGED = 0x10,
		MF_SOURCE_READERF_CURRENTMEDIATYPECHANGED = 0x20,
		MF_SOURCE_READERF_STREAMTICK = 0x100,
		MF_SOURCE_READERF_ALLEFFECTSREMOVED = 0x200
	}
	[ComImport]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("bf94c121-5b05-4e6f-8000-ba598961414d")]
	public interface IMFTransform
	{
		void GetStreamLimits(out int pdwInputMinimum, out int pdwInputMaximum, out int pdwOutputMinimum, out int pdwOutputMaximum);

		void GetStreamCount(out int pcInputStreams, out int pcOutputStreams);

		void GetStreamIds([In] int dwInputIdArraySize, [In][Out] IntPtr pdwInputIDs, [In] int dwOutputIdArraySize, [In][Out] IntPtr pdwOutputIDs);

		void GetInputStreamInfo([In] int dwInputStreamId, out MFT_INPUT_STREAM_INFO pStreamInfo);

		void GetOutputStreamInfo([In] int dwOutputStreamId, out MFT_OUTPUT_STREAM_INFO pStreamInfo);

		void GetAttributes(out IMFAttributes pAttributes);

		void GetInputStreamAttributes([In] int dwInputStreamId, out IMFAttributes pAttributes);

		void GetOutputStreamAttributes([In] int dwOutputStreamId, out IMFAttributes pAttributes);

		void DeleteInputStream([In] int dwOutputStreamId);

		void AddInputStreams([In] int cStreams, [In] IntPtr adwStreamIDs);

		void GetInputAvailableType([In] int dwInputStreamId, [In] int dwTypeIndex, out IMFMediaType ppType);

		void GetOutputAvailableType([In] int dwOutputStreamId, [In] int dwTypeIndex, out IMFMediaType ppType);

		void SetInputType([In] int dwInputStreamId, [In] IMFMediaType pType, [In] _MFT_SET_TYPE_FLAGS dwFlags);

		void SetOutputType([In] int dwOutputStreamId, [In] IMFMediaType pType, [In] _MFT_SET_TYPE_FLAGS dwFlags);

		void GetInputCurrentType([In] int dwInputStreamId, out IMFMediaType ppType);

		void GetOutputCurrentType([In] int dwOutputStreamId, out IMFMediaType ppType);

		void GetInputStatus([In] int dwInputStreamId, out _MFT_INPUT_STATUS_FLAGS pdwFlags);

		void GetOutputStatus([In] int dwInputStreamId, out _MFT_OUTPUT_STATUS_FLAGS pdwFlags);

		void SetOutputBounds([In] long hnsLowerBound, [In] long hnsUpperBound);

		void ProcessEvent([In] int dwInputStreamId, [In] IMFMediaEvent pEvent);

		void ProcessMessage([In] MFT_MESSAGE_TYPE eMessage, [In] IntPtr ulParam);

		void ProcessInput([In] int dwInputStreamId, [In] IMFSample pSample, int dwFlags);

		[PreserveSig]
		int ProcessOutput([In] _MFT_PROCESS_OUTPUT_FLAGS dwFlags, [In] int cOutputBufferCount, [In][Out][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] MFT_OUTPUT_DATA_BUFFER[] pOutputSamples, out _MFT_PROCESS_OUTPUT_STATUS pdwStatus);
	}
	public enum MediaEventType
	{
		MEUnknown = 0,
		MEError = 1,
		MEExtendedType = 2,
		MENonFatalError = 3,
		MESessionUnknown = 100,
		MESessionTopologySet = 101,
		MESessionTopologiesCleared = 102,
		MESessionStarted = 103,
		MESessionPaused = 104,
		MESessionStopped = 105,
		MESessionClosed = 106,
		MESessionEnded = 107,
		MESessionRateChanged = 108,
		MESessionScrubSampleComplete = 109,
		MESessionCapabilitiesChanged = 110,
		MESessionTopologyStatus = 111,
		MESessionNotifyPresentationTime = 112,
		MENewPresentation = 113,
		MELicenseAcquisitionStart = 114,
		MELicenseAcquisitionCompleted = 115,
		MEIndividualizationStart = 116,
		MEIndividualizationCompleted = 117,
		MEEnablerProgress = 118,
		MEEnablerCompleted = 119,
		MEPolicyError = 120,
		MEPolicyReport = 121,
		MEBufferingStarted = 122,
		MEBufferingStopped = 123,
		MEConnectStart = 124,
		MEConnectEnd = 125,
		MEReconnectStart = 126,
		MEReconnectEnd = 127,
		MERendererEvent = 128,
		MESessionStreamSinkFormatChanged = 129,
		MESourceUnknown = 200,
		MESourceStarted = 201,
		MEStreamStarted = 202,
		MESourceSeeked = 203,
		MEStreamSeeked = 204,
		MENewStream = 205,
		MEUpdatedStream = 206,
		MESourceStopped = 207,
		MEStreamStopped = 208,
		MESourcePaused = 209,
		MEStreamPaused = 210,
		MEEndOfPresentation = 211,
		MEEndOfStream = 212,
		MEMediaSample = 213,
		MEStreamTick = 214,
		MEStreamThinMode = 215,
		MEStreamFormatChanged = 216,
		MESourceRateChanged = 217,
		MEEndOfPresentationSegment = 218,
		MESourceCharacteristicsChanged = 219,
		MESourceRateChangeRequested = 220,
		MESourceMetadataChanged = 221,
		MESequencerSourceTopologyUpdated = 222,
		MESinkUnknown = 300,
		MEStreamSinkStarted = 301,
		MEStreamSinkStopped = 302,
		MEStreamSinkPaused = 303,
		MEStreamSinkRateChanged = 304,
		MEStreamSinkRequestSample = 305,
		MEStreamSinkMarker = 306,
		MEStreamSinkPrerolled = 307,
		MEStreamSinkScrubSampleComplete = 308,
		MEStreamSinkFormatChanged = 309,
		MEStreamSinkDeviceChanged = 310,
		MEQualityNotify = 311,
		MESinkInvalidated = 312,
		MEAudioSessionNameChanged = 313,
		MEAudioSessionVolumeChanged = 314,
		MEAudioSessionDeviceRemoved = 315,
		MEAudioSessionServerShutdown = 316,
		MEAudioSessionGroupingParamChanged = 317,
		MEAudioSessionIconChanged = 318,
		MEAudioSessionFormatChanged = 319,
		MEAudioSessionDisconnected = 320,
		MEAudioSessionExclusiveModeOverride = 321,
		METrustUnknown = 400,
		MEPolicyChanged = 401,
		MEContentProtectionMessage = 402,
		MEPolicySet = 403,
		MEWMDRMLicenseBackupCompleted = 500,
		MEWMDRMLicenseBackupProgress = 501,
		MEWMDRMLicenseRestoreCompleted = 502,
		MEWMDRMLicenseRestoreProgress = 503,
		MEWMDRMLicenseAcquisitionCompleted = 506,
		MEWMDRMIndividualizationCompleted = 508,
		MEWMDRMIndividualizationProgress = 513,
		MEWMDRMProximityCompleted = 514,
		MEWMDRMLicenseStoreCleaned = 515,
		MEWMDRMRevocationDownloadCompleted = 516,
		METransformUnknown = 600,
		METransformNeedInput = 601,
		METransformHaveOutput = 602,
		METransformDrainComplete = 603,
		METransformMarker = 604
	}
	public static class MediaFoundationAttributes
	{
		public static readonly Guid MF_TRANSFORM_ASYNC = new Guid("f81a699a-649a-497d-8c73-29f8fed6ad7a");

		public static readonly Guid MF_TRANSFORM_ASYNC_UNLOCK = new Guid("e5666d6b-3422-4eb6-a421-da7db1f8e207");

		[FieldDescription("Transform Flags")]
		public static readonly Guid MF_TRANSFORM_FLAGS_Attribute = new Guid("9359bb7e-6275-46c4-a025-1c01e45f1a86");

		[FieldDescription("Transform Category")]
		public static readonly Guid MF_TRANSFORM_CATEGORY_Attribute = new Guid("ceabba49-506d-4757-a6ff-66c184987e4e");

		[FieldDescription("Class identifier")]
		public static readonly Guid MFT_TRANSFORM_CLSID_Attribute = new Guid("6821c42b-65a4-4e82-99bc-9a88205ecd0c");

		[FieldDescription("Container type")]
		public static readonly Guid MF_TRANSCODE_CONTAINERTYPE = new Guid(353366591, 19132, 18315, 172, 79, 225, 145, 111, 186, 28, 202);

		[FieldDescription("Input Types")]
		public static readonly Guid MFT_INPUT_TYPES_Attributes = new Guid("4276c9b1-759d-4bf3-9cd0-0d723d138f96");

		[FieldDescription("Output Types")]
		public static readonly Guid MFT_OUTPUT_TYPES_Attributes = new Guid("8eae8cf3-a44f-4306-ba5c-bf5dda242818");

		public static readonly Guid MFT_ENUM_HARDWARE_URL_Attribute = new Guid("2fb866ac-b078-4942-ab6c-003d05cda674");

		[FieldDescription("Name")]
		public static readonly Guid MFT_FRIENDLY_NAME_Attribute = new Guid("314ffbae-5b41-4c95-9c19-4e7d586face3");

		public static readonly Guid MFT_CONNECTED_STREAM_ATTRIBUTE = new Guid("71eeb820-a59f-4de2-bcec-38db1dd611a4");

		public static readonly Guid MFT_CONNECTED_TO_HW_STREAM = new Guid("34e6e728-06d6-4491-a553-4795650db912");

		[FieldDescription("Preferred Output Format")]
		public static readonly Guid MFT_PREFERRED_OUTPUTTYPE_Attribute = new Guid("7e700499-396a-49ee-b1b4-f628021e8c9d");

		public static readonly Guid MFT_PROCESS_LOCAL_Attribute = new Guid("543186e4-4649-4e65-b588-4aa352aff379");

		public static readonly Guid MFT_PREFERRED_ENCODER_PROFILE = new Guid("53004909-1ef5-46d7-a18e-5a75f8b5905f");

		public static readonly Guid MFT_HW_TIMESTAMP_WITH_QPC_Attribute = new Guid("8d030fb8-cc43-4258-a22e-9210bef89be4");

		public static readonly Guid MFT_FIELDOFUSE_UNLOCK_Attribute = new Guid("8ec2e9fd-9148-410d-831e-702439461a8e");

		public static readonly Guid MFT_CODEC_MERIT_Attribute = new Guid("88a7cb15-7b07-4a34-9128-e64c6703c4d3");

		public static readonly Guid MFT_ENUM_TRANSCODE_ONLY_ATTRIBUTE = new Guid("111ea8cd-b62a-4bdb-89f6-67ffcdc2458b");

		[FieldDescription("PMP Host Context")]
		public static readonly Guid MF_PD_PMPHOST_CONTEXT = new Guid("6c990d31-bb8e-477a-8598-0d5d96fcd88a");

		[FieldDescription("App Context")]
		public static readonly Guid MF_PD_APP_CONTEXT = new Guid("6c990d32-bb8e-477a-8598-0d5d96fcd88a");

		[FieldDescription("Duration")]
		public static readonly Guid MF_PD_DURATION = new Guid("6c990d33-bb8e-477a-8598-0d5d96fcd88a");

		[FieldDescription("Total File Size")]
		public static readonly Guid MF_PD_TOTAL_FILE_SIZE = new Guid("6c990d34-bb8e-477a-8598-0d5d96fcd88a");

		[FieldDescription("Audio encoding bitrate")]
		public static readonly Guid MF_PD_AUDIO_ENCODING_BITRATE = new Guid("6c990d35-bb8e-477a-8598-0d5d96fcd88a");

		[FieldDescription("Video Encoding Bitrate")]
		public static readonly Guid MF_PD_VIDEO_ENCODING_BITRATE = new Guid("6c990d36-bb8e-477a-8598-0d5d96fcd88a");

		[FieldDescription("MIME Type")]
		public static readonly Guid MF_PD_MIME_TYPE = new Guid("6c990d37-bb8e-477a-8598-0d5d96fcd88a");

		[FieldDescription("Last Modified Time")]
		public static readonly Guid MF_PD_LAST_MODIFIED_TIME = new Guid("6c990d38-bb8e-477a-8598-0d5d96fcd88a");

		[FieldDescription("Element ID")]
		public static readonly Guid MF_PD_PLAYBACK_ELEMENT_ID = new Guid("6c990d39-bb8e-477a-8598-0d5d96fcd88a");

		[FieldDescription("Preferred Language")]
		public static readonly Guid MF_PD_PREFERRED_LANGUAGE = new Guid("6c990d3a-bb8e-477a-8598-0d5d96fcd88a");

		[FieldDescription("Playback boundary time")]
		public static readonly Guid MF_PD_PLAYBACK_BOUNDARY_TIME = new Guid("6c990d3b-bb8e-477a-8598-0d5d96fcd88a");

		[FieldDescription("Audio is variable bitrate")]
		public static readonly Guid MF_PD_AUDIO_ISVARIABLEBITRATE = new Guid("33026ee0-e387-4582-ae0a-34a2ad3baa18");

		[FieldDescription("Major Media Type")]
		public static readonly Guid MF_MT_MAJOR_TYPE = new Guid("48eba18e-f8c9-4687-bf11-0a74c9f96a8f");

		[FieldDescription("Media Subtype")]
		public static readonly Guid MF_MT_SUBTYPE = new Guid("f7e34c9a-42e8-4714-b74b-cb29d72c35e5");

		[FieldDescription("Audio block alignment")]
		public static readonly Guid MF_MT_AUDIO_BLOCK_ALIGNMENT = new Guid("322de230-9eeb-43bd-ab7a-ff412251541d");

		[FieldDescription("Audio average bytes per second")]
		public static readonly Guid MF_MT_AUDIO_AVG_BYTES_PER_SECOND = new Guid("1aab75c8-cfef-451c-ab95-ac034b8e1731");

		[FieldDescription("Audio number of channels")]
		public static readonly Guid MF_MT_AUDIO_NUM_CHANNELS = new Guid("37e48bf5-645e-4c5b-89de-ada9e29b696a");

		[FieldDescription("Audio samples per second")]
		public static readonly Guid MF_MT_AUDIO_SAMPLES_PER_SECOND = new Guid("5faeeae7-0290-4c31-9e8a-c534f68d9dba");

		[FieldDescription("Audio bits per sample")]
		public static readonly Guid MF_MT_AUDIO_BITS_PER_SAMPLE = new Guid("f2deb57f-40fa-4764-aa33-ed4f2d1ff669");

		[FieldDescription("Enable Hardware Transforms")]
		public static readonly Guid MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS = new Guid("a634a91c-822b-41b9-a494-4de4643612b0");

		[FieldDescription("Disable Sink Writer Throttling")]
		public static readonly Guid MF_SINK_WRITER_DISABLE_THROTTLING = new Guid("08b845d8-2b74-4afe-9d53-be16d2d5ae4f");

		[FieldDescription("User data")]
		public static readonly Guid MF_MT_USER_DATA = new Guid("b6bc765f-4c3b-40a4-bd51-2535b66fe09d");

		[FieldDescription("All samples independent")]
		public static readonly Guid MF_MT_ALL_SAMPLES_INDEPENDENT = new Guid("c9173739-5e56-461c-b713-46fb995cb95f");

		[FieldDescription("Fixed size samples")]
		public static readonly Guid MF_MT_FIXED_SIZE_SAMPLES = new Guid("b8ebefaf-b718-4e04-b0a9-116775e3321b");

		[FieldDescription("DirectShow Format Guid")]
		public static readonly Guid MF_MT_AM_FORMAT_TYPE = new Guid("73d1072d-1870-4174-a063-29ff4ff6c11e");

		[FieldDescription("Preferred legacy format structure")]
		public static readonly Guid MF_MT_AUDIO_PREFER_WAVEFORMATEX = new Guid("a901aaba-e037-458a-bdf6-545be2074042");

		[FieldDescription("Is Compressed")]
		public static readonly Guid MF_MT_COMPRESSED = new Guid("3afd0cee-18f2-4ba5-a110-8bea502e1f92");

		[FieldDescription("Average bitrate")]
		public static readonly Guid MF_MT_AVG_BITRATE = new Guid("20332624-fb0d-4d9e-bd0d-cbf6786c102e");

		[FieldDescription("AAC payload type")]
		public static readonly Guid MF_MT_AAC_PAYLOAD_TYPE = new Guid("bfbabe79-7434-4d1c-94f0-72a3b9e17188");

		[FieldDescription("AAC Audio Profile Level Indication")]
		public static readonly Guid MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION = new Guid("7632f0e6-9538-4d61-acda-ea29c8c14456");
	}
	public static class MediaFoundationErrors
	{
		public const int MF_E_PLATFORM_NOT_INITIALIZED = -1072875856;

		public const int MF_E_BUFFERTOOSMALL = -1072875855;

		public const int MF_E_INVALIDREQUEST = -1072875854;

		public const int MF_E_INVALIDSTREAMNUMBER = -1072875853;

		public const int MF_E_INVALIDMEDIATYPE = -1072875852;

		public const int MF_E_NOTACCEPTING = -1072875851;

		public const int MF_E_NOT_INITIALIZED = -1072875850;

		public const int MF_E_UNSUPPORTED_REPRESENTATION = -1072875849;

		public const int MF_E_NO_MORE_TYPES = -1072875847;

		public const int MF_E_UNSUPPORTED_SERVICE = -1072875846;

		public const int MF_E_UNEXPECTED = -1072875845;

		public const int MF_E_INVALIDNAME = -1072875844;

		public const int MF_E_INVALIDTYPE = -1072875843;

		public const int MF_E_INVALID_FILE_FORMAT = -1072875842;

		public const int MF_E_INVALIDINDEX = -1072875841;

		public const int MF_E_INVALID_TIMESTAMP = -1072875840;

		public const int MF_E_UNSUPPORTED_SCHEME = -1072875837;

		public const int MF_E_UNSUPPORTED_BYTESTREAM_TYPE = -1072875836;

		public const int MF_E_UNSUPPORTED_TIME_FORMAT = -1072875835;

		public const int MF_E_NO_SAMPLE_TIMESTAMP = -1072875832;

		public const int MF_E_NO_SAMPLE_DURATION = -1072875831;

		public const int MF_E_INVALID_STREAM_DATA = -1072875829;

		public const int MF_E_RT_UNAVAILABLE = -1072875825;

		public const int MF_E_UNSUPPORTED_RATE = -1072875824;

		public const int MF_E_THINNING_UNSUPPORTED = -1072875823;

		public const int MF_E_REVERSE_UNSUPPORTED = -1072875822;

		public const int MF_E_UNSUPPORTED_RATE_TRANSITION = -1072875821;

		public const int MF_E_RATE_CHANGE_PREEMPTED = -1072875820;

		public const int MF_E_NOT_FOUND = -1072875819;

		public const int MF_E_NOT_AVAILABLE = -1072875818;

		public const int MF_E_NO_CLOCK = -1072875817;

		public const int MF_S_MULTIPLE_BEGIN = 866008;

		public const int MF_E_MULTIPLE_BEGIN = -1072875815;

		public const int MF_E_MULTIPLE_SUBSCRIBERS = -1072875814;

		public const int MF_E_TIMER_ORPHANED = -1072875813;

		public const int MF_E_STATE_TRANSITION_PENDING = -1072875812;

		public const int MF_E_UNSUPPORTED_STATE_TRANSITION = -1072875811;

		public const int MF_E_UNRECOVERABLE_ERROR_OCCURRED = -1072875810;

		public const int MF_E_SAMPLE_HAS_TOO_MANY_BUFFERS = -1072875809;

		public const int MF_E_SAMPLE_NOT_WRITABLE = -1072875808;

		public const int MF_E_INVALID_KEY = -1072875806;

		public const int MF_E_BAD_STARTUP_VERSION = -1072875805;

		public const int MF_E_UNSUPPORTED_CAPTION = -1072875804;

		public const int MF_E_INVALID_POSITION = -1072875803;

		public const int MF_E_ATTRIBUTENOTFOUND = -1072875802;

		public const int MF_E_PROPERTY_TYPE_NOT_ALLOWED = -1072875801;

		public const int MF_E_PROPERTY_TYPE_NOT_SUPPORTED = -1072875800;

		public const int MF_E_PROPERTY_EMPTY = -1072875799;

		public const int MF_E_PROPERTY_NOT_EMPTY = -1072875798;

		public const int MF_E_PROPERTY_VECTOR_NOT_ALLOWED = -1072875797;

		public const int MF_E_PROPERTY_VECTOR_REQUIRED = -1072875796;

		public const int MF_E_OPERATION_CANCELLED = -1072875795;

		public const int MF_E_BYTESTREAM_NOT_SEEKABLE = -1072875794;

		public const int MF_E_DISABLED_IN_SAFEMODE = -1072875793;

		public const int MF_E_CANNOT_PARSE_BYTESTREAM = -1072875792;

		public const int MF_E_SOURCERESOLVER_MUTUALLY_EXCLUSIVE_FLAGS = -1072875791;

		public const int MF_E_MEDIAPROC_WRONGSTATE = -1072875790;

		public const int MF_E_RT_THROUGHPUT_NOT_AVAILABLE = -1072875789;

		public const int MF_E_RT_TOO_MANY_CLASSES = -1072875788;

		public const int MF_E_RT_WOULDBLOCK = -1072875787;

		public const int MF_E_NO_BITPUMP = -1072875786;

		public const int MF_E_RT_OUTOFMEMORY = -1072875785;

		public const int MF_E_RT_WORKQUEUE_CLASS_NOT_SPECIFIED = -1072875784;

		public const int MF_E_INSUFFICIENT_BUFFER = -1072860816;

		public const int MF_E_CANNOT_CREATE_SINK = -1072875782;

		public const int MF_E_BYTESTREAM_UNKNOWN_LENGTH = -1072875781;

		public const int MF_E_SESSION_PAUSEWHILESTOPPED = -1072875780;

		public const int MF_S_ACTIVATE_REPLACED = 866045;

		public const int MF_E_FORMAT_CHANGE_NOT_SUPPORTED = -1072875778;

		public const int MF_E_INVALID_WORKQUEUE = -1072875777;

		public const int MF_E_DRM_UNSUPPORTED = -1072875776;

		public const int MF_E_UNAUTHORIZED = -1072875775;

		public const int MF_E_OUT_OF_RANGE = -1072875774;

		public const int MF_E_INVALID_CODEC_MERIT = -1072875773;

		public const int MF_E_HW_MFT_FAILED_START_STREAMING = -1072875772;

		public const int MF_S_ASF_PARSEINPROGRESS = 1074608792;

		public const int MF_E_ASF_PARSINGINCOMPLETE = -1072874856;

		public const int MF_E_ASF_MISSINGDATA = -1072874855;

		public const int MF_E_ASF_INVALIDDATA = -1072874854;

		public const int MF_E_ASF_OPAQUEPACKET = -1072874853;

		public const int MF_E_ASF_NOINDEX = -1072874852;

		public const int MF_E_ASF_OUTOFRANGE = -1072874851;

		public const int MF_E_ASF_INDEXNOTLOADED = -1072874850;

		public const int MF_E_ASF_TOO_MANY_PAYLOADS = -1072874849;

		public const int MF_E_ASF_UNSUPPORTED_STREAM_TYPE = -1072874848;

		public const int MF_E_ASF_DROPPED_PACKET = -1072874847;

		public const int MF_E_NO_EVENTS_AVAILABLE = -1072873856;

		public const int MF_E_INVALID_STATE_TRANSITION = -1072873854;

		public const int MF_E_END_OF_STREAM = -1072873852;

		public const int MF_E_SHUTDOWN = -1072873851;

		public const int MF_E_MP3_NOTFOUND = -1072873850;

		public const int MF_E_MP3_OUTOFDATA = -1072873849;

		public const int MF_E_MP3_NOTMP3 = -1072873848;

		public const int MF_E_MP3_NOTSUPPORTED = -1072873847;

		public const int MF_E_NO_DURATION = -1072873846;

		public const int MF_E_INVALID_FORMAT = -1072873844;

		public const int MF_E_PROPERTY_NOT_FOUND = -1072873843;

		public const int MF_E_PROPERTY_READ_ONLY = -1072873842;

		public const int MF_E_PROPERTY_NOT_ALLOWED = -1072873841;

		public const int MF_E_MEDIA_SOURCE_NOT_STARTED = -1072873839;

		public const int MF_E_UNSUPPORTED_FORMAT = -1072873832;

		public const int MF_E_MP3_BAD_CRC = -1072873831;

		public const int MF_E_NOT_PROTECTED = -1072873830;

		public const int MF_E_MEDIA_SOURCE_WRONGSTATE = -1072873829;

		public const int MF_E_MEDIA_SOURCE_NO_STREAMS_SELECTED = -1072873828;

		public const int MF_E_CANNOT_FIND_KEYFRAME_SAMPLE = -1072873827;

		public const int MF_E_NETWORK_RESOURCE_FAILURE = -1072872856;

		public const int MF_E_NET_WRITE = -1072872855;

		public const int MF_E_NET_READ = -1072872854;

		public const int MF_E_NET_REQUIRE_NETWORK = -1072872853;

		public const int MF_E_NET_REQUIRE_ASYNC = -1072872852;

		public const int MF_E_NET_BWLEVEL_NOT_SUPPORTED = -1072872851;

		public const int MF_E_NET_STREAMGROUPS_NOT_SUPPORTED = -1072872850;

		public const int MF_E_NET_MANUALSS_NOT_SUPPORTED = -1072872849;

		public const int MF_E_NET_INVALID_PRESENTATION_DESCRIPTOR = -1072872848;

		public const int MF_E_NET_CACHESTREAM_NOT_FOUND = -1072872847;

		public const int MF_I_MANUAL_PROXY = 1074610802;

		public const int MF_E_NET_REQUIRE_INPUT = -1072872844;

		public const int MF_E_NET_REDIRECT = -1072872843;

		public const int MF_E_NET_REDIRECT_TO_PROXY = -1072872842;

		public const int MF_E_NET_TOO_MANY_REDIRECTS = -1072872841;

		public const int MF_E_NET_TIMEOUT = -1072872840;

		public const int MF_E_NET_CLIENT_CLOSE = -1072872839;

		public const int MF_E_NET_BAD_CONTROL_DATA = -1072872838;

		public const int MF_E_NET_INCOMPATIBLE_SERVER = -1072872837;

		public const int MF_E_NET_UNSAFE_URL = -1072872836;

		public const int MF_E_NET_CACHE_NO_DATA = -1072872835;

		public const int MF_E_NET_EOL = -1072872834;

		public const int MF_E_NET_BAD_REQUEST = -1072872833;

		public const int MF_E_NET_INTERNAL_SERVER_ERROR = -1072872832;

		public const int MF_E_NET_SESSION_NOT_FOUND = -1072872831;

		public const int MF_E_NET_NOCONNECTION = -1072872830;

		public const int MF_E_NET_CONNECTION_FAILURE = -1072872829;

		public const int MF_E_NET_INCOMPATIBLE_PUSHSERVER = -1072872828;

		public const int MF_E_NET_SERVER_ACCESSDENIED = -1072872827;

		public const int MF_E_NET_PROXY_ACCESSDENIED = -1072872826;

		public const int MF_E_NET_CANNOTCONNECT = -1072872825;

		public const int MF_E_NET_INVALID_PUSH_TEMPLATE = -1072872824;

		public const int MF_E_NET_INVALID_PUSH_PUBLISHING_POINT = -1072872823;

		public const int MF_E_NET_BUSY = -1072872822;

		public const int MF_E_NET_RESOURCE_GONE = -1072872821;

		public const int MF_E_NET_ERROR_FROM_PROXY = -1072872820;

		public const int MF_E_NET_PROXY_TIMEOUT = -1072872819;

		public const int MF_E_NET_SERVER_UNAVAILABLE = -1072872818;

		public const int MF_E_NET_TOO_MUCH_DATA = -1072872817;

		public const int MF_E_NET_SESSION_INVALID = -1072872816;

		public const int MF_E_OFFLINE_MODE = -1072872815;

		public const int MF_E_NET_UDP_BLOCKED = -1072872814;

		public const int MF_E_NET_UNSUPPORTED_CONFIGURATION = -1072872813;

		public const int MF_E_NET_PROTOCOL_DISABLED = -1072872812;

		public const int MF_E_ALREADY_INITIALIZED = -1072871856;

		public const int MF_E_BANDWIDTH_OVERRUN = -1072871855;

		public const int MF_E_LATE_SAMPLE = -1072871854;

		public const int MF_E_FLUSH_NEEDED = -1072871853;

		public const int MF_E_INVALID_PROFILE = -1072871852;

		public const int MF_E_INDEX_NOT_COMMITTED = -1072871851;

		public const int MF_E_NO_INDEX = -1072871850;

		public const int MF_E_CANNOT_INDEX_IN_PLACE = -1072871849;

		public const int MF_E_MISSING_ASF_LEAKYBUCKET = -1072871848;

		public const int MF_E_INVALID_ASF_STREAMID = -1072871847;

		public const int MF_E_STREAMSINK_REMOVED = -1072870856;

		public const int MF_E_STREAMSINKS_OUT_OF_SYNC = -1072870854;

		public const int MF_E_STREAMSINKS_FIXED = -1072870853;

		public const int MF_E_STREAMSINK_EXISTS = -1072870852;

		public const int MF_E_SAMPLEALLOCATOR_CANCELED = -1072870851;

		public const int MF_E_SAMPLEALLOCATOR_EMPTY = -1072870850;

		public const int MF_E_SINK_ALREADYSTOPPED = -1072870849;

		public const int MF_E_ASF_FILESINK_BITRATE_UNKNOWN = -1072870848;

		public const int MF_E_SINK_NO_STREAMS = -1072870847;

		public const int MF_S_SINK_NOT_FINALIZED = 870978;

		public const int MF_E_METADATA_TOO_LONG = -1072870845;

		public const int MF_E_SINK_NO_SAMPLES_PROCESSED = -1072870844;

		public const int MF_E_VIDEO_REN_NO_PROCAMP_HW = -1072869856;

		public const int MF_E_VIDEO_REN_NO_DEINTERLACE_HW = -1072869855;

		public const int MF_E_VIDEO_REN_COPYPROT_FAILED = -1072869854;

		public const int MF_E_VIDEO_REN_SURFACE_NOT_SHARED = -1072869853;

		public const int MF_E_VIDEO_DEVICE_LOCKED = -1072869852;

		public const int MF_E_NEW_VIDEO_DEVICE = -1072869851;

		public const int MF_E_NO_VIDEO_SAMPLE_AVAILABLE = -1072869850;

		public const int MF_E_NO_AUDIO_PLAYBACK_DEVICE = -1072869756;

		public const int MF_E_AUDIO_PLAYBACK_DEVICE_IN_USE = -1072869755;

		public const int MF_E_AUDIO_PLAYBACK_DEVICE_INVALIDATED = -1072869754;

		public const int MF_E_AUDIO_SERVICE_NOT_RUNNING = -1072869753;

		public const int MF_E_TOPO_INVALID_OPTIONAL_NODE = -1072868850;

		public const int MF_E_TOPO_CANNOT_FIND_DECRYPTOR = -1072868847;

		public const int MF_E_TOPO_CODEC_NOT_FOUND = -1072868846;

		public const int MF_E_TOPO_CANNOT_CONNECT = -1072868845;

		public const int MF_E_TOPO_UNSUPPORTED = -1072868844;

		public const int MF_E_TOPO_INVALID_TIME_ATTRIBUTES = -1072868843;

		public const int MF_E_TOPO_LOOPS_IN_TOPOLOGY = -1072868842;

		public const int MF_E_TOPO_MISSING_PRESENTATION_DESCRIPTOR = -1072868841;

		public const int MF_E_TOPO_MISSING_STREAM_DESCRIPTOR = -1072868840;

		public const int MF_E_TOPO_STREAM_DESCRIPTOR_NOT_SELECTED = -1072868839;

		public const int MF_E_TOPO_MISSING_SOURCE = -1072868838;

		public const int MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED = -1072868837;

		public const int MF_E_SEQUENCER_UNKNOWN_SEGMENT_ID = -1072864852;

		public const int MF_S_SEQUENCER_CONTEXT_CANCELED = 876973;

		public const int MF_E_NO_SOURCE_IN_CACHE = -1072864850;

		public const int MF_S_SEQUENCER_SEGMENT_AT_END_OF_STREAM = 876975;

		public const int MF_E_TRANSFORM_TYPE_NOT_SET = -1072861856;

		public const int MF_E_TRANSFORM_STREAM_CHANGE = -1072861855;

		public const int MF_E_TRANSFORM_INPUT_REMAINING = -1072861854;

		public const int MF_E_TRANSFORM_PROFILE_MISSING = -1072861853;

		public const int MF_E_TRANSFORM_PROFILE_INVALID_OR_CORRUPT = -1072861852;

		public const int MF_E_TRANSFORM_PROFILE_TRUNCATED = -1072861851;

		public const int MF_E_TRANSFORM_PROPERTY_PID_NOT_RECOGNIZED = -1072861850;

		public const int MF_E_TRANSFORM_PROPERTY_VARIANT_TYPE_WRONG = -1072861849;

		public const int MF_E_TRANSFORM_PROPERTY_NOT_WRITEABLE = -1072861848;

		public const int MF_E_TRANSFORM_PROPERTY_ARRAY_VALUE_WRONG_NUM_DIM = -1072861847;

		public const int MF_E_TRANSFORM_PROPERTY_VALUE_SIZE_WRONG = -1072861846;

		public const int MF_E_TRANSFORM_PROPERTY_VALUE_OUT_OF_RANGE = -1072861845;

		public const int MF_E_TRANSFORM_PROPERTY_VALUE_INCOMPATIBLE = -1072861844;

		public const int MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_OUTPUT_MEDIATYPE = -1072861843;

		public const int MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_INPUT_MEDIATYPE = -1072861842;

		public const int MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_MEDIATYPE_COMBINATION = -1072861841;

		public const int MF_E_TRANSFORM_CONFLICTS_WITH_OTHER_CURRENTLY_ENABLED_FEATURES = -1072861840;

		public const int MF_E_TRANSFORM_NEED_MORE_INPUT = -1072861838;

		public const int MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_SPKR_CONFIG = -1072861837;

		public const int MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING = -1072861836;

		public const int MF_S_TRANSFORM_DO_NOT_PROPAGATE_EVENT = 879989;

		public const int MF_E_UNSUPPORTED_D3D_TYPE = -1072861834;

		public const int MF_E_TRANSFORM_ASYNC_LOCKED = -1072861833;

		public const int MF_E_TRANSFORM_CANNOT_INITIALIZE_ACM_DRIVER = -1072861832;

		public const int MF_E_LICENSE_INCORRECT_RIGHTS = -1072860856;

		public const int MF_E_LICENSE_OUTOFDATE = -1072860855;

		public const int MF_E_LICENSE_REQUIRED = -1072860854;

		public const int MF_E_DRM_HARDWARE_INCONSISTENT = -1072860853;

		public const int MF_E_NO_CONTENT_PROTECTION_MANAGER = -1072860852;

		public const int MF_E_LICENSE_RESTORE_NO_RIGHTS = -1072860851;

		public const int MF_E_BACKUP_RESTRICTED_LICENSE = -1072860850;

		public const int MF_E_LICENSE_RESTORE_NEEDS_INDIVIDUALIZATION = -1072860849;

		public const int MF_S_PROTECTION_NOT_REQUIRED = 880976;

		public const int MF_E_COMPONENT_REVOKED = -1072860847;

		public const int MF_E_TRUST_DISABLED = -1072860846;

		public const int MF_E_WMDRMOTA_NO_ACTION = -1072860845;

		public const int MF_E_WMDRMOTA_ACTION_ALREADY_SET = -1072860844;

		public const int MF_E_WMDRMOTA_DRM_HEADER_NOT_AVAILABLE = -1072860843;

		public const int MF_E_WMDRMOTA_DRM_ENCRYPTION_SCHEME_NOT_SUPPORTED = -1072860842;

		public const int MF_E_WMDRMOTA_ACTION_MISMATCH = -1072860841;

		public const int MF_E_WMDRMOTA_INVALID_POLICY = -1072860840;

		public const int MF_E_POLICY_UNSUPPORTED = -1072860839;

		public const int MF_E_OPL_NOT_SUPPORTED = -1072860838;

		public const int MF_E_TOPOLOGY_VERIFICATION_FAILED = -1072860837;

		public const int MF_E_SIGNATURE_VERIFICATION_FAILED = -1072860836;

		public const int MF_E_DEBUGGING_NOT_ALLOWED = -1072860835;

		public const int MF_E_CODE_EXPIRED = -1072860834;

		public const int MF_E_GRL_VERSION_TOO_LOW = -1072860833;

		public const int MF_E_GRL_RENEWAL_NOT_FOUND = -1072860832;

		public const int MF_E_GRL_EXTENSIBLE_ENTRY_NOT_FOUND = -1072860831;

		public const int MF_E_KERNEL_UNTRUSTED = -1072860830;

		public const int MF_E_PEAUTH_UNTRUSTED = -1072860829;

		public const int MF_E_NON_PE_PROCESS = -1072860827;

		public const int MF_E_REBOOT_REQUIRED = -1072860825;

		public const int MF_S_WAIT_FOR_POLICY_SET = 881000;

		public const int MF_S_VIDEO_DISABLED_WITH_UNKNOWN_SOFTWARE_OUTPUT = 881001;

		public const int MF_E_GRL_INVALID_FORMAT = -1072860822;

		public const int MF_E_GRL_UNRECOGNIZED_FORMAT = -1072860821;

		public const int MF_E_ALL_PROCESS_RESTART_REQUIRED = -1072860820;

		public const int MF_E_PROCESS_RESTART_REQUIRED = -1072860819;

		public const int MF_E_USERMODE_UNTRUSTED = -1072860818;

		public const int MF_E_PEAUTH_SESSION_NOT_STARTED = -1072860817;

		public const int MF_E_PEAUTH_PUBLICKEY_REVOKED = -1072860815;

		public const int MF_E_GRL_ABSENT = -1072860814;

		public const int MF_S_PE_TRUSTED = 881011;

		public const int MF_E_PE_UNTRUSTED = -1072860812;

		public const int MF_E_PEAUTH_NOT_STARTED = -1072860811;

		public const int MF_E_INCOMPATIBLE_SAMPLE_PROTECTION = -1072860810;

		public const int MF_E_PE_SESSIONS_MAXED = -1072860809;

		public const int MF_E_HIGH_SECURITY_LEVEL_CONTENT_NOT_ALLOWED = -1072860808;

		public const int MF_E_TEST_SIGNED_COMPONENTS_NOT_ALLOWED = -1072860807;

		public const int MF_E_ITA_UNSUPPORTED_ACTION = -1072860806;

		public const int MF_E_ITA_ERROR_PARSING_SAP_PARAMETERS = -1072860805;

		public const int MF_E_POLICY_MGR_ACTION_OUTOFBOUNDS = -1072860804;

		public const int MF_E_BAD_OPL_STRUCTURE_FORMAT = -1072860803;

		public const int MF_E_ITA_UNRECOGNIZED_ANALOG_VIDEO_PROTECTION_GUID = -1072860802;

		public const int MF_E_NO_PMP_HOST = -1072860801;

		public const int MF_E_ITA_OPL_DATA_NOT_INITIALIZED = -1072860800;

		public const int MF_E_ITA_UNRECOGNIZED_ANALOG_VIDEO_OUTPUT = -1072860799;

		public const int MF_E_ITA_UNRECOGNIZED_DIGITAL_VIDEO_OUTPUT = -1072860798;

		public const int MF_E_CLOCK_INVALID_CONTINUITY_KEY = -1072849856;

		public const int MF_E_CLOCK_NO_TIME_SOURCE = -1072849855;

		public const int MF_E_CLOCK_STATE_ALREADY_SET = -1072849854;

		public const int MF_E_CLOCK_NOT_SIMPLE = -1072849853;

		public const int MF_S_CLOCK_STOPPED = 891972;

		public const int MF_E_NO_MORE_DROP_MODES = -1072848856;

		public const int MF_E_NO_MORE_QUALITY_LEVELS = -1072848855;

		public const int MF_E_DROPTIME_NOT_SUPPORTED = -1072848854;

		public const int MF_E_QUALITYKNOB_WAIT_LONGER = -1072848853;

		public const int MF_E_QM_INVALIDSTATE = -1072848852;

		public const int MF_E_TRANSCODE_NO_CONTAINERTYPE = -1072847856;

		public const int MF_E_TRANSCODE_PROFILE_NO_MATCHING_STREAMS = -1072847855;

		public const int MF_E_TRANSCODE_NO_MATCHING_ENCODER = -1072847854;

		public const int MF_E_ALLOCATOR_NOT_INITIALIZED = -1072846856;

		public const int MF_E_ALLOCATOR_NOT_COMMITED = -1072846855;

		public const int MF_E_ALLOCATOR_ALREADY_COMMITED = -1072846854;

		public const int MF_E_STREAM_ERROR = -1072846853;

		public const int MF_E_INVALID_STREAM_STATE = -1072846852;

		public const int MF_E_HW_STREAM_NOT_CONNECTED = -1072846851;
	}
	public static class MediaFoundationApi
	{
		private static bool initialized;

		public static void Startup()
		{
			if (!initialized)
			{
				int num = 2;
				OperatingSystem oSVersion = Environment.OSVersion;
				if (oSVersion.Version.Major == 6 && oSVersion.Version.Minor == 0)
				{
					num = 1;
				}
				MediaFoundationInterop.MFStartup((num << 16) | 0x70);
				initialized = true;
			}
		}

		public static IEnumerable<IMFActivate> EnumerateTransforms(Guid category)
		{
			MediaFoundationInterop.MFTEnumEx(category, _MFT_ENUM_FLAG.MFT_ENUM_FLAG_ALL, null, null, out var interfacesPointer, out var pcMFTActivate);
			IMFActivate[] array = new IMFActivate[pcMFTActivate];
			for (int i = 0; i < pcMFTActivate; i++)
			{
				IntPtr pUnk = Marshal.ReadIntPtr(new IntPtr(interfacesPointer.ToInt64() + i * Marshal.SizeOf(interfacesPointer)));
				array[i] = (IMFActivate)Marshal.GetObjectForIUnknown(pUnk);
			}
			IMFActivate[] array2 = array;
			for (int j = 0; j < array2.Length; j++)
			{
				yield return array2[j];
			}
			Marshal.FreeCoTaskMem(interfacesPointer);
		}

		public static void Shutdown()
		{
			if (initialized)
			{
				MediaFoundationInterop.MFShutdown();
				initialized = false;
			}
		}

		public static IMFMediaType CreateMediaType()
		{
			MediaFoundationInterop.MFCreateMediaType(out var ppMFType);
			return ppMFType;
		}

		public static IMFMediaType CreateMediaTypeFromWaveFormat(WaveFormat waveFormat)
		{
			IMFMediaType iMFMediaType = CreateMediaType();
			try
			{
				MediaFoundationInterop.MFInitMediaTypeFromWaveFormatEx(iMFMediaType, waveFormat, Marshal.SizeOf<WaveFormat>(waveFormat));
				return iMFMediaType;
			}
			catch (Exception)
			{
				Marshal.ReleaseComObject(iMFMediaType);
				throw;
			}
		}

		public static IMFMediaBuffer CreateMemoryBuffer(int bufferSize)
		{
			MediaFoundationInterop.MFCreateMemoryBuffer(bufferSize, out var ppBuffer);
			return ppBuffer;
		}

		public static IMFSample CreateSample()
		{
			MediaFoundationInterop.MFCreateSample(out var ppIMFSample);
			return ppIMFSample;
		}

		public static IMFAttributes CreateAttributes(int initialSize)
		{
			MediaFoundationInterop.MFCreateAttributes(out var ppMFAttributes, initialSize);
			return ppMFAttributes;
		}

		public static IMFByteStream CreateByteStream(object stream)
		{
			if (stream is IStream)
			{
				MediaFoundationInterop.MFCreateMFByteStreamOnStream(stream as IStream, out var ppByteStream);
				return ppByteStream;
			}
			throw new ArgumentException("Stream must be IStream in desktop apps");
		}

		public static IMFSourceReader CreateSourceReaderFromByteStream(IMFByteStream byteStream)
		{
			MediaFoundationInterop.MFCreateSourceReaderFromByteStream(byteStream, null, out var ppSourceReader);
			return ppSourceReader;
		}
	}
	public static class MediaFoundationInterop
	{
		public const int MF_SOURCE_READER_ALL_STREAMS = -2;

		public const int MF_SOURCE_READER_FIRST_AUDIO_STREAM = -3;

		public const int MF_SOURCE_READER_FIRST_VIDEO_STREAM = -4;

		public const int MF_SOURCE_READER_MEDIASOURCE = -1;

		public const int MF_SDK_VERSION = 2;

		public const int MF_API_VERSION = 112;

		public const int MF_VERSION = 131184;

		[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
		public static extern void MFStartup(int version, int dwFlags = 0);

		[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
		public static extern void MFShutdown();

		[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
		internal static extern void MFCreateMediaType(out IMFMediaType ppMFType);

		[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
		internal static extern void MFInitMediaTypeFromWaveFormatEx([In] IMFMediaType pMFType, [In] WaveFormat pWaveFormat, [In] int cbBufSize);

		[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
		internal static extern void MFCreateWaveFormatExFromMFMediaType(IMFMediaType pMFType, ref IntPtr ppWF, ref int pcbSize, int flags = 0);

		[DllImport("mfreadwrite.dll", ExactSpelling = true, PreserveSig = false)]
		public static extern void MFCreateSourceReaderFromURL([In][MarshalAs(UnmanagedType.LPWStr)] string pwszURL, [In] IMFAttributes pAttributes, [MarshalAs(UnmanagedType.Interface)] out IMFSourceReader ppSourceReader);

		[DllImport("mfreadwrite.dll", ExactSpelling = true, PreserveSig = false)]
		public static extern void MFCreateSourceReaderFromByteStream([In] IMFByteStream pByteStream, [In] IMFAttributes pAttributes, [MarshalAs(UnmanagedType.Interface)] out IMFSourceReader ppSourceReader);

		[DllImport("mfreadwrite.dll", ExactSpelling = true, PreserveSig = false)]
		public static extern void MFCreateSinkWriterFromURL([In][MarshalAs(UnmanagedType.LPWStr)] string pwszOutputURL, [In] IMFByteStream pByteStream, [In] IMFAttributes pAttributes, out IMFSinkWriter ppSinkWriter);

		[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
		public static extern void MFCreateMFByteStreamOnStreamEx([MarshalAs(UnmanagedType.IUnknown)] object punkStream, out IMFByteStream ppByteStream);

		[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
		public static extern void MFCreateMFByteStreamOnStream([In] IStream punkStream, out IMFByteStream ppByteStream);

		[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
		public static extern void MFTEnumEx([In] Guid guidCategory, [In] _MFT_ENUM_FLAG flags, [In] MFT_REGISTER_TYPE_INFO pInputType, [In] MFT_REGISTER_TYPE_INFO pOutputType, out IntPtr pppMFTActivate, out int pcMFTActivate);

		[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
		internal static extern void MFCreateSample(out IMFSample ppIMFSample);

		[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
		internal static extern void MFCreateMemoryBuffer(int cbMaxLength, out IMFMediaBuffer ppBuffer);

		[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
		internal static extern void MFCreateAttributes([MarshalAs(UnmanagedType.Interface)] out IMFAttributes ppMFAttributes, [In] int cInitialSize);

		[DllImport("mf.dll", ExactSpelling = true, PreserveSig = false)]
		public static extern void MFTranscodeGetAudioOutputAvailableTypes([In][MarshalAs(UnmanagedType.LPStruct)] Guid guidSubType, [In] _MFT_ENUM_FLAG dwMFTFlags, [In] IMFAttributes pCodecConfig, [MarshalAs(UnmanagedType.Interface)] out IMFCollection ppAvailableTypes);
	}
	public abstract class MediaFoundationTransform : IWaveProvider, IDisposable
	{
		protected readonly IWaveProvider sourceProvider;

		protected readonly WaveFormat outputWaveFormat;

		private readonly byte[] sourceBuffer;

		private byte[] outputBuffer;

		private int outputBufferOffset;

		private int outputBufferCount;

		private IMFTransform transform;

		private bool disposed;

		private long inputPosition;

		private long outputPosition;

		private bool initializedForStreaming;

		public WaveFormat WaveFormat => outputWaveFormat;

		public MediaFoundationTransform(IWaveProvider sourceProvider, WaveFormat outputFormat)
		{
			outputWaveFormat = outputFormat;
			this.sourceProvider = sourceProvider;
			sourceBuffer = new byte[sourceProvider.WaveFormat.AverageBytesPerSecond];
			outputBuffer = new byte[outputWaveFormat.AverageBytesPerSecond + outputWaveFormat.BlockAlign];
		}

		private void InitializeTransformForStreaming()
		{
			transform.ProcessMessage(MFT_MESSAGE_TYPE.MFT_MESSAGE_COMMAND_FLUSH, IntPtr.Zero);
			transform.ProcessMessage(MFT_MESSAGE_TYPE.MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, IntPtr.Zero);
			transform.ProcessMessage(MFT_MESSAGE_TYPE.MFT_MESSAGE_NOTIFY_START_OF_STREAM, IntPtr.Zero);
			initializedForStreaming = true;
		}

		protected abstract IMFTransform CreateTransform();

		protected virtual void Dispose(bool disposing)
		{
			if (transform != null)
			{
				Marshal.ReleaseComObject(transform);
			}
		}

		public void Dispose()
		{
			if (!disposed)
			{
				disposed = true;
				Dispose(disposing: true);
				GC.SuppressFinalize(this);
			}
		}

		~MediaFoundationTransform()
		{
			Dispose(disposing: false);
		}

		public int Read(byte[] buffer, int offset, int count)
		{
			if (transform == null)
			{
				transform = CreateTransform();
				InitializeTransformForStreaming();
			}
			int i = 0;
			if (outputBufferCount > 0)
			{
				i += ReadFromOutputBuffer(buffer, offset, count - i);
			}
			for (; i < count; i += ReadFromOutputBuffer(buffer, offset + i, count - i))
			{
				IMFSample iMFSample = ReadFromSource();
				if (iMFSample == null)
				{
					EndStreamAndDrain();
					i += ReadFromOutputBuffer(buffer, offset + i, count - i);
					ClearOutputBuffer();
					break;
				}
				if (!initializedForStreaming)
				{
					InitializeTransformForStreaming();
				}
				transform.ProcessInput(0, iMFSample, 0);
				Marshal.ReleaseComObject(iMFSample);
				ReadFromTransform();
			}
			return i;
		}

		private void EndStreamAndDrain()
		{
			transform.ProcessMessage(MFT_MESSAGE_TYPE.MFT_MESSAGE_NOTIFY_END_OF_STREAM, IntPtr.Zero);
			transform.ProcessMessage(MFT_MESSAGE_TYPE.MFT_MESSAGE_COMMAND_DRAIN, IntPtr.Zero);
			int num;
			do
			{
				num = ReadFromTransform();
			}
			while (num > 0);
			inputPosition = 0L;
			outputPosition = 0L;
			transform.ProcessMessage(MFT_MESSAGE_TYPE.MFT_MESSAGE_NOTIFY_END_STREAMING, IntPtr.Zero);
			initializedForStreaming = false;
		}

		private void ClearOutputBuffer()
		{
			outputBufferCount = 0;
			outputBufferOffset = 0;
		}

		private int ReadFromTransform()
		{
			MFT_OUTPUT_DATA_BUFFER[] array = new MFT_OUTPUT_DATA_BUFFER[1];
			IMFSample iMFSample = MediaFoundationApi.CreateSample();
			IMFMediaBuffer iMFMediaBuffer = MediaFoundationApi.CreateMemoryBuffer(outputBuffer.Length);
			iMFSample.AddBuffer(iMFMediaBuffer);
			iMFSample.SetSampleTime(outputPosition);
			array[0].pSample = iMFSample;
			_MFT_PROCESS_OUTPUT_STATUS pdwStatus;
			int num = transform.ProcessOutput(_MFT_PROCESS_OUTPUT_FLAGS.None, 1, array, out pdwStatus);
			switch (num)
			{
			case -1072861838:
				Marshal.ReleaseComObject(iMFMediaBuffer);
				Marshal.ReleaseComObject(iMFSample);
				return 0;
			default:
				Marshal.ThrowExceptionForHR(num);
				break;
			case 0:
				break;
			}
			array[0].pSample.ConvertToContiguousBuffer(out var ppBuffer);
			ppBuffer.Lock(out var ppbBuffer, out var _, out var pcbCurrentLength);
			outputBuffer = BufferHelpers.Ensure(outputBuffer, pcbCurrentLength);
			Marshal.Copy(ppbBuffer, outputBuffer, 0, pcbCurrentLength);
			outputBufferOffset = 0;
			outputBufferCount = pcbCurrentLength;
			ppBuffer.Unlock();
			outputPosition += BytesToNsPosition(outputBufferCount, WaveFormat);
			Marshal.ReleaseComObject(iMFMediaBuffer);
			iMFSample.RemoveAllBuffers();
			Marshal.ReleaseComObject(iMFSample);
			Marshal.ReleaseComObject(ppBuffer);
			return pcbCurrentLength;
		}

		private static long BytesToNsPosition(int bytes, WaveFormat waveFormat)
		{
			return 10000000L * (long)bytes / waveFormat.AverageBytesPerSecond;
		}

		private IMFSample ReadFromSource()
		{
			int num = sourceProvider.Read(sourceBuffer, 0, sourceBuffer.Length);
			if (num == 0)
			{
				return null;
			}
			IMFMediaBuffer iMFMediaBuffer = MediaFoundationApi.CreateMemoryBuffer(num);
			iMFMediaBuffer.Lock(out var ppbBuffer, out var _, out var _);
			Marshal.Copy(sourceBuffer, 0, ppbBuffer, num);
			iMFMediaBuffer.Unlock();
			iMFMediaBuffer.SetCurrentLength(num);
			IMFSample iMFSample = MediaFoundationApi.CreateSample();
			iMFSample.AddBuffer(iMFMediaBuffer);
			iMFSample.SetSampleTime(inputPosition);
			long num2 = BytesToNsPosition(num, sourceProvider.WaveFormat);
			iMFSample.SetSampleDuration(num2);
			inputPosition += num2;
			Marshal.ReleaseComObject(iMFMediaBuffer);
			return iMFSample;
		}

		private int ReadFromOutputBuffer(byte[] buffer, int offset, int needed)
		{
			int num = Math.Min(needed, outputBufferCount);
			Array.Copy(outputBuffer, outputBufferOffset, buffer, offset, num);
			outputBufferOffset += num;
			outputBufferCount -= num;
			if (outputBufferCount == 0)
			{
				outputBufferOffset = 0;
			}
			return num;
		}

		public void Reposition()
		{
			if (initializedForStreaming)
			{
				EndStreamAndDrain();
				ClearOutputBuffer();
				InitializeTransformForStreaming();
			}
		}
	}
	public static class MediaFoundationTransformCategories
	{
		[FieldDescription("Video Decoder")]
		public static readonly Guid VideoDecoder = new Guid("{d6c02d4b-6833-45b4-971a-05a4b04bab91}");

		[FieldDescription("Video Encoder")]
		public static readonly Guid VideoEncoder = new Guid("{f79eac7d-e545-4387-bdee-d647d7bde42a}");

		[FieldDescription("Video Effect")]
		public static readonly Guid VideoEffect = new Guid("{12e17c21-532c-4a6e-8a1c-40825a736397}");

		[FieldDescription("Multiplexer")]
		public static readonly Guid Multiplexer = new Guid("{059c561e-05ae-4b61-b69d-55b61ee54a7b}");

		[FieldDescription("Demultiplexer")]
		public static readonly Guid Demultiplexer = new Guid("{a8700a7a-939b-44c5-99d7-76226b23b3f1}");

		[FieldDescription("Audio Decoder")]
		public static readonly Guid AudioDecoder = new Guid("{9ea73fb4-ef7a-4559-8d5d-719d8f0426c7}");

		[FieldDescription("Audio Encoder")]
		public static readonly Guid AudioEncoder = new Guid("{91c64bd0-f91e-4d8c-9276-db248279d975}");

		[FieldDescription("Audio Effect")]
		public static readonly Guid AudioEffect = new Guid("{11064c48-3648-4ed0-932e-05ce8ac811b7}");

		[FieldDescription("Video Processor")]
		public static readonly Guid VideoProcessor = new Guid("{302EA3FC-AA5F-47f9-9F7A-C2188BB16302}");

		[FieldDescription("Other")]
		public static readonly Guid Other = new Guid("{90175d57-b7ea-4901-aeb3-933a8747756f}");
	}
	public class MediaType
	{
		private readonly IMFMediaType mediaType;

		public int SampleRate
		{
			get
			{
				return GetUInt32(MediaFoundationAttributes.MF_MT_AUDIO_SAMPLES_PER_SECOND);
			}
			set
			{
				mediaType.SetUINT32(MediaFoundationAttributes.MF_MT_AUDIO_SAMPLES_PER_SECOND, value);
			}
		}

		public int ChannelCount
		{
			get
			{
				return GetUInt32(MediaFoundationAttributes.MF_MT_AUDIO_NUM_CHANNELS);
			}
			set
			{
				mediaType.SetUINT32(MediaFoundationAttributes.MF_MT_AUDIO_NUM_CHANNELS, value);
			}
		}

		public int BitsPerSample
		{
			get
			{
				return GetUInt32(MediaFoundationAttributes.MF_MT_AUDIO_BITS_PER_SAMPLE);
			}
			set
			{
				mediaType.SetUINT32(MediaFoundationAttributes.MF_MT_AUDIO_BITS_PER_SAMPLE, value);
			}
		}

		public int AverageBytesPerSecond => GetUInt32(MediaFoundationAttributes.MF_MT_AUDIO_AVG_BYTES_PER_SECOND);

		public Guid SubType
		{
			get
			{
				return GetGuid(MediaFoundationAttributes.MF_MT_SUBTYPE);
			}
			set
			{
				mediaType.SetGUID(MediaFoundationAttributes.MF_MT_SUBTYPE, value);
			}
		}

		public Guid MajorType
		{
			get
			{
				return GetGuid(MediaFoundationAttributes.MF_MT_MAJOR_TYPE);
			}
			set
			{
				mediaType.SetGUID(MediaFoundationAttributes.MF_MT_MAJOR_TYPE, value);
			}
		}

		public IMFMediaType MediaFoundationObject => mediaType;

		public MediaType(IMFMediaType mediaType)
		{
			this.mediaType = mediaType;
		}

		public MediaType()
		{
			mediaType = MediaFoundationApi.CreateMediaType();
		}

		public MediaType(WaveFormat waveFormat)
		{
			mediaType = MediaFoundationApi.CreateMediaTypeFromWaveFormat(waveFormat);
		}

		private int GetUInt32(Guid key)
		{
			mediaType.GetUINT32(key, out var punValue);
			return punValue;
		}

		private Guid GetGuid(Guid key)
		{
			mediaType.GetGUID(key, out var pguidValue);
			return pguidValue;
		}

		public int TryGetUInt32(Guid key, int defaultValue = -1)
		{
			int punValue = defaultValue;
			try
			{
				mediaType.GetUINT32(key, out punValue);
			}
			catch (COMException ex)
			{
				if (HResult.GetHResult(ex) != -1072875802)
				{
					if (HResult.GetHResult(ex) == -1072875843)
					{
						throw new ArgumentException("Not a UINT32 parameter");
					}
					throw;
				}
			}
			return punValue;
		}

		public void SetUInt32(Guid key, int value)
		{
			mediaType.SetUINT32(key, value);
		}
	}
	public static class MediaTypes
	{
		public static readonly Guid MFMediaType_Default = new Guid("81A412E6-8103-4B06-857F-1862781024AC");

		[FieldDescription("Audio")]
		public static readonly Guid MFMediaType_Audio = new Guid("73647561-0000-0010-8000-00aa00389b71");

		[FieldDescription("Video")]
		public static readonly Guid MFMediaType_Video = new Guid("73646976-0000-0010-8000-00aa00389b71");

		[FieldDescription("Protected Media")]
		public static readonly Guid MFMediaType_Protected = new Guid("7b4b6fe6-9d04-4494-be14-7e0bd076c8e4");

		[FieldDescription("SAMI captions")]
		public static readonly Guid MFMediaType_SAMI = new Guid("e69669a0-3dcd-40cb-9e2e-3708387c0616");

		[FieldDescription("Script stream")]
		public static readonly Guid MFMediaType_Script = new Guid("72178c22-e45b-11d5-bc2a-00b0d0f3f4ab");

		[FieldDescription("Still image stream")]
		public static readonly Guid MFMediaType_Image = new Guid("72178c23-e45b-11d5-bc2a-00b0d0f3f4ab");

		[FieldDescription("HTML stream")]
		public static readonly Guid MFMediaType_HTML = new Guid("72178c24-e45b-11d5-bc2a-00b0d0f3f4ab");

		[FieldDescription("Binary stream")]
		public static readonly Guid MFMediaType_Binary = new Guid("72178c25-e45b-11d5-bc2a-00b0d0f3f4ab");

		[FieldDescription("File transfer")]
		public static readonly Guid MFMediaType_FileTransfer = new Guid("72178c26-e45b-11d5-bc2a-00b0d0f3f4ab");
	}
	public struct MFT_INPUT_STREAM_INFO
	{
		public long hnsMaxLatency;

		public _MFT_INPUT_STREAM_INFO_FLAGS dwFlags;

		public int cbSize;

		public int cbMaxLookahead;

		public int cbAlignment;
	}
	public enum MFT_MESSAGE_TYPE
	{
		MFT_MESSAGE_COMMAND_FLUSH = 0,
		MFT_MESSAGE_COMMAND_DRAIN = 1,
		MFT_MESSAGE_SET_D3D_MANAGER = 2,
		MFT_MESSAGE_DROP_SAMPLES = 3,
		MFT_MESSAGE_COMMAND_TICK = 4,
		MFT_MESSAGE_NOTIFY_BEGIN_STREAMING = 268435456,
		MFT_MESSAGE_NOTIFY_END_STREAMING = 268435457,
		MFT_MESSAGE_NOTIFY_END_OF_STREAM = 268435458,
		MFT_MESSAGE_NOTIFY_START_OF_STREAM = 268435459,
		MFT_MESSAGE_COMMAND_MARKER = 536870912
	}
	public struct MFT_OUTPUT_DATA_BUFFER
	{
		public int dwStreamID;

		public IMFSample pSample;

		public _MFT_OUTPUT_DATA_BUFFER_FLAGS dwStatus;

		public IMFCollection pEvents;
	}
	public struct MFT_OUTPUT_STREAM_INFO
	{
		public _MFT_OUTPUT_STREAM_INFO_FLAGS dwFlags;

		public int cbSize;

		public int cbAlignment;
	}
	[StructLayout(LayoutKind.Sequential)]
	public class MFT_REGISTER_TYPE_INFO
	{
		public Guid guidMajorType;

		public Guid guidSubtype;
	}
	[StructLayout(LayoutKind.Sequential)]
	public class MF_SINK_WRITER_STATISTICS
	{
		public int cb;

		public long llLastTimestampReceived;

		public long llLastTimestampEncoded;

		public long llLastTimestampProcessed;

		public long llLastStreamTickReceived;

		public long llLastSinkSampleRequest;

		public long qwNumSamplesReceived;

		public long qwNumSamplesEncoded;

		public long qwNumSamplesProcessed;

		public long qwNumStreamTicksReceived;

		public int dwByteCountQueued;

		public long qwByteCountProcessed;

		public int dwNumOutstandingSinkSampleRequests;

		public int dwAverageSampleRateReceived;

		public int dwAverageSampleRateEncoded;

		public int dwAverageSampleRateProcessed;
	}
	public static class TranscodeContainerTypes
	{
		public static readonly Guid MFTranscodeContainerType_ASF = new Guid(1125085038u, 46783, 20417, 160, 189, 158, 228, 110, 238, 42, 251);

		public static readonly Guid MFTranscodeContainerType_MPEG4 = new Guid(3698118749u, 47568, 16623, 189, 53, 250, 98, 44, 26, 178, 138);

		public static readonly Guid MFTranscodeContainerType_MP3 = new Guid(3828922642u, 33777, 19942, 158, 58, 159, 251, 198, 221, 36, 209);

		public static readonly Guid MFTranscodeContainerType_3GP = new Guid(885326183, 17522, 20276, 158, 160, 196, 159, 186, 207, 3, 125);

		public static readonly Guid MFTranscodeContainerType_AC3 = new Guid(1837994435u, 35985, 20177, 135, 66, 140, 52, 125, 91, 68, 208);

		public static readonly Guid MFTranscodeContainerType_ADTS = new Guid(321901181, 3842, 17374, 163, 1, 56, 251, 187, 179, 131, 78);

		public static readonly Guid MFTranscodeContainerType_MPEG2 = new Guid(3217218553u, 31668, 20367, 175, 222, 225, 18, 196, 75, 168, 130);

		public static readonly Guid MFTranscodeContainerType_FMPEG4 = new Guid(2611508977u, 16799, 19319, 161, 224, 53, 149, 157, 157, 64, 4);

		public static readonly Guid MFTranscodeContainerType_WAVE = new Guid(1690518844, 3878, 18241, 190, 99, 135, 189, 248, 187, 147, 91);

		public static readonly Guid MFTranscodeContainerType_AVI = new Guid(2128603311, 16431, 19830, 163, 60, 97, 159, 209, 87, 208, 241);

		public static readonly Guid MFTranscodeContainerType_AMR = new Guid(39672531, 25114, 18267, 150, 77, 102, 177, 200, 36, 240, 121);
	}
	[Flags]
	public enum _MFT_ENUM_FLAG
	{
		None = 0,
		MFT_ENUM_FLAG_SYNCMFT = 1,
		MFT_ENUM_FLAG_ASYNCMFT = 2,
		MFT_ENUM_FLAG_HARDWARE = 4,
		MFT_ENUM_FLAG_FIELDOFUSE = 8,
		MFT_ENUM_FLAG_LOCALMFT = 0x10,
		MFT_ENUM_FLAG_TRANSCODE_ONLY = 0x20,
		MFT_ENUM_FLAG_SORTANDFILTER = 0x40,
		MFT_ENUM_FLAG_ALL = 0x3F
	}
	[Flags]
	public enum _MFT_INPUT_STATUS_FLAGS
	{
		None = 0,
		MFT_INPUT_STATUS_ACCEPT_DATA = 1
	}
	[Flags]
	public enum _MFT_INPUT_STREAM_INFO_FLAGS
	{
		None = 0,
		MFT_INPUT_STREAM_WHOLE_SAMPLES = 1,
		MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER = 2,
		MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE = 4,
		MFT_INPUT_STREAM_HOLDS_BUFFERS = 8,
		MFT_INPUT_STREAM_DOES_NOT_ADDREF = 0x100,
		MFT_INPUT_STREAM_REMOVABLE = 0x200,
		MFT_INPUT_STREAM_OPTIONAL = 0x400,
		MFT_INPUT_STREAM_PROCESSES_IN_PLACE = 0x800
	}
	[Flags]
	public enum _MFT_OUTPUT_DATA_BUFFER_FLAGS
	{
		None = 0,
		MFT_OUTPUT_DATA_BUFFER_INCOMPLETE = 0x1000000,
		MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE = 0x100,
		MFT_OUTPUT_DATA_BUFFER_STREAM_END = 0x200,
		MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE = 0x300
	}
	[Flags]
	public enum _MFT_OUTPUT_STATUS_FLAGS
	{
		None = 0,
		MFT_OUTPUT_STATUS_SAMPLE_READY = 1
	}
	[Flags]
	public enum _MFT_OUTPUT_STREAM_INFO_FLAGS
	{
		None = 0,
		MFT_OUTPUT_STREAM_WHOLE_SAMPLES = 1,
		MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER = 2,
		MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE = 4,
		MFT_OUTPUT_STREAM_DISCARDABLE = 8,
		MFT_OUTPUT_STREAM_OPTIONAL = 0x10,
		MFT_OUTPUT_STREAM_PROVIDES_SAMPLES = 0x100,
		MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES = 0x200,
		MFT_OUTPUT_STREAM_LAZY_READ = 0x400,
		MFT_OUTPUT_STREAM_REMOVABLE = 0x800
	}
	[Flags]
	public enum _MFT_PROCESS_OUTPUT_FLAGS
	{
		None = 0,
		MFT_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER = 1,
		MFT_PROCESS_OUTPUT_REGENERATE_LAST_OUTPUT = 2
	}
	[Flags]
	public enum _MFT_PROCESS_OUTPUT_STATUS
	{
		None = 0,
		MFT_PROCESS_OUTPUT_STATUS_NEW_STREAMS = 0x100
	}
	[Flags]
	public enum _MFT_SET_TYPE_FLAGS
	{
		None = 0,
		MFT_SET_TYPE_TEST_ONLY = 1
	}
}
namespace NAudio.Dmo
{
	public class DmoDescriptor
	{
		public string Name { get; private set; }

		public Guid Clsid { get; private set; }

		public DmoDescriptor(string name, Guid clsid)
		{
			Name = name;
			Clsid = clsid;
		}
	}
	public class DmoEnumerator
	{
		public static IEnumerable<DmoDescriptor> GetAudioEffectNames()
		{
			return GetDmos(DmoGuids.DMOCATEGORY_AUDIO_EFFECT);
		}

		public static IEnumerable<DmoDescriptor> GetAudioEncoderNames()
		{
			return GetDmos(DmoGuids.DMOCATEGORY_AUDIO_ENCODER);
		}

		public static IEnumerable<DmoDescriptor> GetAudioDecoderNames()
		{
			return GetDmos(DmoGuids.DMOCATEGORY_AUDIO_DECODER);
		}

		private static IEnumerable<DmoDescriptor> GetDmos(Guid category)
		{
			Marshal.ThrowExceptionForHR(DmoInterop.DMOEnum(ref category, DmoEnumFlags.None, 0, null, 0, null, out var enumDmo));
			int itemsFetched;
			do
			{
				enumDmo.Next(1, out var clsid, out var name, out itemsFetched);
				if (itemsFetched == 1)
				{
					string name2 = Marshal.PtrToStringUni(name);
					Marshal.FreeCoTaskMem(name);
					yield return new DmoDescriptor(name2, clsid);
				}
			}
			while (itemsFetched > 0);
		}
	}
	[Flags]
	internal enum DmoEnumFlags
	{
		None = 0,
		DMO_ENUMF_INCLUDE_KEYED = 1
	}
	internal static class DmoGuids
	{
		public static readonly Guid DMOCATEGORY_AUDIO_DECODER = new Guid("57f2db8b-e6bb-4513-9d43-dcd2a6593125");

		public static readonly Guid DMOCATEGORY_AUDIO_ENCODER = new Guid("33D9A761-90C8-11d0-BD43-00A0C911CE86");

		public static readonly Guid DMOCATEGORY_VIDEO_DECODER = new Guid("4a69b442-28be-4991-969c-b500adf5d8a8");

		public static readonly Guid DMOCATEGORY_VIDEO_ENCODER = new Guid("33D9A760-90C8-11d0-BD43-00A0C911CE86");

		public static readonly Guid DMOCATEGORY_AUDIO_EFFECT = new Guid("f3602b3f-0592-48df-a4cd-674721e7ebeb");

		public static readonly Guid DMOCATEGORY_VIDEO_EFFECT = new Guid("d990ee14-776c-4723-be46-3da2f56f10b9");

		public static readonly Guid DMOCATEGORY_AUDIO_CAPTURE_EFFECT = new Guid("f665aaba-3e09-4920-aa5f-219811148f09");
	}
	internal static class DmoMediaTypeGuids
	{
		public static readonly Guid FORMAT_None = new Guid("0F6417D6-C318-11D0-A43F-00A0C9223196");

		public static readonly Guid FORMAT_VideoInfo = new Guid("05589f80-c356-11ce-bf01-00aa0055595a");

		public static readonly Guid FORMAT_VideoInfo2 = new Guid("F72A76A0-EB0A-11d0-ACE4-0000C0CC16BA");

		public static readonly Guid FORMAT_WaveFormatEx = new Guid("05589f81-c356-11ce-bf01-00aa0055595a");

		public static readonly Guid FORMAT_MPEGVideo = new Guid("05589f82-c356-11ce-bf01-00aa0055595a");

		public static readonly Guid FORMAT_MPEGStreams = new Guid("05589f83-c356-11ce-bf01-00aa0055595a");

		public static readonly Guid FORMAT_DvInfo = new Guid("05589f84-c356-11ce-bf01-00aa0055595a");

		public static readonly Guid FORMAT_525WSS = new Guid("C7ECF04D-4582-4869-9ABB-BFB523B62EDF");
	}
	internal enum DmoHResults
	{
		DMO_E_INVALIDSTREAMINDEX = -2147220991,
		DMO_E_INVALIDTYPE,
		DMO_E_TYPE_NOT_SET,
		DMO_E_NOTACCEPTING,
		DMO_E_TYPE_NOT_ACCEPTED,
		DMO_E_NO_MORE_ITEMS
	}
	[Flags]
	public enum DmoInPlaceProcessFlags
	{
		Normal = 0,
		Zero = 1
	}
	public enum DmoInPlaceProcessReturn
	{
		Normal,
		HasEffectTail
	}
	[Flags]
	public enum DmoInputDataBufferFlags
	{
		None = 0,
		SyncPoint = 1,
		Time = 2,
		TimeLength = 4
	}
	[Flags]
	internal enum DmoInputStatusFlags
	{
		None = 0,
		DMO_INPUT_STATUSF_ACCEPT_DATA = 1
	}
	internal static class DmoInterop
	{
		[DllImport("msdmo.dll")]
		public static extern int DMOEnum([In] ref Guid guidCategory, DmoEnumFlags flags, int inTypes, [In] DmoPartialMediaType[] inTypesArray, int outTypes, [In] DmoPartialMediaType[] outTypesArray, out IEnumDmo enumDmo);

		[DllImport("msdmo.dll")]
		public static extern int MoFreeMediaType([In] ref DmoMediaType mediaType);

		[DllImport("msdmo.dll")]
		public static extern int MoInitMediaType([In][Out] ref DmoMediaType mediaType, int formatBlockBytes);

		[DllImport("msdmo.dll")]
		public static extern int DMOGetName([In] ref Guid clsidDMO, [Out] StringBuilder name);
	}
	public struct DmoMediaType
	{
		private Guid majortype;

		private Guid subtype;

		private bool bFixedSizeSamples;

		private bool bTemporalCompression;

		private int lSampleSize;

		private Guid formattype;

		private IntPtr pUnk;

		private int cbFormat;

		private IntPtr pbFormat;

		public Guid MajorType => majortype;

		public string MajorTypeName => MediaTypes.GetMediaTypeName(majortype);

		public Guid SubType => subtype;

		public string SubTypeName
		{
			get
			{
				if (majortype == MediaTypes.MEDIATYPE_Audio)
				{
					return AudioMediaSubtypes.GetAudioSubtypeName(subtype);
				}
				return subtype.ToString();
			}
		}

		public bool FixedSizeSamples => bFixedSizeSamples;

		public int SampleSize => lSampleSize;

		public Guid FormatType => formattype;

		public string FormatTypeName
		{
			get
			{
				if (formattype == DmoMediaTypeGuids.FORMAT_None)
				{
					return "None";
				}
				if (formattype == Guid.Empty)
				{
					return "Null";
				}
				if (formattype == DmoMediaTypeGuids.FORMAT_WaveFormatEx)
				{
					return "WaveFormatEx";
				}
				return FormatType.ToString();
			}
		}

		public WaveFormat GetWaveFormat()
		{
			if (formattype == DmoMediaTypeGuids.FORMAT_WaveFormatEx)
			{
				return WaveFormat.MarshalFromPtr(pbFormat);
			}
			throw new InvalidOperationException("Not a WaveFormat type");
		}

		public void SetWaveFormat(WaveFormat waveFormat)
		{
			//IL_0024: 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)
			//IL_002c: Invalid comparison between Unknown and I4
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between Unknown and I4
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Invalid comparison between Unknown and I4
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			majortype = MediaTypes.MEDIATYPE_Audio;
			WaveFormatExtensible val = (WaveFormatExtensible)(object)((waveFormat is WaveFormatExtensible) ? waveFormat : null);
			if (val != null)
			{
				subtype = val.SubFormat;
			}
			else
			{
				WaveFormatEncoding encoding = waveFormat.Encoding;
				if ((int)encoding != 1)
				{
					if ((int)encoding != 3)
					{
						if ((int)encoding != 85)
						{
							throw new ArgumentException($"Not a supported encoding {waveFormat.Encoding}");
						}
						subtype = AudioMediaSubtypes.WMMEDIASUBTYPE_MP3;
					}
					else
					{
						subtype = AudioMediaSubtypes.MEDIASUBTYPE_IEEE_FLOAT;
					}
				}
				else
				{
					subtype = AudioMediaSubtypes.MEDIASUBTYPE_PCM;
				}
			}
			bFixedSizeSamples = SubType == AudioMediaSubtypes.MEDIASUBTYPE_PCM || SubType == AudioMediaSubtypes.MEDIASUBTYPE_IEEE_FLOAT;
			formattype = DmoMediaTypeGuids.FORMAT_WaveFormatEx;
			if (cbFormat < Marshal.SizeOf<WaveFormat>(waveFormat))
			{
				throw new InvalidOperationException("Not enough memory assigned for a WaveFormat structure");
			}
			Marshal.StructureToPtr<WaveFormat>(waveFormat, pbFormat, fDeleteOld: false);
		}
	}
	[StructLayout(LayoutKind.Sequential, Pack = 8)]
	public struct DmoOutputDataBuffer : IDisposable
	{
		[MarshalAs(UnmanagedType.Interface)]
		private IMediaBuffer pBuffer;

		private DmoOutputDataBufferFlags dwStatus;

		private long rtTimestamp;

		private long referenceTimeDuration;

		public IMediaBuffer MediaBuffer
		{
			get
			{
				return pBuffer;
			}
			internal set
			{
				pBuffer = value;
			}
		}

		public int Length => ((MediaBuffer)pBuffer).Length;

		public DmoOutputDataBufferFlags StatusFlags
		{
			get
			{
				return dwStatus;
			}
			internal set
			{
				dwStatus = value;
			}
		}

		public long Timestamp
		{
			get
			{
				return rtTimestamp;
			}
			internal set
			{
				rtTimestamp = value;
			}
		}

		public long Duration
		{
			get
			{
				return referenceTimeDuration;
			}
			internal set
			{
				referenceTimeDuration = value;
			}
		}

		public bool MoreDataAvailable => (StatusFlags & DmoOutputDataBufferFlags.Incomplete) == DmoOutputDataBufferFlags.Incomplete;

		public DmoOutputDataBuffer(int maxBufferSize)
		{
			pBuffer = new MediaBuffer(maxBufferSize);
			dwStatus = DmoOutputDataBufferFlags.None;
			rtTimestamp = 0L;
			referenceTimeDuration = 0L;
		}

		public void Dispose()
		{
			if (pBuffer != null)
			{
				((MediaBuffer)pBuffer).Dispose();
				pBuffer = null;
				GC.SuppressFinalize(this);
			}
		}

		public void RetrieveData(byte[] data, int offset)
		{
			((MediaBuffer)pBuffer).RetrieveData(data, offset);
		}
	}
	[Flags]
	public enum DmoOutputDataBufferFlags
	{
		None = 0,
		SyncPoint = 1,
		Time = 2,
		TimeLength = 4,
		Incomplete = 0x1000000
	}
	internal struct DmoPartialMediaType
	{
		private Guid type;

		private Guid subtype;

		public Guid Type
		{
			get
			{
				return type;
			}
			internal set
			{
				type = value;
			}
		}

		public Guid Subtype
		{
			get
			{
				return subtype;
			}
			internal set
			{
				subtype = value;
			}
		}
	}
	[Flags]
	public enum DmoProcessOutputFlags
	{
		None = 0,
		DiscardWhenNoBuffer = 1
	}
	[Flags]
	internal enum DmoSetTypeFlags
	{
		None = 0,
		DMO_SET_TYPEF_TEST_ONLY = 1,
		DMO_SET_TYPEF_CLEAR = 2
	}
	[ComImport]
	[Guid("2c3cd98a-2bfa-4a53-9c27-5249ba64ba0f")]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	internal interface IEnumDmo
	{
		int Next(int itemsToFetch, out Guid clsid, out IntPtr name, out int itemsFetched);

		int Skip(int itemsToSkip);

		int Reset();

		int Clone(out IEnumDmo enumPointer);
	}
	[ComImport]
	[SuppressUnmanagedCodeSecurity]
	[Guid("59eff8b9-938c-4a26-82f2-95cb84cdc837")]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	public interface IMediaBuffer
	{
		[PreserveSig]
		int SetLength(int length);

		[PreserveSig]
		int GetMaxLength(out int maxLength);

		[PreserveSig]
		int GetBufferAndLength(IntPtr bufferPointerPointer, IntPtr validDataLengthPointer);
	}
	[ComImport]
	[SuppressUnmanagedCodeSecurity]
	[Guid("d8ad0f58-5494-4102-97c5-ec798e59bcf4")]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	internal interface IMediaObject
	{
		[PreserveSig]
		int GetStreamCount(out int inputStreams, out int outputStreams);

		[PreserveSig]
		int GetInputStreamInfo(int inputStreamIndex, out InputStreamInfoFlags flags);

		[PreserveSig]
		int GetOutputStreamInfo(int outputStreamIndex, out OutputStreamInfoFlags flags);

		[PreserveSig]
		int GetInputType(int inputStreamIndex, int typeIndex, out DmoMediaType mediaType);

		[PreserveSig]
		int GetOutputType(int outputStreamIndex, int typeIndex, out DmoMediaType mediaType);

		[PreserveSig]
		int SetInputType(int inputStreamIndex, [In] ref DmoMediaType mediaType, DmoSetTypeFlags flags);

		[PreserveSig]
		int SetOutputType(int outputStreamIndex, [In] ref DmoMediaType mediaType, DmoSetTypeFlags flags);

		[PreserveSig]
		int GetInputCurrentType(int inputStreamIndex, out DmoMediaType mediaType);

		[PreserveSig]
		int GetOutputCurrentType(int outputStreamIndex, out DmoMediaType mediaType);

		[PreserveSig]
		int GetInputSizeInfo(int inputStreamIndex, out int size, out int maxLookahead, out int alignment);

		[PreserveSig]
		int GetOutputSizeInfo(int outputStreamIndex, out int size, out int alignment);

		[PreserveSig]
		int GetInputMaxLatency(int inputStreamIndex, out long referenceTimeMaxLatency);

		[PreserveSig]
		int SetInputMaxLatency(int inputStreamIndex, long referenceTimeMaxLatency);

		[PreserveSig]
		int Flush();

		[PreserveSig]
		int Discontinuity(int inputStreamIndex);

		[PreserveSig]
		int AllocateStreamingResources();

		[PreserveSig]
		int FreeStreamingResources();

		[PreserveSig]
		int GetInputStatus(int inputStreamIndex, out DmoInputStatusFlags flags);

		[PreserveSig]
		int ProcessInput(int inputStreamIndex, [In] IMediaBuffer mediaBuffer, DmoInputDataBufferFlags flags, long referenceTimeTimestamp, long referenceTimeDuration);

		[PreserveSig]
		int ProcessOutput(DmoProcessOutputFlags flags, int outputBufferCount, [In][Out][MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] DmoOutputDataBuffer[] outputBuffers, out int statusReserved);

		[PreserveSig]
		int Lock(bool acquireLock);
	}
	[ComImport]
	[SuppressUnmanagedCodeSecurity]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	[Guid("651B9AD0-0FC7-4AA9-9538-D89931010741")]
	internal interface IMediaObjectInPlace
	{
		[PreserveSig]
		int Process([In] int size, [In] IntPtr data, [In] long refTimeStart, [In] DmoInPlaceProcessFlags dwFlags);

		[PreserveSig]
		int Clone([MarshalAs(UnmanagedType.Interface)] out IMediaObjectInPlace mediaObjectInPlace);

		[PreserveSig]
		int GetLatency(out long latencyTime);
	}
	[ComImport]
	[SuppressUnmanagedCodeSecurity]
	[Guid("6d6cbb60-a223-44aa-842f-a2f06750be6d")]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	internal interface IMediaParamInfo
	{
		[PreserveSig]
		int GetParamCount(out int paramCount);

		[PreserveSig]
		int GetParamInfo(int paramIndex, ref MediaParamInfo paramInfo);

		[PreserveSig]
		int GetParamText(int paramIndex, out IntPtr paramText);

		[PreserveSig]
		int GetNumTimeFormats(out int numTimeFormats);

		[PreserveSig]
		int GetSupportedTimeFormat(int formatIndex, out Guid guidTimeFormat);

		[PreserveSig]
		int GetCurrentTimeFormat(out Guid guidTimeFormat, out int mediaTimeData);
	}
	[Flags]
	internal enum InputStreamInfoFlags
	{
		None = 0,
		DMO_INPUT_STREAMF_WHOLE_SAMPLES = 1,
		DMO_INPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER = 2,
		DMO_INPUT_STREAMF_FIXED_SAMPLE_SIZE = 4,
		DMO_INPUT_STREAMF_HOLDS_BUFFERS = 8
	}
	[ComImport]
	[Guid("E7E9984F-F09F-4da4-903F-6E2E0EFE56B5")]
	[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	internal interface IWMResamplerProps
	{
		int SetHalfFilterLength(int outputQuality);

		int SetUserChannelMtx([In] float[] channelConversionMatrix);
	}
	public class MediaBuffer : IMediaBuffer, IDisposable
	{
		private IntPtr buffer;

		private int length;

		private readonly int maxLength;

		public int Length
		{
			get
			{
				return length;
			}
			set
			{
				if (length > maxLength)
				{
					throw new ArgumentException("Cannot be greater than maximum buffer size");
				}
				length = value;
			}
		}

		public MediaBuffer(int maxLength)
		{
			buffer = Marshal.AllocCoTaskMem(maxLength);
			this.maxLength = maxLength;
		}

		public void Dispose()
		{
			if (buffer != IntPtr.Zero)
			{
				Marshal.FreeCoTaskMem(buffer);
				buffer = IntPtr.Zero;
				GC.SuppressFinalize(this);
			}
		}

		~MediaBuffer()
		{
			Dispose();
		}

		int IMediaBuffer.SetLength(int length)
		{
			if (length > maxLength)
			{
				return -2147483645;
			}
			this.length = length;
			return 0;
		}

		int IMediaBuffer.GetMaxLength(out int maxLength)
		{
			maxLength = this.maxLength;
			return 0;
		}

		int IMediaBuffer.GetBufferAndLength(IntPtr bufferPointerPointer, IntPtr validDataLengthPointer)
		{
			if (bufferPointerPointer != IntPtr.Zero)
			{
				Marshal.WriteIntPtr(bufferPointerPointer, buffer);
			}
			if (validDataLengthPointer != IntPtr.Zero)
			{
				Marshal.WriteInt32(validDataLengthPointer, length);
			}
			return 0;
		}

		public void LoadData(byte[] data, int bytes)
		{
			Length = bytes;
			Marshal.Copy(data, 0, buffer, bytes);
		}

		public void RetrieveData(byte[] data, int offset)
		{
			Marshal.Copy(buffer, data, offset, Length);
		}
	}
	public class MediaObject : IDisposable
	{
		private IMediaObject mediaObject;

		private readonly int inputStreams;

		private readonly int outputStreams;

		public int InputStreamCount => inputStreams;

		public int OutputStreamCount => outputStreams;

		internal MediaObject(IMediaObject mediaObject)
		{
			this.mediaObject = mediaObject;
			mediaObject.GetStreamCount(out inputStreams, out outputStreams);
		}

		public DmoMediaType? GetInputType(int inputStream, int inputTypeIndex)
		{
			try
			{
				if (mediaObject.GetInputType(inputStream, inputTypeIndex, out var mediaType) == 0)
				{
					DmoInterop.MoFreeMediaType(ref mediaType);
					return mediaType;
				}
			}
			catch (COMException ex)
			{
				if (HResult.GetHResult(ex) != -2147220986)
				{
					throw;
				}
			}
			return null;
		}

		public DmoMediaType? GetOutputType(int outputStream, int outputTypeIndex)
		{
			try
			{
				if (mediaObject.GetOutputType(outputStream, outputTypeIndex, out var mediaType) == 0)
				{
					DmoInterop.MoFreeMediaType(ref mediaType);
					return mediaType;
				}
			}
			catch (COMException ex)
			{
				if (HResult.GetHResult(ex) != -2147220986)
				{
					throw;
				}
			}
			return null;
		}

		public DmoMediaType GetOutputCurrentType(int outputStreamIndex)
		{
			DmoMediaType mediaType;
			int outputCurrentType = mediaObject.GetOutputCurrentType(outputStreamIndex, out mediaType);
			switch (outputCurrentType)
			{
			case 0:
				DmoInterop.MoFreeMediaType(ref mediaType);
				return mediaType;
			case -2147220989:
				throw new InvalidOperationException("Media type was not set.");
			default:
				throw Marshal.GetExceptionForHR(outputCurrentType);
			}
		}

		public IEnumerable<DmoMediaType> GetInputTypes(int inputStreamIndex)
		{
			int typeIndex = 0;
			while (true)
			{
				DmoMediaType? inputType;
				DmoMediaType? dmoMediaType = (inputType = GetInputType(inputStreamIndex, typeIndex));
				if (dmoMediaType.HasValue)
				{
					yield return inputType.Value;
					typeIndex++;
					continue;
				}
				break;
			}
		}

		public IEnumerable<DmoMediaType> GetOutputTypes(int outputStreamIndex)
		{
			int typeIndex = 0;
			while (true)
			{
				DmoMediaType? outputType;
				DmoMediaType? dmoMediaType = (outputType = GetOutputType(outputStreamIndex, typeIndex));
				if (dmoMediaType.HasValue)
				{
					yield return outputType.Value;
					typeIndex++;
					continue;
				}
				break;
			}
		}

		public bool SupportsInputType(int inputStreamIndex, DmoMediaType mediaType)
		{
			return SetInputType(inputStreamIndex, mediaType, DmoSetTypeFlags.DMO_SET_TYPEF_TEST_ONLY);
		}

		private bool SetInputType(int inputStreamIndex, DmoMediaType mediaType, DmoSetTypeFlags flags)
		{
			switch (mediaObject.SetInputType(inputStreamIndex, ref mediaType, flags))
			{
			case -2147220991:
				throw new ArgumentException("Invalid stream index");
			default:
				_ = -2147220987;
				return false;
			case 0:
				return true;
			}
		}

		public void SetInputType(int inputStreamIndex, DmoMediaType mediaType)
		{
			if (!SetInputType(inputStreamIndex, mediaType, DmoSetTypeFlags.None))
			{
				throw new ArgumentException("Media Type not supported");
			}
		}

		public void SetInputWaveFormat(int inputStreamIndex, WaveFormat waveFormat)
		{
			DmoMediaType mediaType = CreateDmoMediaTypeForWaveFormat(waveFormat);
			bool num = SetInputType(inputStreamIndex, mediaType, DmoSetTypeFlags.None);
			DmoInterop.MoFreeMediaType(ref mediaType);
			if (!num)
			{
				throw new ArgumentException("Media Type not supported");
			}
		}

		public bool SupportsInputWaveFormat(int inputStreamIndex, WaveFormat waveFormat)
		{
			DmoMediaType mediaType = CreateDmoMediaTypeForWaveFormat(waveFormat);
			bool result = SetInputType(inputStreamIndex, mediaType, DmoSetTypeFlags.DMO_SET_TYPEF_TEST_ONLY);
			DmoInterop.MoFreeMediaType(ref mediaType);
			return result;
		}

		private DmoMediaType CreateDmoMediaTypeForWaveFormat(WaveFormat

Mods/RealRadio/NAudio.WinForms.dll

Decompiled a day ago
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Threading;
using System.Windows.Forms;
using NAudio.Mixer;
using NAudio.Wave;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("Mark Heath")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("© Mark Heath 2023")]
[assembly: AssemblyFileVersion("2.2.1.0")]
[assembly: AssemblyInformationalVersion("2.2.1")]
[assembly: AssemblyProduct("NAudio.WinForms")]
[assembly: AssemblyTitle("NAudio.WinForms")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/naudio/NAudio")]
[assembly: AssemblyVersion("2.2.1.0")]
namespace NAudio.Wave
{
	public class WaveCallbackInfo
	{
		private WaveWindow waveOutWindow;

		private WaveWindowNative waveOutWindowNative;

		public WaveCallbackStrategy Strategy { get; private set; }

		public IntPtr Handle { get; private set; }

		public static WaveCallbackInfo FunctionCallback()
		{
			return new WaveCallbackInfo((WaveCallbackStrategy)0, IntPtr.Zero);
		}

		public static WaveCallbackInfo NewWindow()
		{
			return new WaveCallbackInfo((WaveCallbackStrategy)1, IntPtr.Zero);
		}

		public static WaveCallbackInfo ExistingWindow(IntPtr handle)
		{
			if (handle == IntPtr.Zero)
			{
				throw new ArgumentException("Handle cannot be zero");
			}
			return new WaveCallbackInfo((WaveCallbackStrategy)2, handle);
		}

		private WaveCallbackInfo(WaveCallbackStrategy strategy, IntPtr handle)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			Strategy = strategy;
			Handle = handle;
		}

		internal void Connect(WaveCallback callback)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Invalid comparison between Unknown and I4
			if ((int)Strategy == 1)
			{
				waveOutWindow = new WaveWindow(callback);
				((Control)waveOutWindow).CreateControl();
				Handle = ((Control)waveOutWindow).Handle;
			}
			else if ((int)Strategy == 2)
			{
				waveOutWindowNative = new WaveWindowNative(callback);
				((NativeWindow)waveOutWindowNative).AssignHandle(Handle);
			}
		}

		internal MmResult WaveOutOpen(out IntPtr waveOutHandle, int deviceNumber, WaveFormat waveFormat, WaveCallback callback)
		{
			//IL_0001: 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_0041: 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_0021: 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)
			if ((int)Strategy == 0)
			{
				return WaveInterop.waveOutOpen(ref waveOutHandle, (IntPtr)deviceNumber, waveFormat, callback, IntPtr.Zero, (WaveInOutOpenFlags)196608);
			}
			return WaveInterop.waveOutOpenWindow(ref waveOutHandle, (IntPtr)deviceNumber, waveFormat, Handle, IntPtr.Zero, (WaveInOutOpenFlags)65536);
		}

		internal MmResult WaveInOpen(out IntPtr waveInHandle, int deviceNumber, WaveFormat waveFormat, WaveCallback callback)
		{
			//IL_0001: 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_0041: 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_0021: 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)
			if ((int)Strategy == 0)
			{
				return WaveInterop.waveInOpen(ref waveInHandle, (IntPtr)deviceNumber, waveFormat, callback, IntPtr.Zero, (WaveInOutOpenFlags)196608);
			}
			return WaveInterop.waveInOpenWindow(ref waveInHandle, (IntPtr)deviceNumber, waveFormat, Handle, IntPtr.Zero, (WaveInOutOpenFlags)65536);
		}

		internal void Disconnect()
		{
			if (waveOutWindow != null)
			{
				((Form)waveOutWindow).Close();
				waveOutWindow = null;
			}
			if (waveOutWindowNative != null)
			{
				((NativeWindow)waveOutWindowNative).ReleaseHandle();
				waveOutWindowNative = null;
			}
		}
	}
	public class WaveIn : IWaveIn, IDisposable
	{
		private IntPtr waveInHandle;

		private volatile bool recording;

		private WaveInBuffer[] buffers;

		private readonly WaveCallback callback;

		private WaveCallbackInfo callbackInfo;

		private readonly SynchronizationContext syncContext;

		private int lastReturnedBufferIndex;

		public static int DeviceCount => WaveInterop.waveInGetNumDevs();

		public int BufferMilliseconds { get; set; }

		public int NumberOfBuffers { get; set; }

		public int DeviceNumber { get; set; }

		public WaveFormat WaveFormat { get; set; }

		public event EventHandler<WaveInEventArgs> DataAvailable;

		public event EventHandler<StoppedEventArgs> RecordingStopped;

		public WaveIn()
			: this(WaveCallbackInfo.NewWindow())
		{
		}

		public WaveIn(IntPtr windowHandle)
			: this(WaveCallbackInfo.ExistingWindow(windowHandle))
		{
		}

		public WaveIn(WaveCallbackInfo callbackInfo)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			syncContext = SynchronizationContext.Current;
			if (((int)callbackInfo.Strategy == 1 || (int)callbackInfo.Strategy == 2) && syncContext == null)
			{
				throw new InvalidOperationException("Use WaveInEvent to record on a background thread");
			}
			DeviceNumber = 0;
			WaveFormat = new WaveFormat(8000, 16, 1);
			BufferMilliseconds = 100;
			NumberOfBuffers = 3;
			callback = new WaveCallback(Callback);
			this.callbackInfo = callbackInfo;
			callbackInfo.Connect(callback);
		}

		public static WaveInCapabilities GetCapabilities(int devNumber)
		{
			//IL_0002: 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_0018: 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)
			WaveInCapabilities val = default(WaveInCapabilities);
			int num = Marshal.SizeOf<WaveInCapabilities>(val);
			MmException.Try(WaveInterop.waveInGetDevCaps((IntPtr)devNumber, ref val, num), "waveInGetDevCaps");
			return val;
		}

		private void CreateBuffers()
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			int num = BufferMilliseconds * WaveFormat.AverageBytesPerSecond / 1000;
			if (num % WaveFormat.BlockAlign != 0)
			{
				num -= num % WaveFormat.BlockAlign;
			}
			buffers = (WaveInBuffer[])(object)new WaveInBuffer[NumberOfBuffers];
			for (int i = 0; i < buffers.Length; i++)
			{
				buffers[i] = new WaveInBuffer(waveInHandle, num);
			}
		}

		private void Callback(IntPtr waveInHandle, WaveMessage message, IntPtr userData, WaveHeader waveHeader, IntPtr reserved)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			if ((int)message != 960 || !recording)
			{
				return;
			}
			WaveInBuffer val = (WaveInBuffer)((GCHandle)waveHeader.userData).Target;
			if (val != null)
			{
				lastReturnedBufferIndex = Array.IndexOf(buffers, val);
				RaiseDataAvailable(val);
				try
				{
					val.Reuse();
				}
				catch (Exception e)
				{
					recording = false;
					RaiseRecordingStopped(e);
				}
			}
		}

		private void RaiseDataAvailable(WaveInBuffer buffer)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			this.DataAvailable?.Invoke(this, new WaveInEventArgs(buffer.Data, buffer.BytesRecorded));
		}

		private void RaiseRecordingStopped(Exception e)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			EventHandler<StoppedEventArgs> handler = this.RecordingStopped;
			if (handler == null)
			{
				return;
			}
			if (syncContext == null)
			{
				handler(this, new StoppedEventArgs(e));
				return;
			}
			syncContext.Post(delegate
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Expected O, but got Unknown
				handler(this, new StoppedEventArgs(e));
			}, null);
		}

		private void OpenWaveInDevice()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			CloseWaveInDevice();
			MmException.Try(callbackInfo.WaveInOpen(out waveInHandle, DeviceNumber, WaveFormat, callback), "waveInOpen");
			CreateBuffers();
		}

		public void StartRecording()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (recording)
			{
				throw new InvalidOperationException("Already recording");
			}
			OpenWaveInDevice();
			EnqueueBuffers();
			MmException.Try(WaveInterop.waveInStart(waveInHandle), "waveInStart");
			recording = true;
		}

		private void EnqueueBuffers()
		{
			WaveInBuffer[] array = buffers;
			foreach (WaveInBuffer val in array)
			{
				if (!val.InQueue)
				{
					val.Reuse();
				}
			}
		}

		public void StopRecording()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (!recording)
			{
				return;
			}
			recording = false;
			MmException.Try(WaveInterop.waveInStop(waveInHandle), "waveInStop");
			for (int i = 0; i < buffers.Length; i++)
			{
				int num = (i + lastReturnedBufferIndex + 1) % buffers.Length;
				WaveInBuffer val = buffers[num];
				if (val.Done)
				{
					RaiseDataAvailable(val);
				}
			}
			RaiseRecordingStopped(null);
		}

		public long GetPosition()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_002d: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			MmTime val = default(MmTime);
			val.wType = 4u;
			MmException.Try(WaveInterop.waveInGetPosition(waveInHandle, ref val, Marshal.SizeOf<MmTime>(val)), "waveInGetPosition");
			if (val.wType != 4)
			{
				throw new Exception($"waveInGetPosition: wType -> Expected {4}, Received {val.wType}");
			}
			return val.cb;
		}

		protected virtual void Dispose(bool disposing)
		{
			if (disposing)
			{
				if (recording)
				{
					StopRecording();
				}
				CloseWaveInDevice();
				if (callbackInfo != null)
				{
					callbackInfo.Disconnect();
					callbackInfo = null;
				}
			}
		}

		private void CloseWaveInDevice()
		{
			//IL_0019: 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)
			if (waveInHandle == IntPtr.Zero)
			{
				return;
			}
			WaveInterop.waveInReset(waveInHandle);
			if (buffers != null)
			{
				for (int i = 0; i < buffers.Length; i++)
				{
					buffers[i].Dispose();
				}
				buffers = null;
			}
			WaveInterop.waveInClose(waveInHandle);
			waveInHandle = IntPtr.Zero;
		}

		public MixerLine GetMixerLine()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			if (waveInHandle != IntPtr.Zero)
			{
				return new MixerLine(waveInHandle, 0, (MixerFlags)(-1610612736));
			}
			return new MixerLine((IntPtr)DeviceNumber, 0, (MixerFlags)536870912);
		}

		public void Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}
	}
	public class WaveOut : IWavePlayer, IDisposable, IWavePosition
	{
		private IntPtr hWaveOut;

		private WaveOutBuffer[] buffers;

		private IWaveProvider waveStream;

		private volatile PlaybackState playbackState;

		private readonly WaveCallback callback;

		private readonly WaveCallbackInfo callbackInfo;

		private readonly object waveOutLock;

		private int queuedBuffers;

		private readonly SynchronizationContext syncContext;

		public static int DeviceCount => WaveInterop.waveOutGetNumDevs();

		public int DesiredLatency { get; set; }

		public int NumberOfBuffers { get; set; }

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


		public WaveFormat OutputWaveFormat => waveStream.WaveFormat;

		public PlaybackState PlaybackState => playbackState;

		public float Volume
		{
			get
			{
				return WaveOutUtils.GetWaveOutVolume(hWaveOut, waveOutLock);
			}
			set
			{
				WaveOutUtils.SetWaveOutVolume(value, hWaveOut, waveOutLock);
			}
		}

		public event EventHandler<StoppedEventArgs> PlaybackStopped;

		public static WaveOutCapabilities GetCapabilities(int devNumber)
		{
			//IL_0002: 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_0018: 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)
			WaveOutCapabilities val = default(WaveOutCapabilities);
			int num = Marshal.SizeOf<WaveOutCapabilities>(val);
			MmException.Try(WaveInterop.waveOutGetDevCaps((IntPtr)devNumber, ref val, num), "waveOutGetDevCaps");
			return val;
		}

		public WaveOut()
			: this((SynchronizationContext.Current == null) ? WaveCallbackInfo.FunctionCallback() : WaveCallbackInfo.NewWindow())
		{
		}

		public WaveOut(IntPtr windowHandle)
			: this(WaveCallbackInfo.ExistingWindow(windowHandle))
		{
		}

		public WaveOut(WaveCallbackInfo callbackInfo)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			syncContext = SynchronizationContext.Current;
			DesiredLatency = 300;
			NumberOfBuffers = 2;
			callback = new WaveCallback(Callback);
			waveOutLock = new object();
			this.callbackInfo = callbackInfo;
			callbackInfo.Connect(callback);
		}

		public void Init(IWaveProvider waveProvider)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Expected O, but got Unknown
			waveStream = waveProvider;
			int num = waveProvider.WaveFormat.ConvertLatencyToByteSize((DesiredLatency + NumberOfBuffers - 1) / NumberOfBuffers);
			MmResult val;
			lock (waveOutLock)
			{
				val = callbackInfo.WaveOutOpen(out hWaveOut, DeviceNumber, waveStream.WaveFormat, callback);
			}
			MmException.Try(val, "waveOutOpen");
			buffers = (WaveOutBuffer[])(object)new WaveOutBuffer[NumberOfBuffers];
			playbackState = (PlaybackState)0;
			for (int i = 0; i < NumberOfBuffers; i++)
			{
				buffers[i] = new WaveOutBuffer(hWaveOut, num, waveStream, waveOutLock);
			}
		}

		public void Play()
		{
			//IL_0001: 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_0023: Invalid comparison between Unknown and I4
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if ((int)playbackState == 0)
			{
				playbackState = (PlaybackState)1;
				EnqueueBuffers();
			}
			else if ((int)playbackState == 2)
			{
				EnqueueBuffers();
				Resume();
				playbackState = (PlaybackState)1;
			}
		}

		private void EnqueueBuffers()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < NumberOfBuffers; i++)
			{
				if (!buffers[i].InQueue)
				{
					if (!buffers[i].OnDone())
					{
						playbackState = (PlaybackState)0;
						break;
					}
					Interlocked.Increment(ref queuedBuffers);
				}
			}
		}

		public void Pause()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if ((int)playbackState == 1)
			{
				playbackState = (PlaybackState)2;
				MmResult val;
				lock (waveOutLock)
				{
					val = WaveInterop.waveOutPause(hWaveOut);
				}
				if ((int)val != 0)
				{
					throw new MmException(val, "waveOutPause");
				}
			}
		}

		public void Resume()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			//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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			if ((int)playbackState == 2)
			{
				MmResult val;
				lock (waveOutLock)
				{
					val = WaveInterop.waveOutRestart(hWaveOut);
				}
				if ((int)val != 0)
				{
					throw new MmException(val, "waveOutRestart");
				}
				playbackState = (PlaybackState)1;
			}
		}

		public void Stop()
		{
			//IL_0001: 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_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)
			//IL_003c: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if ((int)playbackState != 0)
			{
				playbackState = (PlaybackState)0;
				MmResult val;
				lock (waveOutLock)
				{
					val = WaveInterop.waveOutReset(hWaveOut);
				}
				if ((int)val != 0)
				{
					throw new MmException(val, "waveOutReset");
				}
				if ((int)callbackInfo.Strategy == 0)
				{
					RaisePlaybackStoppedEvent(null);
				}
			}
		}

		public long GetPosition()
		{
			return WaveOutUtils.GetPositionBytes(hWaveOut, waveOutLock);
		}

		public void Dispose()
		{
			GC.SuppressFinalize(this);
			Dispose(disposing: true);
		}

		protected void Dispose(bool disposing)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			Stop();
			if (disposing && buffers != null)
			{
				for (int i = 0; i < buffers.Length; i++)
				{
					if (buffers[i] != null)
					{
						buffers[i].Dispose();
					}
				}
				buffers = null;
			}
			lock (waveOutLock)
			{
				WaveInterop.waveOutClose(hWaveOut);
			}
			if (disposing)
			{
				callbackInfo.Disconnect();
			}
		}

		~WaveOut()
		{
			Dispose(disposing: false);
		}

		private void Callback(IntPtr hWaveOut, WaveMessage uMsg, IntPtr dwInstance, WaveHeader wavhdr, IntPtr dwReserved)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Invalid comparison between Unknown and I4
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			if ((int)uMsg != 957)
			{
				return;
			}
			WaveOutBuffer val = (WaveOutBuffer)((GCHandle)wavhdr.userData).Target;
			Interlocked.Decrement(ref queuedBuffers);
			Exception e = null;
			if ((int)PlaybackState == 1)
			{
				lock (waveOutLock)
				{
					try
					{
						if (val.OnDone())
						{
							Interlocked.Increment(ref queuedBuffers);
						}
					}
					catch (Exception ex)
					{
						e = ex;
					}
				}
			}
			if (queuedBuffers == 0 && ((int)callbackInfo.Strategy != 0 || (int)playbackState != 0))
			{
				playbackState = (PlaybackState)0;
				RaisePlaybackStoppedEvent(e);
			}
		}

		private void RaisePlaybackStoppedEvent(Exception e)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			EventHandler<StoppedEventArgs> handler = this.PlaybackStopped;
			if (handler == null)
			{
				return;
			}
			if (syncContext == null)
			{
				handler(this, new StoppedEventArgs(e));
				return;
			}
			syncContext.Post(delegate
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Expected O, but got Unknown
				handler(this, new StoppedEventArgs(e));
			}, null);
		}
	}
	internal class WaveWindowNative : NativeWindow
	{
		private WaveCallback waveCallback;

		public WaveWindowNative(WaveCallback waveCallback)
		{
			this.waveCallback = waveCallback;
		}

		protected override void WndProc(ref Message m)
		{
			//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)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected I4, but got Unknown
			//IL_006b: 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)
			//IL_003a: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			WaveMessage val = (WaveMessage)((Message)(ref m)).Msg;
			switch (val - 955)
			{
			case 2:
			case 5:
			{
				IntPtr wParam = ((Message)(ref m)).WParam;
				WaveHeader val2 = new WaveHeader();
				Marshal.PtrToStructure<WaveHeader>(((Message)(ref m)).LParam, val2);
				waveCallback.Invoke(wParam, val, IntPtr.Zero, val2, IntPtr.Zero);
				break;
			}
			case 0:
			case 1:
			case 3:
			case 4:
				waveCallback.Invoke(((Message)(ref m)).WParam, val, IntPtr.Zero, (WaveHeader)null, IntPtr.Zero);
				break;
			default:
				((NativeWindow)this).WndProc(ref m);
				break;
			}
		}
	}
	internal class WaveWindow : Form
	{
		private WaveCallback waveCallback;

		public WaveWindow(WaveCallback waveCallback)
		{
			this.waveCallback = waveCallback;
		}

		protected override void WndProc(ref Message m)
		{
			//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)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected I4, but got Unknown
			//IL_006b: 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)
			//IL_003a: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			WaveMessage val = (WaveMessage)((Message)(ref m)).Msg;
			switch (val - 955)
			{
			case 2:
			case 5:
			{
				IntPtr wParam = ((Message)(ref m)).WParam;
				WaveHeader val2 = new WaveHeader();
				Marshal.PtrToStructure<WaveHeader>(((Message)(ref m)).LParam, val2);
				waveCallback.Invoke(wParam, val, IntPtr.Zero, val2, IntPtr.Zero);
				break;
			}
			case 0:
			case 1:
			case 3:
			case 4:
				waveCallback.Invoke(((Message)(ref m)).WParam, val, IntPtr.Zero, (WaveHeader)null, IntPtr.Zero);
				break;
			default:
				((Form)this).WndProc(ref m);
				break;
			}
		}
	}
}
namespace NAudio.Utils
{
	public class ProgressLog : UserControl
	{
		private delegate void LogMessageDelegate(Color color, string message);

		private delegate void ClearLogDelegate();

		private IContainer components;

		private RichTextBox richTextBoxLog;

		public string Text => ((Control)richTextBoxLog).Text;

		public ProgressLog()
		{
			InitializeComponent();
		}

		public void LogMessage(Color color, string message)
		{
			if (((Control)richTextBoxLog).InvokeRequired)
			{
				((Control)this).Invoke((Delegate)new LogMessageDelegate(LogMessage), new object[2] { color, message });
			}
			else
			{
				((TextBoxBase)richTextBoxLog).SelectionStart = ((TextBoxBase)richTextBoxLog).TextLength;
				richTextBoxLog.SelectionColor = color;
				((TextBoxBase)richTextBoxLog).AppendText(message);
				((TextBoxBase)richTextBoxLog).AppendText(Environment.NewLine);
			}
		}

		public void ClearLog()
		{
			if (((Control)richTextBoxLog).InvokeRequired)
			{
				((Control)this).Invoke((Delegate)new ClearLogDelegate(ClearLog), new object[0]);
			}
			else
			{
				((TextBoxBase)richTextBoxLog).Clear();
			}
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing && components != null)
			{
				components.Dispose();
			}
			((ContainerControl)this).Dispose(disposing);
		}

		private void InitializeComponent()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			richTextBoxLog = new RichTextBox();
			((Control)this).SuspendLayout();
			((TextBoxBase)richTextBoxLog).BorderStyle = (BorderStyle)0;
			((Control)richTextBoxLog).Dock = (DockStyle)5;
			((Control)richTextBoxLog).Location = new Point(1, 1);
			((Control)richTextBoxLog).Name = "richTextBoxLog";
			((TextBoxBase)richTextBoxLog).ReadOnly = true;
			((Control)richTextBoxLog).Size = new Size(311, 129);
			((Control)richTextBoxLog).TabIndex = 0;
			((Control)richTextBoxLog).Text = "";
			((ContainerControl)this).AutoScaleDimensions = new SizeF(6f, 13f);
			((ContainerControl)this).AutoScaleMode = (AutoScaleMode)1;
			((Control)this).BackColor = SystemColors.ControlDarkDark;
			((Control)this).Controls.Add((Control)(object)richTextBoxLog);
			((Control)this).Name = "ProgressLog";
			((Control)this).Padding = new Padding(1);
			((Control)this).Size = new Size(313, 131);
			((Control)this).ResumeLayout(false);
		}
	}
}
namespace NAudio.WinForms.Gui
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Fader
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					resourceMan = new ResourceManager("NAudio.WinForms.Gui.Fader", typeof(Fader).Assembly);
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal Fader()
		{
		}
	}
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class PanSlider
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					resourceMan = new ResourceManager("NAudio.WinForms.Gui.PanSlider", typeof(PanSlider).Assembly);
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal PanSlider()
		{
		}
	}
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class VolumeSlider
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					resourceMan = new ResourceManager("NAudio.WinForms.Gui.VolumeSlider", typeof(VolumeSlider).Assembly);
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal VolumeSlider()
		{
		}
	}
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class WaveViewer
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					resourceMan = new ResourceManager("NAudio.WinForms.Gui.WaveViewer", typeof(WaveViewer).Assembly);
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal WaveViewer()
		{
		}
	}
}
namespace NAudio.Gui
{
	public class Fader : Control
	{
		private int minimum;

		private int maximum;

		private float percent;

		private Orientation orientation;

		private Container components;

		private readonly int SliderHeight = 30;

		private readonly int SliderWidth = 15;

		private Rectangle sliderRectangle;

		private bool dragging;

		private int dragY;

		public int Minimum
		{
			get
			{
				return minimum;
			}
			set
			{
				minimum = value;
			}
		}

		public int Maximum
		{
			get
			{
				return maximum;
			}
			set
			{
				maximum = value;
			}
		}

		public int Value
		{
			get
			{
				return (int)(percent * (float)(maximum - minimum)) + minimum;
			}
			set
			{
				percent = (float)(value - minimum) / (float)(maximum - minimum);
			}
		}

		public Orientation Orientation
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return orientation;
			}
			set
			{
				//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)
				orientation = value;
			}
		}

		public Fader()
		{
			InitializeComponent();
			((Control)this).SetStyle((ControlStyles)73730, true);
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing && components != null)
			{
				components.Dispose();
			}
			((Control)this).Dispose(disposing);
		}

		private void DrawSlider(Graphics g)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			Brush val = (Brush)new SolidBrush(Color.White);
			Pen val2 = new Pen(Color.Black);
			sliderRectangle.X = (((Control)this).Width - SliderWidth) / 2;
			sliderRectangle.Width = SliderWidth;
			sliderRectangle.Y = (int)((float)(((Control)this).Height - SliderHeight) * percent);
			sliderRectangle.Height = SliderHeight;
			g.FillRectangle(val, sliderRectangle);
			g.DrawLine(val2, sliderRectangle.Left, sliderRectangle.Top + sliderRectangle.Height / 2, sliderRectangle.Right, sliderRectangle.Top + sliderRectangle.Height / 2);
			val.Dispose();
			val2.Dispose();
		}

		protected override void OnPaint(PaintEventArgs e)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			Graphics graphics = e.Graphics;
			if ((int)Orientation == 1)
			{
				Brush val = (Brush)new SolidBrush(Color.Black);
				graphics.FillRectangle(val, ((Control)this).Width / 2, SliderHeight / 2, 2, ((Control)this).Height - SliderHeight);
				val.Dispose();
				DrawSlider(graphics);
			}
			((Control)this).OnPaint(e);
		}

		protected override void OnMouseDown(MouseEventArgs e)
		{
			if (sliderRectangle.Contains(e.X, e.Y))
			{
				dragging = true;
				dragY = e.Y - sliderRectangle.Y;
			}
			((Control)this).OnMouseDown(e);
		}

		protected override void OnMouseMove(MouseEventArgs e)
		{
			if (dragging)
			{
				int num = e.Y - dragY;
				if (num < 0)
				{
					percent = 0f;
				}
				else if (num > ((Control)this).Height - SliderHeight)
				{
					percent = 1f;
				}
				else
				{
					percent = (float)num / (float)(((Control)this).Height - SliderHeight);
				}
				((Control)this).Invalidate();
			}
			((Control)this).OnMouseMove(e);
		}

		protected override void OnMouseUp(MouseEventArgs e)
		{
			dragging = false;
			((Control)this).OnMouseUp(e);
		}

		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
		}
	}
	public class PanSlider : UserControl
	{
		private Container components;

		private float pan;

		public float Pan
		{
			get
			{
				return pan;
			}
			set
			{
				if (value < -1f)
				{
					value = -1f;
				}
				if (value > 1f)
				{
					value = 1f;
				}
				if (value != pan)
				{
					pan = value;
					if (this.PanChanged != null)
					{
						this.PanChanged(this, EventArgs.Empty);
					}
					((Control)this).Invalidate();
				}
			}
		}

		public event EventHandler PanChanged;

		public PanSlider()
		{
			InitializeComponent();
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing && components != null)
			{
				components.Dispose();
			}
			((ContainerControl)this).Dispose(disposing);
		}

		private void InitializeComponent()
		{
			((Control)this).Name = "PanSlider";
			((Control)this).Size = new Size(104, 16);
		}

		protected override void OnPaint(PaintEventArgs pe)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			StringFormat val = new StringFormat();
			val.LineAlignment = (StringAlignment)1;
			val.Alignment = (StringAlignment)1;
			string text;
			if ((double)pan == 0.0)
			{
				pe.Graphics.FillRectangle(Brushes.Orange, ((Control)this).Width / 2 - 1, 1, 3, ((Control)this).Height - 2);
				text = "C";
			}
			else if (pan > 0f)
			{
				pe.Graphics.FillRectangle(Brushes.Orange, ((Control)this).Width / 2, 1, (int)((float)(((Control)this).Width / 2) * pan), ((Control)this).Height - 2);
				text = $"{pan * 100f:F0}%R";
			}
			else
			{
				pe.Graphics.FillRectangle(Brushes.Orange, (int)((float)(((Control)this).Width / 2) * (pan + 1f)), 1, (int)((float)(((Control)this).Width / 2) * (0f - pan)), ((Control)this).Height - 2);
				text = $"{pan * -100f:F0}%L";
			}
			pe.Graphics.DrawRectangle(Pens.Black, 0, 0, ((Control)this).Width - 1, ((Control)this).Height - 1);
			pe.Graphics.DrawString(text, ((Control)this).Font, Brushes.Black, (RectangleF)((Control)this).ClientRectangle, val);
		}

		protected override void OnMouseMove(MouseEventArgs e)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			if ((int)e.Button == 1048576)
			{
				SetPanFromMouse(e.X);
			}
			((Control)this).OnMouseMove(e);
		}

		protected override void OnMouseDown(MouseEventArgs e)
		{
			SetPanFromMouse(e.X);
			((UserControl)this).OnMouseDown(e);
		}

		private void SetPanFromMouse(int x)
		{
			Pan = (float)x / (float)((Control)this).Width * 2f - 1f;
		}
	}
	public class Pot : UserControl
	{
		private double minimum;

		private double maximum = 1.0;

		private double value = 0.5;

		private int beginDragY;

		private double beginDragValue;

		private bool dragging;

		private IContainer components;

		public double Minimum
		{
			get
			{
				return minimum;
			}
			set
			{
				if (value >= maximum)
				{
					throw new ArgumentOutOfRangeException("Minimum must be less than maximum");
				}
				minimum = value;
				if (Value < minimum)
				{
					Value = minimum;
				}
			}
		}

		public double Maximum
		{
			get
			{
				return maximum;
			}
			set
			{
				if (value <= minimum)
				{
					throw new ArgumentOutOfRangeException("Maximum must be greater than minimum");
				}
				maximum = value;
				if (Value > maximum)
				{
					Value = maximum;
				}
			}
		}

		public double Value
		{
			get
			{
				return value;
			}
			set
			{
				SetValue(value, raiseEvents: false);
			}
		}

		public event EventHandler ValueChanged;

		public Pot()
		{
			((Control)this).SetStyle((ControlStyles)73730, true);
			InitializeComponent();
		}

		private void SetValue(double newValue, bool raiseEvents)
		{
			if (value != newValue)
			{
				value = newValue;
				if (raiseEvents && this.ValueChanged != null)
				{
					this.ValueChanged(this, EventArgs.Empty);
				}
				((Control)this).Invalidate();
			}
		}

		protected override void OnPaint(PaintEventArgs e)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			int num = Math.Min(((Control)this).Width - 4, ((Control)this).Height - 4);
			Pen val = new Pen(((Control)this).ForeColor, 3f);
			val.LineJoin = (LineJoin)2;
			GraphicsState val2 = e.Graphics.Save();
			e.Graphics.TranslateTransform((float)(((Control)this).Width / 2), (float)(((Control)this).Height / 2));
			e.Graphics.SmoothingMode = (SmoothingMode)4;
			e.Graphics.DrawArc(val, new Rectangle(num / -2, num / -2, num, num), 135f, 270f);
			double num2 = (value - minimum) / (maximum - minimum);
			double num3 = 135.0 + num2 * 270.0;
			double num4 = (double)num / 2.0 * Math.Cos(Math.PI * num3 / 180.0);
			double num5 = (double)num / 2.0 * Math.Sin(Math.PI * num3 / 180.0);
			e.Graphics.DrawLine(val, 0f, 0f, (float)num4, (float)num5);
			e.Graphics.Restore(val2);
			((Control)this).OnPaint(e);
		}

		protected override void OnMouseDown(MouseEventArgs e)
		{
			dragging = true;
			beginDragY = e.Y;
			beginDragValue = value;
			((UserControl)this).OnMouseDown(e);
		}

		protected override void OnMouseUp(MouseEventArgs e)
		{
			dragging = false;
			((Control)this).OnMouseUp(e);
		}

		protected override void OnMouseMove(MouseEventArgs e)
		{
			if (dragging)
			{
				int num = beginDragY - e.Y;
				double num2 = (maximum - minimum) * ((double)num / 150.0);
				double num3 = beginDragValue + num2;
				if (num3 < minimum)
				{
					num3 = minimum;
				}
				if (num3 > maximum)
				{
					num3 = maximum;
				}
				SetValue(num3, raiseEvents: true);
			}
			((Control)this).OnMouseMove(e);
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing && components != null)
			{
				components.Dispose();
			}
			((ContainerControl)this).Dispose(disposing);
		}

		private void InitializeComponent()
		{
			((Control)this).SuspendLayout();
			((ContainerControl)this).AutoScaleDimensions = new SizeF(6f, 13f);
			((ContainerControl)this).AutoScaleMode = (AutoScaleMode)1;
			((Control)this).Name = "Pot";
			((Control)this).Size = new Size(32, 32);
			((Control)this).ResumeLayout(false);
		}
	}
	public class VolumeMeter : Control
	{
		private Brush foregroundBrush;

		private float amplitude;

		private IContainer components;

		[DefaultValue(-3.0)]
		public float Amplitude
		{
			get
			{
				return amplitude;
			}
			set
			{
				amplitude = value;
				((Control)this).Invalidate();
			}
		}

		[DefaultValue(-60.0)]
		public float MinDb { get; set; }

		[DefaultValue(18.0)]
		public float MaxDb { get; set; }

		[DefaultValue(/*Could not decode attribute arguments.*/)]
		public Orientation Orientation { get; set; }

		public VolumeMeter()
		{
			((Control)this).SetStyle((ControlStyles)139266, true);
			MinDb = -60f;
			MaxDb = 18f;
			Amplitude = 0f;
			Orientation = (Orientation)1;
			InitializeComponent();
			((Control)this).OnForeColorChanged(EventArgs.Empty);
		}

		protected override void OnForeColorChanged(EventArgs e)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			foregroundBrush = (Brush)new SolidBrush(((Control)this).ForeColor);
			((Control)this).OnForeColorChanged(e);
		}

		protected override void OnPaint(PaintEventArgs pe)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			pe.Graphics.DrawRectangle(Pens.Black, 0, 0, ((Control)this).Width - 1, ((Control)this).Height - 1);
			double num = 20.0 * Math.Log10(Amplitude);
			if (num < (double)MinDb)
			{
				num = MinDb;
			}
			if (num > (double)MaxDb)
			{
				num = MaxDb;
			}
			double num2 = (num - (double)MinDb) / (double)(MaxDb - MinDb);
			int num3 = ((Control)this).Width - 2;
			int num4 = ((Control)this).Height - 2;
			if ((int)Orientation == 0)
			{
				num3 = (int)((double)num3 * num2);
				pe.Graphics.FillRectangle(foregroundBrush, 1, 1, num3, num4);
			}
			else
			{
				num4 = (int)((double)num4 * num2);
				pe.Graphics.FillRectangle(foregroundBrush, 1, ((Control)this).Height - 1 - num4, num3, num4);
			}
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing && components != null)
			{
				components.Dispose();
			}
			((Control)this).Dispose(disposing);
		}

		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
		}
	}
	public class VolumeSlider : UserControl
	{
		private Container components;

		private float volume = 1f;

		private float MinDb = -48f;

		[DefaultValue(1f)]
		public float Volume
		{
			get
			{
				return volume;
			}
			set
			{
				if (value < 0f)
				{
					value = 0f;
				}
				if (value > 1f)
				{
					value = 1f;
				}
				if (volume != value)
				{
					volume = value;
					if (this.VolumeChanged != null)
					{
						this.VolumeChanged(this, EventArgs.Empty);
					}
					((Control)this).Invalidate();
				}
			}
		}

		public event EventHandler VolumeChanged;

		public VolumeSlider()
		{
			InitializeComponent();
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing && components != null)
			{
				components.Dispose();
			}
			((ContainerControl)this).Dispose(disposing);
		}

		private void InitializeComponent()
		{
			((Control)this).Name = "VolumeSlider";
			((Control)this).Size = new Size(96, 16);
		}

		protected override void OnPaint(PaintEventArgs pe)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			StringFormat val = new StringFormat();
			val.LineAlignment = (StringAlignment)1;
			val.Alignment = (StringAlignment)1;
			pe.Graphics.DrawRectangle(Pens.Black, 0, 0, ((Control)this).Width - 1, ((Control)this).Height - 1);
			float num = 20f * (float)Math.Log10(Volume);
			float num2 = 1f - num / MinDb;
			pe.Graphics.FillRectangle(Brushes.LightGreen, 1, 1, (int)((float)(((Control)this).Width - 2) * num2), ((Control)this).Height - 2);
			string text = $"{num:F2} dB";
			pe.Graphics.DrawString(text, ((Control)this).Font, Brushes.Black, (RectangleF)((Control)this).ClientRectangle, val);
		}

		protected override void OnMouseMove(MouseEventArgs e)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			if ((int)e.Button == 1048576)
			{
				SetVolumeFromMouse(e.X);
			}
			((Control)this).OnMouseMove(e);
		}

		protected override void OnMouseDown(MouseEventArgs e)
		{
			SetVolumeFromMouse(e.X);
			((UserControl)this).OnMouseDown(e);
		}

		private void SetVolumeFromMouse(int x)
		{
			float num = (1f - (float)x / (float)((Control)this).Width) * MinDb;
			if (x <= 0)
			{
				Volume = 0f;
			}
			else
			{
				Volume = (float)Math.Pow(10.0, num / 20f);
			}
		}
	}
	public class WaveformPainter : Control
	{
		private Pen foregroundPen;

		private List<float> samples = new List<float>(1000);

		private int maxSamples;

		private int insertPos;

		private IContainer components;

		public WaveformPainter()
		{
			((Control)this).SetStyle((ControlStyles)139266, true);
			InitializeComponent();
			((Control)this).OnForeColorChanged(EventArgs.Empty);
			((Control)this).OnResize(EventArgs.Empty);
		}

		protected override void OnResize(EventArgs e)
		{
			maxSamples = ((Control)this).Width;
			((Control)this).OnResize(e);
		}

		protected override void OnForeColorChanged(EventArgs e)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			foregroundPen = new Pen(((Control)this).ForeColor);
			((Control)this).OnForeColorChanged(e);
		}

		public void AddMax(float maxSample)
		{
			if (maxSamples != 0)
			{
				if (samples.Count <= maxSamples)
				{
					samples.Add(maxSample);
				}
				else if (insertPos < maxSamples)
				{
					samples[insertPos] = maxSample;
				}
				insertPos++;
				insertPos %= maxSamples;
				((Control)this).Invalidate();
			}
		}

		protected override void OnPaint(PaintEventArgs pe)
		{
			((Control)this).OnPaint(pe);
			for (int i = 0; i < ((Control)this).Width; i++)
			{
				float num = (float)((Control)this).Height * GetSample(i - ((Control)this).Width + insertPos);
				float num2 = ((float)((Control)this).Height - num) / 2f;
				pe.Graphics.DrawLine(foregroundPen, (float)i, num2, (float)i, num2 + num);
			}
		}

		private float GetSample(int index)
		{
			if (index < 0)
			{
				index += maxSamples;
			}
			if ((index >= 0) & (index < samples.Count))
			{
				return samples[index];
			}
			return 0f;
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing && components != null)
			{
				components.Dispose();
			}
			((Control)this).Dispose(disposing);
		}

		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
		}
	}
	public class WaveViewer : UserControl
	{
		private Container components;

		private WaveStream waveStream;

		private int samplesPerPixel = 128;

		private long startPosition;

		private int bytesPerSample;

		public WaveStream WaveStream
		{
			get
			{
				return waveStream;
			}
			set
			{
				waveStream = value;
				if (waveStream != null)
				{
					bytesPerSample = waveStream.WaveFormat.BitsPerSample / 8 * waveStream.WaveFormat.Channels;
				}
				((Control)this).Invalidate();
			}
		}

		public int SamplesPerPixel
		{
			get
			{
				return samplesPerPixel;
			}
			set
			{
				samplesPerPixel = value;
				((Control)this).Invalidate();
			}
		}

		public long StartPosition
		{
			get
			{
				return startPosition;
			}
			set
			{
				startPosition = value;
			}
		}

		public WaveViewer()
		{
			InitializeComponent();
			((Control)this).DoubleBuffered = true;
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing && components != null)
			{
				components.Dispose();
			}
			((ContainerControl)this).Dispose(disposing);
		}

		protected override void OnPaint(PaintEventArgs e)
		{
			if (waveStream != null)
			{
				((Stream)(object)waveStream).Position = 0L;
				byte[] array = new byte[samplesPerPixel * bytesPerSample];
				((Stream)(object)waveStream).Position = startPosition + e.ClipRectangle.Left * bytesPerSample * samplesPerPixel;
				for (float num = e.ClipRectangle.X; num < (float)e.ClipRectangle.Right; num += 1f)
				{
					short num2 = 0;
					short num3 = 0;
					int num4 = ((Stream)(object)waveStream).Read(array, 0, samplesPerPixel * bytesPerSample);
					if (num4 == 0)
					{
						break;
					}
					for (int i = 0; i < num4; i += 2)
					{
						short num5 = BitConverter.ToInt16(array, i);
						if (num5 < num2)
						{
							num2 = num5;
						}
						if (num5 > num3)
						{
							num3 = num5;
						}
					}
					float num6 = ((float)num2 - -32768f) / 65535f;
					float num7 = ((float)num3 - -32768f) / 65535f;
					e.Graphics.DrawLine(Pens.Black, num, (float)((Control)this).Height * num6, num, (float)((Control)this).Height * num7);
				}
			}
			((Control)this).OnPaint(e);
		}

		private void InitializeComponent()
		{
			components = new Container();
		}
	}
}

Mods/RealRadio/NAudio.WinMM.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Threading;
using Microsoft.Win32;
using NAudio.CoreAudioApi;
using NAudio.Mixer;
using NAudio.Utils;
using NAudio.Wave.Compression;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("NAudio.WinMM")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("© Mark Heath 2023")]
[assembly: AssemblyFileVersion("2.2.1.0")]
[assembly: AssemblyInformationalVersion("2.2.1")]
[assembly: AssemblyProduct("NAudio.WinMM")]
[assembly: AssemblyTitle("NAudio.WinMM")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/naudio/NAudio")]
[assembly: AssemblyVersion("2.2.1.0")]
namespace NAudio.Mixer
{
	public class BooleanMixerControl : MixerControl
	{
		private MixerInterop.MIXERCONTROLDETAILS_BOOLEAN boolDetails;

		public bool Value
		{
			get
			{
				GetControlDetails();
				return boolDetails.fValue == 1;
			}
			set
			{
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				boolDetails.fValue = (value ? 1 : 0);
				mixerControlDetails.paDetails = Marshal.AllocHGlobal(Marshal.SizeOf(boolDetails));
				Marshal.StructureToPtr(boolDetails, mixerControlDetails.paDetails, fDeleteOld: false);
				MmException.Try(MixerInterop.mixerSetControlDetails(mixerHandle, ref mixerControlDetails, MixerFlags.Mixer | mixerHandleType), "mixerSetControlDetails");
				Marshal.FreeHGlobal(mixerControlDetails.paDetails);
			}
		}

		internal BooleanMixerControl(MixerInterop.MIXERCONTROL mixerControl, IntPtr mixerHandle, MixerFlags mixerHandleType, int nChannels)
		{
			base.mixerControl = mixerControl;
			base.mixerHandle = mixerHandle;
			base.mixerHandleType = mixerHandleType;
			base.nChannels = nChannels;
			mixerControlDetails = default(MixerInterop.MIXERCONTROLDETAILS);
			GetControlDetails();
		}

		protected override void GetDetails(IntPtr pDetails)
		{
			boolDetails = Marshal.PtrToStructure<MixerInterop.MIXERCONTROLDETAILS_BOOLEAN>(pDetails);
		}
	}
	public class CustomMixerControl : MixerControl
	{
		internal CustomMixerControl(MixerInterop.MIXERCONTROL mixerControl, IntPtr mixerHandle, MixerFlags mixerHandleType, int nChannels)
		{
			base.mixerControl = mixerControl;
			base.mixerHandle = mixerHandle;
			base.mixerHandleType = mixerHandleType;
			base.nChannels = nChannels;
			mixerControlDetails = default(MixerInterop.MIXERCONTROLDETAILS);
			GetControlDetails();
		}

		protected override void GetDetails(IntPtr pDetails)
		{
		}
	}
	public class ListTextMixerControl : MixerControl
	{
		internal ListTextMixerControl(MixerInterop.MIXERCONTROL mixerControl, IntPtr mixerHandle, MixerFlags mixerHandleType, int nChannels)
		{
			base.mixerControl = mixerControl;
			base.mixerHandle = mixerHandle;
			base.mixerHandleType = mixerHandleType;
			base.nChannels = nChannels;
			mixerControlDetails = default(MixerInterop.MIXERCONTROLDETAILS);
			GetControlDetails();
		}

		protected override void GetDetails(IntPtr pDetails)
		{
		}
	}
	public class Mixer
	{
		private MixerInterop.MIXERCAPS caps;

		private IntPtr mixerHandle;

		private MixerFlags mixerHandleType;

		public static int NumberOfDevices => MixerInterop.mixerGetNumDevs();

		public int DestinationCount => (int)caps.cDestinations;

		public string Name => caps.szPname;

		public Manufacturers Manufacturer => (Manufacturers)caps.wMid;

		public int ProductID => caps.wPid;

		public IEnumerable<MixerLine> Destinations
		{
			get
			{
				for (int destination = 0; destination < DestinationCount; destination++)
				{
					yield return GetDestination(destination);
				}
			}
		}

		public static IEnumerable<Mixer> Mixers
		{
			get
			{
				for (int device = 0; device < NumberOfDevices; device++)
				{
					yield return new Mixer(device);
				}
			}
		}

		public Mixer(int mixerIndex)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if (mixerIndex < 0 || mixerIndex >= NumberOfDevices)
			{
				throw new ArgumentOutOfRangeException("mixerID");
			}
			caps = default(MixerInterop.MIXERCAPS);
			MmException.Try(MixerInterop.mixerGetDevCaps((IntPtr)mixerIndex, ref caps, Marshal.SizeOf(caps)), "mixerGetDevCaps");
			mixerHandle = (IntPtr)mixerIndex;
			mixerHandleType = MixerFlags.Mixer;
		}

		public MixerLine GetDestination(int destinationIndex)
		{
			if (destinationIndex < 0 || destinationIndex >= DestinationCount)
			{
				throw new ArgumentOutOfRangeException("destinationIndex");
			}
			return new MixerLine(mixerHandle, destinationIndex, mixerHandleType);
		}
	}
	public abstract class MixerControl
	{
		internal MixerInterop.MIXERCONTROL mixerControl;

		internal MixerInterop.MIXERCONTROLDETAILS mixerControlDetails;

		protected IntPtr mixerHandle;

		protected int nChannels;

		protected MixerFlags mixerHandleType;

		public string Name => mixerControl.szName;

		public MixerControlType ControlType => mixerControl.dwControlType;

		public bool IsBoolean => IsControlBoolean(mixerControl.dwControlType);

		public bool IsListText => IsControlListText(mixerControl.dwControlType);

		public bool IsSigned => IsControlSigned(mixerControl.dwControlType);

		public bool IsUnsigned => IsControlUnsigned(mixerControl.dwControlType);

		public bool IsCustom => IsControlCustom(mixerControl.dwControlType);

		public static IList<MixerControl> GetMixerControls(IntPtr mixerHandle, MixerLine mixerLine, MixerFlags mixerHandleType)
		{
			//IL_006f: 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_0076: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			List<MixerControl> list = new List<MixerControl>();
			if (mixerLine.ControlsCount > 0)
			{
				int num = Marshal.SizeOf<MixerInterop.MIXERCONTROL>();
				MixerInterop.MIXERLINECONTROLS mixerLineControls = default(MixerInterop.MIXERLINECONTROLS);
				IntPtr intPtr = Marshal.AllocHGlobal(num * mixerLine.ControlsCount);
				mixerLineControls.cbStruct = Marshal.SizeOf(mixerLineControls);
				mixerLineControls.dwLineID = mixerLine.LineId;
				mixerLineControls.cControls = mixerLine.ControlsCount;
				mixerLineControls.pamxctrl = intPtr;
				mixerLineControls.cbmxctrl = Marshal.SizeOf<MixerInterop.MIXERCONTROL>();
				try
				{
					MmResult val = MixerInterop.mixerGetLineControls(mixerHandle, ref mixerLineControls, MixerFlags.Mixer | mixerHandleType);
					if ((int)val != 0)
					{
						throw new MmException(val, "mixerGetLineControls");
					}
					for (int i = 0; i < mixerLineControls.cControls; i++)
					{
						MixerInterop.MIXERCONTROL mIXERCONTROL = Marshal.PtrToStructure<MixerInterop.MIXERCONTROL>((IntPtr)(intPtr.ToInt64() + num * i));
						MixerControl item = GetMixerControl(mixerHandle, mixerLine.LineId, mIXERCONTROL.dwControlID, mixerLine.Channels, mixerHandleType);
						list.Add(item);
					}
				}
				finally
				{
					Marshal.FreeHGlobal(intPtr);
				}
			}
			return list;
		}

		public static MixerControl GetMixerControl(IntPtr mixerHandle, int nLineId, int controlId, int nChannels, MixerFlags mixerFlags)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			MixerInterop.MIXERLINECONTROLS mixerLineControls = default(MixerInterop.MIXERLINECONTROLS);
			MixerInterop.MIXERCONTROL structure = default(MixerInterop.MIXERCONTROL);
			IntPtr intPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(structure));
			mixerLineControls.cbStruct = Marshal.SizeOf(mixerLineControls);
			mixerLineControls.cControls = 1;
			mixerLineControls.dwControlID = controlId;
			mixerLineControls.cbmxctrl = Marshal.SizeOf(structure);
			mixerLineControls.pamxctrl = intPtr;
			mixerLineControls.dwLineID = nLineId;
			MmResult val = MixerInterop.mixerGetLineControls(mixerHandle, ref mixerLineControls, MixerFlags.ListText | mixerFlags);
			if ((int)val != 0)
			{
				Marshal.FreeCoTaskMem(intPtr);
				throw new MmException(val, "mixerGetLineControls");
			}
			structure = Marshal.PtrToStructure<MixerInterop.MIXERCONTROL>(mixerLineControls.pamxctrl);
			Marshal.FreeCoTaskMem(intPtr);
			if (IsControlBoolean(structure.dwControlType))
			{
				return new BooleanMixerControl(structure, mixerHandle, mixerFlags, nChannels);
			}
			if (IsControlSigned(structure.dwControlType))
			{
				return new SignedMixerControl(structure, mixerHandle, mixerFlags, nChannels);
			}
			if (IsControlUnsigned(structure.dwControlType))
			{
				return new UnsignedMixerControl(structure, mixerHandle, mixerFlags, nChannels);
			}
			if (IsControlListText(structure.dwControlType))
			{
				return new ListTextMixerControl(structure, mixerHandle, mixerFlags, nChannels);
			}
			if (IsControlCustom(structure.dwControlType))
			{
				return new CustomMixerControl(structure, mixerHandle, mixerFlags, nChannels);
			}
			throw new InvalidOperationException($"Unknown mixer control type {structure.dwControlType}");
		}

		protected void GetControlDetails()
		{
			//IL_01a6: 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_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			mixerControlDetails.cbStruct = Marshal.SizeOf(mixerControlDetails);
			mixerControlDetails.dwControlID = mixerControl.dwControlID;
			if (IsCustom)
			{
				mixerControlDetails.cChannels = 0;
			}
			else if ((mixerControl.fdwControl & (true ? 1u : 0u)) != 0)
			{
				mixerControlDetails.cChannels = 1;
			}
			else
			{
				mixerControlDetails.cChannels = nChannels;
			}
			if ((mixerControl.fdwControl & 2u) != 0)
			{
				mixerControlDetails.hwndOwner = (IntPtr)mixerControl.cMultipleItems;
			}
			else if (IsCustom)
			{
				mixerControlDetails.hwndOwner = IntPtr.Zero;
			}
			else
			{
				mixerControlDetails.hwndOwner = IntPtr.Zero;
			}
			if (IsBoolean)
			{
				mixerControlDetails.cbDetails = Marshal.SizeOf<MixerInterop.MIXERCONTROLDETAILS_BOOLEAN>();
			}
			else if (IsListText)
			{
				mixerControlDetails.cbDetails = Marshal.SizeOf<MixerInterop.MIXERCONTROLDETAILS_LISTTEXT>();
			}
			else if (IsSigned)
			{
				mixerControlDetails.cbDetails = Marshal.SizeOf<MixerInterop.MIXERCONTROLDETAILS_SIGNED>();
			}
			else if (IsUnsigned)
			{
				mixerControlDetails.cbDetails = Marshal.SizeOf<MixerInterop.MIXERCONTROLDETAILS_UNSIGNED>();
			}
			else
			{
				mixerControlDetails.cbDetails = mixerControl.Metrics.customData;
			}
			int num = mixerControlDetails.cbDetails * mixerControlDetails.cChannels;
			if ((mixerControl.fdwControl & 2u) != 0)
			{
				num *= (int)mixerControl.cMultipleItems;
			}
			IntPtr intPtr = Marshal.AllocCoTaskMem(num);
			mixerControlDetails.paDetails = intPtr;
			MmResult val = MixerInterop.mixerGetControlDetails(mixerHandle, ref mixerControlDetails, MixerFlags.Mixer | mixerHandleType);
			if ((int)val == 0)
			{
				GetDetails(mixerControlDetails.paDetails);
			}
			Marshal.FreeCoTaskMem(intPtr);
			if ((int)val != 0)
			{
				throw new MmException(val, "mixerGetControlDetails");
			}
		}

		protected abstract void GetDetails(IntPtr pDetails);

		private static bool IsControlBoolean(MixerControlType controlType)
		{
			switch (controlType)
			{
			case MixerControlType.BooleanMeter:
			case MixerControlType.Boolean:
			case MixerControlType.OnOff:
			case MixerControlType.Mute:
			case MixerControlType.Mono:
			case MixerControlType.Loudness:
			case MixerControlType.StereoEnhance:
			case MixerControlType.Button:
			case MixerControlType.SingleSelect:
			case MixerControlType.Mux:
			case MixerControlType.MultipleSelect:
			case MixerControlType.Mixer:
				return true;
			default:
				return false;
			}
		}

		private static bool IsControlListText(MixerControlType controlType)
		{
			if (controlType == MixerControlType.Equalizer || (uint)(controlType - 1879113728) <= 1u || (uint)(controlType - 1895890944) <= 1u)
			{
				return true;
			}
			return false;
		}

		private static bool IsControlSigned(MixerControlType controlType)
		{
			switch (controlType)
			{
			case MixerControlType.SignedMeter:
			case MixerControlType.PeakMeter:
			case MixerControlType.Signed:
			case MixerControlType.Decibels:
			case MixerControlType.Slider:
			case MixerControlType.Pan:
			case MixerControlType.QSoundPan:
				return true;
			default:
				return false;
			}
		}

		private static bool IsControlUnsigned(MixerControlType controlType)
		{
			switch (controlType)
			{
			case MixerControlType.UnsignedMeter:
			case MixerControlType.Unsigned:
			case MixerControlType.Percent:
			case MixerControlType.Fader:
			case MixerControlType.Volume:
			case MixerControlType.Bass:
			case MixerControlType.Treble:
			case MixerControlType.Equalizer:
			case MixerControlType.MicroTime:
			case MixerControlType.MilliTime:
				return true;
			default:
				return false;
			}
		}

		private static bool IsControlCustom(MixerControlType controlType)
		{
			return controlType == MixerControlType.Custom;
		}

		public override string ToString()
		{
			return $"{Name} {ControlType}";
		}
	}
	[Flags]
	internal enum MixerControlClass
	{
		Custom = 0,
		Meter = 0x10000000,
		Switch = 0x20000000,
		Number = 0x30000000,
		Slider = 0x40000000,
		Fader = 0x50000000,
		Time = 0x60000000,
		List = 0x70000000,
		Mask = 0x70000000
	}
	[Flags]
	internal enum MixerControlSubclass
	{
		SwitchBoolean = 0,
		SwitchButton = 0x1000000,
		MeterPolled = 0,
		TimeMicrosecs = 0,
		TimeMillisecs = 0x1000000,
		ListSingle = 0,
		ListMultiple = 0x1000000,
		Mask = 0xF000000
	}
	[Flags]
	internal enum MixerControlUnits
	{
		Custom = 0,
		Boolean = 0x10000,
		Signed = 0x20000,
		Unsigned = 0x30000,
		Decibels = 0x40000,
		Percent = 0x50000,
		Mask = 0xFF0000
	}
	public enum MixerControlType
	{
		Custom = 0,
		BooleanMeter = 268500992,
		SignedMeter = 268566528,
		PeakMeter = 268566529,
		UnsignedMeter = 268632064,
		Boolean = 536936448,
		OnOff = 536936449,
		Mute = 536936450,
		Mono = 536936451,
		Loudness = 536936452,
		StereoEnhance = 536936453,
		Button = 553713664,
		Decibels = 805568512,
		Signed = 805437440,
		Unsigned = 805502976,
		Percent = 805634048,
		Slider = 1073872896,
		Pan = 1073872897,
		QSoundPan = 1073872898,
		Fader = 1342373888,
		Volume = 1342373889,
		Bass = 1342373890,
		Treble = 1342373891,
		Equalizer = 1342373892,
		SingleSelect = 1879113728,
		Mux = 1879113729,
		MultipleSelect = 1895890944,
		Mixer = 1895890945,
		MicroTime = 1610809344,
		MilliTime = 1627586560
	}
	[Flags]
	public enum MixerFlags
	{
		Handle = int.MinValue,
		Mixer = 0,
		MixerHandle = int.MinValue,
		WaveOut = 0x10000000,
		WaveOutHandle = -1879048192,
		WaveIn = 0x20000000,
		WaveInHandle = -1610612736,
		MidiOut = 0x30000000,
		MidiOutHandle = -1342177280,
		MidiIn = 0x40000000,
		MidiInHandle = -1073741824,
		Aux = 0x50000000,
		Value = 0,
		ListText = 1,
		QueryMask = 0xF,
		All = 0,
		OneById = 1,
		OneByType = 2,
		GetLineInfoOfDestination = 0,
		GetLineInfoOfSource = 1,
		GetLineInfoOfLineId = 2,
		GetLineInfoOfComponentType = 3,
		GetLineInfoOfTargetType = 4,
		GetLineInfoOfQueryMask = 0xF
	}
	internal class MixerInterop
	{
		[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 1)]
		public struct MIXERCONTROLDETAILS
		{
			public int cbStruct;

			public int dwControlID;

			public int cChannels;

			public IntPtr hwndOwner;

			public int cbDetails;

			public IntPtr paDetails;
		}

		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		public struct MIXERCAPS
		{
			public ushort wMid;

			public ushort wPid;

			public uint vDriverVersion;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
			public string szPname;

			public uint fdwSupport;

			public uint cDestinations;
		}

		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		public struct MIXERLINECONTROLS
		{
			public int cbStruct;

			public int dwLineID;

			public int dwControlID;

			public int cControls;

			public int cbmxctrl;

			public IntPtr pamxctrl;
		}

		[Flags]
		public enum MIXERLINE_LINEF
		{
			MIXERLINE_LINEF_ACTIVE = 1,
			MIXERLINE_LINEF_DISCONNECTED = 0x8000,
			MIXERLINE_LINEF_SOURCE = int.MinValue
		}

		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		public struct MIXERLINE
		{
			public int cbStruct;

			public int dwDestination;

			public int dwSource;

			public int dwLineID;

			public MIXERLINE_LINEF fdwLine;

			public IntPtr dwUser;

			public MixerLineComponentType dwComponentType;

			public int cChannels;

			public int cConnections;

			public int cControls;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
			public string szShortName;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
			public string szName;

			public uint dwType;

			public uint dwDeviceID;

			public ushort wMid;

			public ushort wPid;

			public uint vDriverVersion;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
			public string szPname;
		}

		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		public struct Bounds
		{
			public int minimum;

			public int maximum;

			public int reserved2;

			public int reserved3;

			public int reserved4;

			public int reserved5;
		}

		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		public struct Metrics
		{
			public int step;

			public int customData;

			public int reserved2;

			public int reserved3;

			public int reserved4;

			public int reserved5;
		}

		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		public struct MIXERCONTROL
		{
			public uint cbStruct;

			public int dwControlID;

			public MixerControlType dwControlType;

			public uint fdwControl;

			public uint cMultipleItems;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
			public string szShortName;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
			public string szName;

			public Bounds Bounds;

			public Metrics Metrics;
		}

		public struct MIXERCONTROLDETAILS_BOOLEAN
		{
			public int fValue;
		}

		public struct MIXERCONTROLDETAILS_SIGNED
		{
			public int lValue;
		}

		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		public struct MIXERCONTROLDETAILS_LISTTEXT
		{
			public uint dwParam1;

			public uint dwParam2;

			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
			public string szName;
		}

		public struct MIXERCONTROLDETAILS_UNSIGNED
		{
			public uint dwValue;
		}

		public const uint MIXERCONTROL_CONTROLF_UNIFORM = 1u;

		public const uint MIXERCONTROL_CONTROLF_MULTIPLE = 2u;

		public const uint MIXERCONTROL_CONTROLF_DISABLED = 2147483648u;

		public const int MAXPNAMELEN = 32;

		public const int MIXER_SHORT_NAME_CHARS = 16;

		public const int MIXER_LONG_NAME_CHARS = 64;

		[DllImport("winmm.dll", CharSet = CharSet.Ansi)]
		public static extern int mixerGetNumDevs();

		[DllImport("winmm.dll", CharSet = CharSet.Ansi)]
		public static extern MmResult mixerOpen(out IntPtr hMixer, int uMxId, IntPtr dwCallback, IntPtr dwInstance, MixerFlags dwOpenFlags);

		[DllImport("winmm.dll", CharSet = CharSet.Ansi)]
		public static extern MmResult mixerClose(IntPtr hMixer);

		[DllImport("winmm.dll", CharSet = CharSet.Ansi)]
		public static extern MmResult mixerGetControlDetails(IntPtr hMixer, ref MIXERCONTROLDETAILS mixerControlDetails, MixerFlags dwDetailsFlags);

		[DllImport("winmm.dll", CharSet = CharSet.Ansi)]
		public static extern MmResult mixerGetDevCaps(IntPtr nMixerID, ref MIXERCAPS mixerCaps, int mixerCapsSize);

		[DllImport("winmm.dll", CharSet = CharSet.Ansi)]
		public static extern MmResult mixerGetID(IntPtr hMixer, out int mixerID, MixerFlags dwMixerIDFlags);

		[DllImport("winmm.dll", CharSet = CharSet.Ansi)]
		public static extern MmResult mixerGetLineControls(IntPtr hMixer, ref MIXERLINECONTROLS mixerLineControls, MixerFlags dwControlFlags);

		[DllImport("winmm.dll", CharSet = CharSet.Ansi)]
		public static extern MmResult mixerGetLineInfo(IntPtr hMixer, ref MIXERLINE mixerLine, MixerFlags dwInfoFlags);

		[DllImport("winmm.dll", CharSet = CharSet.Ansi)]
		public static extern MmResult mixerMessage(IntPtr hMixer, uint nMessage, IntPtr dwParam1, IntPtr dwParam2);

		[DllImport("winmm.dll", CharSet = CharSet.Ansi)]
		public static extern MmResult mixerSetControlDetails(IntPtr hMixer, ref MIXERCONTROLDETAILS mixerControlDetails, MixerFlags dwDetailsFlags);
	}
	public class MixerLine
	{
		private MixerInterop.MIXERLINE mixerLine;

		private IntPtr mixerHandle;

		private MixerFlags mixerHandleType;

		public string Name => mixerLine.szName;

		public string ShortName => mixerLine.szShortName;

		public int LineId => mixerLine.dwLineID;

		public MixerLineComponentType ComponentType => mixerLine.dwComponentType;

		public string TypeDescription => mixerLine.dwComponentType switch
		{
			MixerLineComponentType.DestinationUndefined => "Undefined Destination", 
			MixerLineComponentType.DestinationDigital => "Digital Destination", 
			MixerLineComponentType.DestinationLine => "Line Level Destination", 
			MixerLineComponentType.DestinationMonitor => "Monitor Destination", 
			MixerLineComponentType.DestinationSpeakers => "Speakers Destination", 
			MixerLineComponentType.DestinationHeadphones => "Headphones Destination", 
			MixerLineComponentType.DestinationTelephone => "Telephone Destination", 
			MixerLineComponentType.DestinationWaveIn => "Wave Input Destination", 
			MixerLineComponentType.DestinationVoiceIn => "Voice Recognition Destination", 
			MixerLineComponentType.SourceUndefined => "Undefined Source", 
			MixerLineComponentType.SourceDigital => "Digital Source", 
			MixerLineComponentType.SourceLine => "Line Level Source", 
			MixerLineComponentType.SourceMicrophone => "Microphone Source", 
			MixerLineComponentType.SourceSynthesizer => "Synthesizer Source", 
			MixerLineComponentType.SourceCompactDisc => "Compact Disk Source", 
			MixerLineComponentType.SourceTelephone => "Telephone Source", 
			MixerLineComponentType.SourcePcSpeaker => "PC Speaker Source", 
			MixerLineComponentType.SourceWaveOut => "Wave Out Source", 
			MixerLineComponentType.SourceAuxiliary => "Auxiliary Source", 
			MixerLineComponentType.SourceAnalog => "Analog Source", 
			_ => "Invalid Component Type", 
		};

		public int Channels => mixerLine.cChannels;

		public int SourceCount => mixerLine.cConnections;

		public int ControlsCount => mixerLine.cControls;

		public bool IsActive => (mixerLine.fdwLine & MixerInterop.MIXERLINE_LINEF.MIXERLINE_LINEF_ACTIVE) != 0;

		public bool IsDisconnected => (mixerLine.fdwLine & MixerInterop.MIXERLINE_LINEF.MIXERLINE_LINEF_DISCONNECTED) != 0;

		public bool IsSource => (mixerLine.fdwLine & MixerInterop.MIXERLINE_LINEF.MIXERLINE_LINEF_SOURCE) != 0;

		public IEnumerable<MixerControl> Controls => MixerControl.GetMixerControls(mixerHandle, this, mixerHandleType);

		public IEnumerable<MixerLine> Sources
		{
			get
			{
				for (int source = 0; source < SourceCount; source++)
				{
					yield return GetSource(source);
				}
			}
		}

		public string TargetName => mixerLine.szPname;

		public MixerLine(IntPtr mixerHandle, int destinationIndex, MixerFlags mixerHandleType)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			this.mixerHandle = mixerHandle;
			this.mixerHandleType = mixerHandleType;
			mixerLine = default(MixerInterop.MIXERLINE);
			mixerLine.cbStruct = Marshal.SizeOf(mixerLine);
			mixerLine.dwDestination = destinationIndex;
			MmException.Try(MixerInterop.mixerGetLineInfo(mixerHandle, ref mixerLine, mixerHandleType | MixerFlags.Mixer), "mixerGetLineInfo");
		}

		public MixerLine(IntPtr mixerHandle, int destinationIndex, int sourceIndex, MixerFlags mixerHandleType)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			this.mixerHandle = mixerHandle;
			this.mixerHandleType = mixerHandleType;
			mixerLine = default(MixerInterop.MIXERLINE);
			mixerLine.cbStruct = Marshal.SizeOf(mixerLine);
			mixerLine.dwDestination = destinationIndex;
			mixerLine.dwSource = sourceIndex;
			MmException.Try(MixerInterop.mixerGetLineInfo(mixerHandle, ref mixerLine, mixerHandleType | MixerFlags.ListText), "mixerGetLineInfo");
		}

		public static int GetMixerIdForWaveIn(int waveInDevice)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			int mixerID = -1;
			MmException.Try(MixerInterop.mixerGetID((IntPtr)waveInDevice, out mixerID, MixerFlags.WaveIn), "mixerGetID");
			return mixerID;
		}

		public MixerLine GetSource(int sourceIndex)
		{
			if (sourceIndex < 0 || sourceIndex >= SourceCount)
			{
				throw new ArgumentOutOfRangeException("sourceIndex");
			}
			return new MixerLine(mixerHandle, mixerLine.dwDestination, sourceIndex, mixerHandleType);
		}

		public override string ToString()
		{
			return $"{Name} {TypeDescription} ({ControlsCount} controls, ID={mixerLine.dwLineID})";
		}
	}
	public enum MixerLineComponentType
	{
		DestinationUndefined = 0,
		DestinationDigital = 1,
		DestinationLine = 2,
		DestinationMonitor = 3,
		DestinationSpeakers = 4,
		DestinationHeadphones = 5,
		DestinationTelephone = 6,
		DestinationWaveIn = 7,
		DestinationVoiceIn = 8,
		SourceUndefined = 4096,
		SourceDigital = 4097,
		SourceLine = 4098,
		SourceMicrophone = 4099,
		SourceSynthesizer = 4100,
		SourceCompactDisc = 4101,
		SourceTelephone = 4102,
		SourcePcSpeaker = 4103,
		SourceWaveOut = 4104,
		SourceAuxiliary = 4105,
		SourceAnalog = 4106
	}
	public class SignedMixerControl : MixerControl
	{
		private MixerInterop.MIXERCONTROLDETAILS_SIGNED signedDetails;

		public int Value
		{
			get
			{
				GetControlDetails();
				return signedDetails.lValue;
			}
			set
			{
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				signedDetails.lValue = value;
				mixerControlDetails.paDetails = Marshal.AllocHGlobal(Marshal.SizeOf(signedDetails));
				Marshal.StructureToPtr(signedDetails, mixerControlDetails.paDetails, fDeleteOld: false);
				MmException.Try(MixerInterop.mixerSetControlDetails(mixerHandle, ref mixerControlDetails, MixerFlags.Mixer | mixerHandleType), "mixerSetControlDetails");
				Marshal.FreeHGlobal(mixerControlDetails.paDetails);
			}
		}

		public int MinValue => mixerControl.Bounds.minimum;

		public int MaxValue => mixerControl.Bounds.maximum;

		public double Percent
		{
			get
			{
				return 100.0 * (double)(Value - MinValue) / (double)(MaxValue - MinValue);
			}
			set
			{
				Value = (int)((double)MinValue + value / 100.0 * (double)(MaxValue - MinValue));
			}
		}

		internal SignedMixerControl(MixerInterop.MIXERCONTROL mixerControl, IntPtr mixerHandle, MixerFlags mixerHandleType, int nChannels)
		{
			base.mixerControl = mixerControl;
			base.mixerHandle = mixerHandle;
			base.mixerHandleType = mixerHandleType;
			base.nChannels = nChannels;
			mixerControlDetails = default(MixerInterop.MIXERCONTROLDETAILS);
			GetControlDetails();
		}

		protected override void GetDetails(IntPtr pDetails)
		{
			signedDetails = Marshal.PtrToStructure<MixerInterop.MIXERCONTROLDETAILS_SIGNED>(mixerControlDetails.paDetails);
		}

		public override string ToString()
		{
			return $"{base.ToString()} {Percent}%";
		}
	}
	public class UnsignedMixerControl : MixerControl
	{
		private MixerInterop.MIXERCONTROLDETAILS_UNSIGNED[] unsignedDetails;

		public uint Value
		{
			get
			{
				GetControlDetails();
				return unsignedDetails[0].dwValue;
			}
			set
			{
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				int num = Marshal.SizeOf(unsignedDetails[0]);
				mixerControlDetails.paDetails = Marshal.AllocHGlobal(num * nChannels);
				for (int i = 0; i < nChannels; i++)
				{
					unsignedDetails[i].dwValue = value;
					long num2 = mixerControlDetails.paDetails.ToInt64() + num * i;
					Marshal.StructureToPtr(unsignedDetails[i], (IntPtr)num2, fDeleteOld: false);
				}
				MmException.Try(MixerInterop.mixerSetControlDetails(mixerHandle, ref mixerControlDetails, MixerFlags.Mixer | mixerHandleType), "mixerSetControlDetails");
				Marshal.FreeHGlobal(mixerControlDetails.paDetails);
			}
		}

		public uint MinValue => (uint)mixerControl.Bounds.minimum;

		public uint MaxValue => (uint)mixerControl.Bounds.maximum;

		public double Percent
		{
			get
			{
				return 100.0 * (double)(Value - MinValue) / (double)(MaxValue - MinValue);
			}
			set
			{
				Value = (uint)((double)MinValue + value / 100.0 * (double)(MaxValue - MinValue));
			}
		}

		internal UnsignedMixerControl(MixerInterop.MIXERCONTROL mixerControl, IntPtr mixerHandle, MixerFlags mixerHandleType, int nChannels)
		{
			base.mixerControl = mixerControl;
			base.mixerHandle = mixerHandle;
			base.mixerHandleType = mixerHandleType;
			base.nChannels = nChannels;
			mixerControlDetails = default(MixerInterop.MIXERCONTROLDETAILS);
			GetControlDetails();
		}

		protected override void GetDetails(IntPtr pDetails)
		{
			unsignedDetails = new MixerInterop.MIXERCONTROLDETAILS_UNSIGNED[nChannels];
			for (int i = 0; i < nChannels; i++)
			{
				unsignedDetails[i] = Marshal.PtrToStructure<MixerInterop.MIXERCONTROLDETAILS_UNSIGNED>(mixerControlDetails.paDetails);
			}
		}

		public override string ToString()
		{
			return $"{base.ToString()} {Percent}%";
		}
	}
}
namespace NAudio.Wave
{
	internal enum AcmMetrics
	{
		CountDrivers = 1,
		CountCodecs = 2,
		CountConverters = 3,
		CountFilters = 4,
		CountDisabled = 5,
		CountHardware = 6,
		CountLocalDrivers = 20,
		CountLocalCodecs = 21,
		CountLocalConverters = 22,
		CountLocalFilters = 23,
		CountLocalDisabled = 24,
		HardwareWaveInput = 30,
		HardwareWaveOutput = 31,
		MaxSizeFormat = 50,
		MaxSizeFilter = 51,
		DriverSupport = 100,
		DriverPriority = 101
	}
	[Flags]
	internal enum AcmStreamConvertFlags
	{
		BlockAlign = 4,
		Start = 0x10,
		End = 0x20
	}
	[StructLayout(LayoutKind.Explicit)]
	public struct MmTime
	{
		public const int TIME_MS = 1;

		public const int TIME_SAMPLES = 2;

		public const int TIME_BYTES = 4;

		[FieldOffset(0)]
		public uint wType;

		[FieldOffset(4)]
		public uint ms;

		[FieldOffset(4)]
		public uint sample;

		[FieldOffset(4)]
		public uint cb;

		[FieldOffset(4)]
		public uint ticks;

		[FieldOffset(4)]
		public byte smpteHour;

		[FieldOffset(5)]
		public byte smpteMin;

		[FieldOffset(6)]
		public byte smpteSec;

		[FieldOffset(7)]
		public byte smpteFrame;

		[FieldOffset(8)]
		public byte smpteFps;

		[FieldOffset(9)]
		public byte smpteDummy;

		[FieldOffset(10)]
		public byte smptePad0;

		[FieldOffset(11)]
		public byte smptePad1;

		[FieldOffset(4)]
		public uint midiSongPtrPos;
	}
	public enum WaveCallbackStrategy
	{
		FunctionCallback,
		NewWindow,
		ExistingWindow,
		Event
	}
	[StructLayout(LayoutKind.Sequential)]
	public sealed class WaveHeader
	{
		public IntPtr dataBuffer;

		public int bufferLength;

		public int bytesRecorded;

		public IntPtr userData;

		public WaveHeaderFlags flags;

		public int loops;

		public IntPtr next;

		public IntPtr reserved;
	}
	[Flags]
	public enum WaveHeaderFlags
	{
		BeginLoop = 4,
		Done = 1,
		EndLoop = 8,
		InQueue = 0x10,
		Prepared = 2
	}
	[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
	public struct WaveInCapabilities
	{
		private short manufacturerId;

		private short productId;

		private int driverVersion;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
		private string productName;

		private SupportedWaveFormat supportedFormats;

		private short channels;

		private short reserved;

		private Guid manufacturerGuid;

		private Guid productGuid;

		private Guid nameGuid;

		private const int MaxProductNameLength = 32;

		public int Channels => channels;

		public string ProductName => productName;

		public Guid NameGuid => nameGuid;

		public Guid ProductGuid => productGuid;

		public Guid ManufacturerGuid => manufacturerGuid;

		public bool SupportsWaveFormat(SupportedWaveFormat waveFormat)
		{
			return (supportedFormats & waveFormat) == waveFormat;
		}
	}
	public static class WaveCapabilitiesHelpers
	{
		public static readonly Guid MicrosoftDefaultManufacturerId = new Guid("d5a47fa8-6d98-11d1-a21a-00a0c9223196");

		public static readonly Guid DefaultWaveOutGuid = new Guid("E36DC310-6D9A-11D1-A21A-00A0C9223196");

		public static readonly Guid DefaultWaveInGuid = new Guid("E36DC311-6D9A-11D1-A21A-00A0C9223196");

		public static string GetNameFromGuid(Guid guid)
		{
			string result = null;
			using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey("System\\CurrentControlSet\\Control\\MediaCategories"))
			{
				using RegistryKey registryKey2 = registryKey.OpenSubKey(guid.ToString("B"));
				if (registryKey2 != null)
				{
					result = registryKey2.GetValue("Name") as string;
				}
			}
			return result;
		}
	}
	public class WaveInterop
	{
		[Flags]
		public enum WaveInOutOpenFlags
		{
			CallbackNull = 0,
			CallbackFunction = 0x30000,
			CallbackEvent = 0x50000,
			CallbackWindow = 0x10000,
			CallbackThread = 0x20000
		}

		public enum WaveMessage
		{
			WaveInOpen = 958,
			WaveInClose = 959,
			WaveInData = 960,
			WaveOutClose = 956,
			WaveOutDone = 957,
			WaveOutOpen = 955
		}

		public delegate void WaveCallback(IntPtr hWaveOut, WaveMessage message, IntPtr dwInstance, WaveHeader wavhdr, IntPtr dwReserved);

		[DllImport("winmm.dll")]
		public static extern int mmioStringToFOURCC([MarshalAs(UnmanagedType.LPStr)] string s, int flags);

		[DllImport("winmm.dll")]
		public static extern int waveOutGetNumDevs();

		[DllImport("winmm.dll")]
		public static extern MmResult waveOutPrepareHeader(IntPtr hWaveOut, WaveHeader lpWaveOutHdr, int uSize);

		[DllImport("winmm.dll")]
		public static extern MmResult waveOutUnprepareHeader(IntPtr hWaveOut, WaveHeader lpWaveOutHdr, int uSize);

		[DllImport("winmm.dll")]
		public static extern MmResult waveOutWrite(IntPtr hWaveOut, WaveHeader lpWaveOutHdr, int uSize);

		[DllImport("winmm.dll")]
		public static extern MmResult waveOutOpen(out IntPtr hWaveOut, IntPtr uDeviceID, WaveFormat lpFormat, WaveCallback dwCallback, IntPtr dwInstance, WaveInOutOpenFlags dwFlags);

		[DllImport("winmm.dll", EntryPoint = "waveOutOpen")]
		public static extern MmResult waveOutOpenWindow(out IntPtr hWaveOut, IntPtr uDeviceID, WaveFormat lpFormat, IntPtr callbackWindowHandle, IntPtr dwInstance, WaveInOutOpenFlags dwFlags);

		[DllImport("winmm.dll")]
		public static extern MmResult waveOutReset(IntPtr hWaveOut);

		[DllImport("winmm.dll")]
		public static extern MmResult waveOutClose(IntPtr hWaveOut);

		[DllImport("winmm.dll")]
		public static extern MmResult waveOutPause(IntPtr hWaveOut);

		[DllImport("winmm.dll")]
		public static extern MmResult waveOutRestart(IntPtr hWaveOut);

		[DllImport("winmm.dll")]
		public static extern MmResult waveOutGetPosition(IntPtr hWaveOut, ref MmTime mmTime, int uSize);

		[DllImport("winmm.dll")]
		public static extern MmResult waveOutSetVolume(IntPtr hWaveOut, int dwVolume);

		[DllImport("winmm.dll")]
		public static extern MmResult waveOutGetVolume(IntPtr hWaveOut, out int dwVolume);

		[DllImport("winmm.dll", CharSet = CharSet.Auto)]
		public static extern MmResult waveOutGetDevCaps(IntPtr deviceID, out WaveOutCapabilities waveOutCaps, int waveOutCapsSize);

		[DllImport("winmm.dll")]
		public static extern int waveInGetNumDevs();

		[DllImport("winmm.dll", CharSet = CharSet.Auto)]
		public static extern MmResult waveInGetDevCaps(IntPtr deviceID, out WaveInCapabilities waveInCaps, int waveInCapsSize);

		[DllImport("winmm.dll")]
		public static extern MmResult waveInAddBuffer(IntPtr hWaveIn, WaveHeader pwh, int cbwh);

		[DllImport("winmm.dll")]
		public static extern MmResult waveInClose(IntPtr hWaveIn);

		[DllImport("winmm.dll")]
		public static extern MmResult waveInOpen(out IntPtr hWaveIn, IntPtr uDeviceID, WaveFormat lpFormat, WaveCallback dwCallback, IntPtr dwInstance, WaveInOutOpenFlags dwFlags);

		[DllImport("winmm.dll", EntryPoint = "waveInOpen")]
		public static extern MmResult waveInOpenWindow(out IntPtr hWaveIn, IntPtr uDeviceID, WaveFormat lpFormat, IntPtr callbackWindowHandle, IntPtr dwInstance, WaveInOutOpenFlags dwFlags);

		[DllImport("winmm.dll")]
		public static extern MmResult waveInPrepareHeader(IntPtr hWaveIn, WaveHeader lpWaveInHdr, int uSize);

		[DllImport("winmm.dll")]
		public static extern MmResult waveInUnprepareHeader(IntPtr hWaveIn, WaveHeader lpWaveInHdr, int uSize);

		[DllImport("winmm.dll")]
		public static extern MmResult waveInReset(IntPtr hWaveIn);

		[DllImport("winmm.dll")]
		public static extern MmResult waveInStart(IntPtr hWaveIn);

		[DllImport("winmm.dll")]
		public static extern MmResult waveInStop(IntPtr hWaveIn);

		[DllImport("winmm.dll")]
		public static extern MmResult waveInGetPosition(IntPtr hWaveIn, out MmTime mmTime, int uSize);
	}
	[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
	public struct WaveOutCapabilities
	{
		private short manufacturerId;

		private short productId;

		private int driverVersion;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
		private string productName;

		private SupportedWaveFormat supportedFormats;

		private short channels;

		private short reserved;

		private WaveOutSupport support;

		private Guid manufacturerGuid;

		private Guid productGuid;

		private Guid nameGuid;

		private const int MaxProductNameLength = 32;

		public int Channels => channels;

		public bool SupportsPlaybackRateControl => (support & WaveOutSupport.PlaybackRate) == WaveOutSupport.PlaybackRate;

		public string ProductName => productName;

		public Guid NameGuid => nameGuid;

		public Guid ProductGuid => productGuid;

		public Guid ManufacturerGuid => manufacturerGuid;

		public bool SupportsWaveFormat(SupportedWaveFormat waveFormat)
		{
			return (supportedFormats & waveFormat) == waveFormat;
		}
	}
	[Flags]
	public enum SupportedWaveFormat
	{
		WAVE_FORMAT_1M08 = 1,
		WAVE_FORMAT_1S08 = 2,
		WAVE_FORMAT_1M16 = 4,
		WAVE_FORMAT_1S16 = 8,
		WAVE_FORMAT_2M08 = 0x10,
		WAVE_FORMAT_2S08 = 0x20,
		WAVE_FORMAT_2M16 = 0x40,
		WAVE_FORMAT_2S16 = 0x80,
		WAVE_FORMAT_4M08 = 0x100,
		WAVE_FORMAT_4S08 = 0x200,
		WAVE_FORMAT_4M16 = 0x400,
		WAVE_FORMAT_4S16 = 0x800,
		WAVE_FORMAT_44M08 = 0x100,
		WAVE_FORMAT_44S08 = 0x200,
		WAVE_FORMAT_44M16 = 0x400,
		WAVE_FORMAT_44S16 = 0x800,
		WAVE_FORMAT_48M08 = 0x1000,
		WAVE_FORMAT_48S08 = 0x2000,
		WAVE_FORMAT_48M16 = 0x4000,
		WAVE_FORMAT_48S16 = 0x8000,
		WAVE_FORMAT_96M08 = 0x10000,
		WAVE_FORMAT_96S08 = 0x20000,
		WAVE_FORMAT_96M16 = 0x40000,
		WAVE_FORMAT_96S16 = 0x80000
	}
	[Flags]
	internal enum WaveOutSupport
	{
		Pitch = 1,
		PlaybackRate = 2,
		Volume = 4,
		LRVolume = 8,
		Sync = 0x10,
		SampleAccurate = 0x20
	}
	public class AcmMp3FrameDecompressor : IMp3FrameDecompressor, IDisposable
	{
		private readonly AcmStream conversionStream;

		private readonly WaveFormat pcmFormat;

		private bool disposed;

		public WaveFormat OutputFormat => pcmFormat;

		public AcmMp3FrameDecompressor(WaveFormat sourceFormat)
		{
			pcmFormat = AcmStream.SuggestPcmFormat(sourceFormat);
			try
			{
				conversionStream = new AcmStream(sourceFormat, pcmFormat);
			}
			catch (Exception)
			{
				disposed = true;
				GC.SuppressFinalize(this);
				throw;
			}
		}

		public int DecompressFrame(Mp3Frame frame, byte[] dest, int destOffset)
		{
			if (frame == null)
			{
				throw new ArgumentNullException("frame", "You must provide a non-null Mp3Frame to decompress");
			}
			Array.Copy(frame.RawData, conversionStream.SourceBuffer, frame.FrameLength);
			int sourceBytesConverted;
			int num = conversionStream.Convert(frame.FrameLength, out sourceBytesConverted);
			if (sourceBytesConverted != frame.FrameLength)
			{
				throw new InvalidOperationException($"Couldn't convert the whole MP3 frame (converted {sourceBytesConverted}/{frame.FrameLength})");
			}
			Array.Copy(conversionStream.DestBuffer, 0, dest, destOffset, num);
			return num;
		}

		public void Reset()
		{
			conversionStream.Reposition();
		}

		public void Dispose()
		{
			if (!disposed)
			{
				disposed = true;
				if (conversionStream != null)
				{
					conversionStream.Dispose();
				}
				GC.SuppressFinalize(this);
			}
		}

		~AcmMp3FrameDecompressor()
		{
			Dispose();
		}
	}
	public class WaveFormatConversionProvider : IWaveProvider, IDisposable
	{
		private readonly AcmStream conversionStream;

		private readonly IWaveProvider sourceProvider;

		private readonly int preferredSourceReadSize;

		private int leftoverDestBytes;

		private int leftoverDestOffset;

		private int leftoverSourceBytes;

		private bool isDisposed;

		public WaveFormat WaveFormat { get; }

		public WaveFormatConversionProvider(WaveFormat targetFormat, IWaveProvider sourceProvider)
		{
			this.sourceProvider = sourceProvider;
			WaveFormat = targetFormat;
			conversionStream = new AcmStream(sourceProvider.WaveFormat, targetFormat);
			preferredSourceReadSize = Math.Min(sourceProvider.WaveFormat.AverageBytesPerSecond, conversionStream.SourceBuffer.Length);
			preferredSourceReadSize -= preferredSourceReadSize % sourceProvider.WaveFormat.BlockAlign;
		}

		public void Reposition()
		{
			leftoverDestBytes = 0;
			leftoverDestOffset = 0;
			leftoverSourceBytes = 0;
			conversionStream.Reposition();
		}

		public int Read(byte[] buffer, int offset, int count)
		{
			int i = 0;
			if (count % WaveFormat.BlockAlign != 0)
			{
				count -= count % WaveFormat.BlockAlign;
			}
			int num5;
			for (; i < count; i += num5)
			{
				int num = Math.Min(count - i, leftoverDestBytes);
				if (num > 0)
				{
					Array.Copy(conversionStream.DestBuffer, leftoverDestOffset, buffer, offset + i, num);
					leftoverDestOffset += num;
					leftoverDestBytes -= num;
					i += num;
				}
				if (i >= count)
				{
					break;
				}
				int num2 = Math.Min(preferredSourceReadSize, conversionStream.SourceBuffer.Length - leftoverSourceBytes);
				int num3 = sourceProvider.Read(conversionStream.SourceBuffer, leftoverSourceBytes, num2) + leftoverSourceBytes;
				if (num3 == 0)
				{
					break;
				}
				int sourceBytesConverted;
				int num4 = conversionStream.Convert(num3, out sourceBytesConverted);
				if (sourceBytesConverted == 0)
				{
					break;
				}
				leftoverSourceBytes = num3 - sourceBytesConverted;
				if (leftoverSourceBytes > 0)
				{
					Buffer.BlockCopy(conversionStream.SourceBuffer, sourceBytesConverted, conversionStream.SourceBuffer, 0, leftoverSourceBytes);
				}
				if (num4 <= 0)
				{
					break;
				}
				int val = count - i;
				num5 = Math.Min(num4, val);
				if (num5 < num4)
				{
					leftoverDestBytes = num4 - num5;
					leftoverDestOffset = num5;
				}
				Array.Copy(conversionStream.DestBuffer, 0, buffer, i + offset, num5);
			}
			return i;
		}

		protected virtual void Dispose(bool disposing)
		{
			if (!isDisposed)
			{
				isDisposed = true;
				conversionStream?.Dispose();
			}
		}

		public void Dispose()
		{
			GC.SuppressFinalize(this);
			Dispose(disposing: true);
		}

		~WaveFormatConversionProvider()
		{
			Dispose(disposing: false);
		}
	}
	public class WaveFormatConversionStream : WaveStream
	{
		private readonly WaveFormatConversionProvider conversionProvider;

		private readonly WaveFormat targetFormat;

		private readonly long length;

		private long position;

		private readonly WaveStream sourceStream;

		private bool isDisposed;

		public override long Position
		{
			get
			{
				return position;
			}
			set
			{
				value -= value % ((WaveStream)this).BlockAlign;
				long num = EstimateDestToSource(value);
				((Stream)(object)sourceStream).Position = num;
				position = EstimateSourceToDest(((Stream)(object)sourceStream).Position);
				conversionProvider.Reposition();
			}
		}

		public override long Length => length;

		public override WaveFormat WaveFormat => targetFormat;

		public WaveFormatConversionStream(WaveFormat targetFormat, WaveStream sourceStream)
		{
			this.sourceStream = sourceStream;
			this.targetFormat = targetFormat;
			conversionProvider = new WaveFormatConversionProvider(targetFormat, (IWaveProvider)(object)sourceStream);
			length = EstimateSourceToDest((int)((Stream)(object)sourceStream).Length);
			position = 0L;
		}

		public static WaveStream CreatePcmStream(WaveStream sourceStream)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Invalid comparison between Unknown and I4
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			if ((int)sourceStream.WaveFormat.Encoding == 1)
			{
				return sourceStream;
			}
			WaveFormat val = AcmStream.SuggestPcmFormat(sourceStream.WaveFormat);
			if (val.SampleRate < 8000)
			{
				if ((int)sourceStream.WaveFormat.Encoding != 163)
				{
					throw new InvalidOperationException("Invalid suggested output format, please explicitly provide a target format");
				}
				val = new WaveFormat(8000, 16, 1);
			}
			return (WaveStream)(object)new WaveFormatConversionStream(val, sourceStream);
		}

		[Obsolete("can be unreliable, use of this method not encouraged")]
		public int SourceToDest(int source)
		{
			return (int)EstimateSourceToDest(source);
		}

		private long EstimateSourceToDest(long source)
		{
			long num = source * targetFormat.AverageBytesPerSecond / sourceStream.WaveFormat.AverageBytesPerSecond;
			return num - num % targetFormat.BlockAlign;
		}

		private long EstimateDestToSource(long dest)
		{
			long num = dest * sourceStream.WaveFormat.AverageBytesPerSecond / targetFormat.AverageBytesPerSecond;
			return (int)(num - num % sourceStream.WaveFormat.BlockAlign);
		}

		[Obsolete("can be unreliable, use of this method not encouraged")]
		public int DestToSource(int dest)
		{
			return (int)EstimateDestToSource(dest);
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			int num = conversionProvider.Read(buffer, offset, count);
			position += num;
			return num;
		}

		protected override void Dispose(bool disposing)
		{
			if (!isDisposed)
			{
				isDisposed = true;
				if (disposing)
				{
					((Stream)(object)sourceStream).Dispose();
					conversionProvider.Dispose();
				}
			}
			((Stream)this).Dispose(disposing);
		}
	}
	public class WaveInBuffer : IDisposable
	{
		private readonly WaveHeader header;

		private readonly int bufferSize;

		private readonly byte[] buffer;

		private GCHandle hBuffer;

		private IntPtr waveInHandle;

		private GCHandle hHeader;

		private GCHandle hThis;

		public byte[] Data => buffer;

		public bool Done => (header.flags & WaveHeaderFlags.Done) == WaveHeaderFlags.Done;

		public bool InQueue => (header.flags & WaveHeaderFlags.InQueue) == WaveHeaderFlags.InQueue;

		public int BytesRecorded => header.bytesRecorded;

		public int BufferSize => bufferSize;

		public WaveInBuffer(IntPtr waveInHandle, int bufferSize)
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			this.bufferSize = bufferSize;
			buffer = new byte[bufferSize];
			hBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned);
			this.waveInHandle = waveInHandle;
			header = new WaveHeader();
			hHeader = GCHandle.Alloc(header, GCHandleType.Pinned);
			header.dataBuffer = hBuffer.AddrOfPinnedObject();
			header.bufferLength = bufferSize;
			header.loops = 1;
			hThis = GCHandle.Alloc(this);
			header.userData = (IntPtr)hThis;
			MmException.Try(WaveInterop.waveInPrepareHeader(waveInHandle, header, Marshal.SizeOf(header)), "waveInPrepareHeader");
		}

		public void Reuse()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			MmException.Try(WaveInterop.waveInUnprepareHeader(waveInHandle, header, Marshal.SizeOf(header)), "waveUnprepareHeader");
			MmException.Try(WaveInterop.waveInPrepareHeader(waveInHandle, header, Marshal.SizeOf(header)), "waveInPrepareHeader");
			MmException.Try(WaveInterop.waveInAddBuffer(waveInHandle, header, Marshal.SizeOf(header)), "waveInAddBuffer");
		}

		~WaveInBuffer()
		{
			Dispose(disposing: false);
		}

		public void Dispose()
		{
			GC.SuppressFinalize(this);
			Dispose(disposing: true);
		}

		protected void Dispose(bool disposing)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			if (waveInHandle != IntPtr.Zero)
			{
				WaveInterop.waveInUnprepareHeader(waveInHandle, header, Marshal.SizeOf(header));
				waveInHandle = IntPtr.Zero;
			}
			if (hHeader.IsAllocated)
			{
				hHeader.Free();
			}
			if (hBuffer.IsAllocated)
			{
				hBuffer.Free();
			}
			if (hThis.IsAllocated)
			{
				hThis.Free();
			}
		}
	}
	public class WaveInEvent : IWaveIn, IDisposable
	{
		private readonly AutoResetEvent callbackEvent;

		private readonly SynchronizationContext syncContext;

		private IntPtr waveInHandle;

		private volatile CaptureState captureState;

		private WaveInBuffer[] buffers;

		public static int DeviceCount => WaveInterop.waveInGetNumDevs();

		public int BufferMilliseconds { get; set; }

		public int NumberOfBuffers { get; set; }

		public int DeviceNumber { get; set; }

		public WaveFormat WaveFormat { get; set; }

		public event EventHandler<WaveInEventArgs> DataAvailable;

		public event EventHandler<StoppedEventArgs> RecordingStopped;

		public WaveInEvent()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			callbackEvent = new AutoResetEvent(initialState: false);
			syncContext = SynchronizationContext.Current;
			DeviceNumber = 0;
			WaveFormat = new WaveFormat(8000, 16, 1);
			BufferMilliseconds = 100;
			NumberOfBuffers = 3;
			captureState = (CaptureState)0;
		}

		public static WaveInCapabilities GetCapabilities(int devNumber)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			WaveInCapabilities waveInCaps = default(WaveInCapabilities);
			int waveInCapsSize = Marshal.SizeOf(waveInCaps);
			MmException.Try(WaveInterop.waveInGetDevCaps((IntPtr)devNumber, out waveInCaps, waveInCapsSize), "waveInGetDevCaps");
			return waveInCaps;
		}

		private void CreateBuffers()
		{
			int num = BufferMilliseconds * WaveFormat.AverageBytesPerSecond / 1000;
			if (num % WaveFormat.BlockAlign != 0)
			{
				num -= num % WaveFormat.BlockAlign;
			}
			buffers = new WaveInBuffer[NumberOfBuffers];
			for (int i = 0; i < buffers.Length; i++)
			{
				buffers[i] = new WaveInBuffer(waveInHandle, num);
			}
		}

		private void OpenWaveInDevice()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			CloseWaveInDevice();
			MmException.Try(WaveInterop.waveInOpenWindow(out waveInHandle, (IntPtr)DeviceNumber, WaveFormat, callbackEvent.SafeWaitHandle.DangerousGetHandle(), IntPtr.Zero, WaveInterop.WaveInOutOpenFlags.CallbackEvent), "waveInOpen");
			CreateBuffers();
		}

		public void StartRecording()
		{
			//IL_0001: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			if ((int)captureState != 0)
			{
				throw new InvalidOperationException("Already recording");
			}
			OpenWaveInDevice();
			MmException.Try(WaveInterop.waveInStart(waveInHandle), "waveInStart");
			captureState = (CaptureState)1;
			ThreadPool.QueueUserWorkItem(delegate
			{
				RecordThread();
			}, null);
		}

		private void RecordThread()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			Exception e = null;
			try
			{
				DoRecording();
			}
			catch (Exception ex)
			{
				e = ex;
			}
			finally
			{
				captureState = (CaptureState)0;
				RaiseRecordingStoppedEvent(e);
			}
		}

		private void DoRecording()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Invalid comparison between Unknown and I4
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Invalid comparison between Unknown and I4
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			captureState = (CaptureState)2;
			WaveInBuffer[] array = buffers;
			foreach (WaveInBuffer waveInBuffer in array)
			{
				if (!waveInBuffer.InQueue)
				{
					waveInBuffer.Reuse();
				}
			}
			while ((int)captureState == 2)
			{
				if (!callbackEvent.WaitOne())
				{
					continue;
				}
				array = buffers;
				foreach (WaveInBuffer waveInBuffer2 in array)
				{
					if (waveInBuffer2.Done)
					{
						if (waveInBuffer2.BytesRecorded > 0)
						{
							this.DataAvailable?.Invoke(this, new WaveInEventArgs(waveInBuffer2.Data, waveInBuffer2.BytesRecorded));
						}
						if ((int)captureState == 2)
						{
							waveInBuffer2.Reuse();
						}
					}
				}
			}
		}

		private void RaiseRecordingStoppedEvent(Exception e)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			EventHandler<StoppedEventArgs> handler = this.RecordingStopped;
			if (handler == null)
			{
				return;
			}
			if (syncContext == null)
			{
				handler(this, new StoppedEventArgs(e));
				return;
			}
			syncContext.Post(delegate
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Expected O, but got Unknown
				handler(this, new StoppedEventArgs(e));
			}, null);
		}

		public void StopRecording()
		{
			//IL_0001: 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_0019: 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)
			if ((int)captureState != 0)
			{
				captureState = (CaptureState)3;
				MmException.Try(WaveInterop.waveInStop(waveInHandle), "waveInStop");
				MmException.Try(WaveInterop.waveInReset(waveInHandle), "waveInReset");
				callbackEvent.Set();
			}
		}

		public long GetPosition()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			MmTime mmTime = default(MmTime);
			mmTime.wType = 4u;
			MmException.Try(WaveInterop.waveInGetPosition(waveInHandle, out mmTime, Marshal.SizeOf(mmTime)), "waveInGetPosition");
			if (mmTime.wType != 4)
			{
				throw new Exception($"waveInGetPosition: wType -> Expected {4}, Received {mmTime.wType}");
			}
			return mmTime.cb;
		}

		protected virtual void Dispose(bool disposing)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			if (disposing)
			{
				if ((int)captureState != 0)
				{
					StopRecording();
				}
				CloseWaveInDevice();
			}
		}

		private void CloseWaveInDevice()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			WaveInterop.waveInReset(waveInHandle);
			if (buffers != null)
			{
				for (int i = 0; i < buffers.Length; i++)
				{
					buffers[i].Dispose();
				}
				buffers = null;
			}
			WaveInterop.waveInClose(waveInHandle);
			waveInHandle = IntPtr.Zero;
		}

		public MixerLine GetMixerLine()
		{
			if (waveInHandle != IntPtr.Zero)
			{
				return new MixerLine(waveInHandle, 0, MixerFlags.WaveInHandle);
			}
			return new MixerLine((IntPtr)DeviceNumber, 0, MixerFlags.WaveIn);
		}

		public void Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}
	}
	public class WaveOutBuffer : IDisposable
	{
		private readonly WaveHeader header;

		private readonly int bufferSize;

		private readonly byte[] buffer;

		private readonly IWaveProvider waveStream;

		private readonly object waveOutLock;

		private GCHandle hBuffer;

		private IntPtr hWaveOut;

		private GCHandle hHeader;

		private GCHandle hThis;

		public bool InQueue => (header.flags & WaveHeaderFlags.InQueue) == WaveHeaderFlags.InQueue;

		public int BufferSize => bufferSize;

		public WaveOutBuffer(IntPtr hWaveOut, int bufferSize, IWaveProvider bufferFillStream, object waveOutLock)
		{
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			this.bufferSize = bufferSize;
			buffer = new byte[bufferSize];
			hBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned);
			this.hWaveOut = hWaveOut;
			waveStream = bufferFillStream;
			this.waveOutLock = waveOutLock;
			header = new WaveHeader();
			hHeader = GCHandle.Alloc(header, GCHandleType.Pinned);
			header.dataBuffer = hBuffer.AddrOfPinnedObject();
			header.bufferLength = bufferSize;
			header.loops = 1;
			hThis = GCHandle.Alloc(this);
			header.userData = (IntPtr)hThis;
			lock (waveOutLock)
			{
				MmException.Try(WaveInterop.waveOutPrepareHeader(hWaveOut, header, Marshal.SizeOf(header)), "waveOutPrepareHeader");
			}
		}

		~WaveOutBuffer()
		{
			Dispose(disposing: false);
		}

		public void Dispose()
		{
			GC.SuppressFinalize(this);
			Dispose(disposing: true);
		}

		protected void Dispose(bool disposing)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			if (hHeader.IsAllocated)
			{
				hHeader.Free();
			}
			if (hBuffer.IsAllocated)
			{
				hBuffer.Free();
			}
			if (hThis.IsAllocated)
			{
				hThis.Free();
			}
			if (hWaveOut != IntPtr.Zero)
			{
				lock (waveOutLock)
				{
					WaveInterop.waveOutUnprepareHeader(hWaveOut, header, Marshal.SizeOf(header));
				}
				hWaveOut = IntPtr.Zero;
			}
		}

		public bool OnDone()
		{
			int num;
			lock (waveStream)
			{
				num = waveStream.Read(buffer, 0, buffer.Length);
			}
			if (num == 0)
			{
				return false;
			}
			for (int i = num; i < buffer.Length; i++)
			{
				buffer[i] = 0;
			}
			WriteToWaveOut();
			return true;
		}

		private void WriteToWaveOut()
		{
			//IL_0028: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			MmResult val;
			lock (waveOutLock)
			{
				val = WaveInterop.waveOutWrite(hWaveOut, header, Marshal.SizeOf(header));
			}
			if ((int)val != 0)
			{
				throw new MmException(val, "waveOutWrite");
			}
			GC.KeepAlive(this);
		}
	}
	public class WaveOutEvent : IWavePlayer, IDisposable, IWavePosition
	{
		private readonly object waveOutLock;

		private readonly SynchronizationContext syncContext;

		private IntPtr hWaveOut;

		private WaveOutBuffer[] buffers;

		private IWaveProvider waveStream;

		private volatile PlaybackState playbackState;

		private AutoResetEvent callbackEvent;

		public int DesiredLatency { get; set; }

		public int NumberOfBuffers { get; set; }

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


		public WaveFormat OutputWaveFormat => waveStream.WaveFormat;

		public PlaybackState PlaybackState => playbackState;

		public float Volume
		{
			get
			{
				return WaveOutUtils.GetWaveOutVolume(hWaveOut, waveOutLock);
			}
			set
			{
				WaveOutUtils.SetWaveOutVolume(value, hWaveOut, waveOutLock);
			}
		}

		public event EventHandler<StoppedEventArgs> PlaybackStopped;

		public WaveOutEvent()
		{
			syncContext = SynchronizationContext.Current;
			if (syncContext != null && (syncContext.GetType().Name == "LegacyAspNetSynchronizationContext" || syncContext.GetType().Name == "AspNetSynchronizationContext"))
			{
				syncContext = null;
			}
			DesiredLatency = 300;
			NumberOfBuffers = 2;
			waveOutLock = new object();
		}

		public void Init(IWaveProvider waveProvider)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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)
			if ((int)playbackState != 0)
			{
				throw new InvalidOperationException("Can't re-initialize during playback");
			}
			if (hWaveOut != IntPtr.Zero)
			{
				DisposeBuffers();
				CloseWaveOut();
			}
			callbackEvent = new AutoResetEvent(initialState: false);
			waveStream = waveProvider;
			int bufferSize = waveProvider.WaveFormat.ConvertLatencyToByteSize((DesiredLatency + NumberOfBuffers - 1) / NumberOfBuffers);
			MmResult val;
			lock (waveOutLock)
			{
				val = WaveInterop.waveOutOpenWindow(out hWaveOut, (IntPtr)DeviceNumber, waveStream.WaveFormat, callbackEvent.SafeWaitHandle.DangerousGetHandle(), IntPtr.Zero, WaveInterop.WaveInOutOpenFlags.CallbackEvent);
			}
			MmException.Try(val, "waveOutOpen");
			buffers = new WaveOutBuffer[NumberOfBuffers];
			playbackState = (PlaybackState)0;
			for (int i = 0; i < NumberOfBuffers; i++)
			{
				buffers[i] = new WaveOutBuffer(hWaveOut, bufferSize, waveStream, waveOutLock);
			}
		}

		public void Play()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Invalid comparison between Unknown and I4
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (buffers == null || waveStream == null)
			{
				throw new InvalidOperationException("Must call Init first");
			}
			if ((int)playbackState == 0)
			{
				playbackState = (PlaybackState)1;
				callbackEvent.Set();
				ThreadPool.QueueUserWorkItem(delegate
				{
					PlaybackThread();
				}, null);
			}
			else if ((int)playbackState == 2)
			{
				Resume();
				callbackEvent.Set();
			}
		}

		private void PlaybackThread()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			Exception e = null;
			try
			{
				DoPlayback();
			}
			catch (Exception ex)
			{
				e = ex;
			}
			finally
			{
				playbackState = (PlaybackState)0;
				RaisePlaybackStoppedEvent(e);
			}
		}

		private void DoPlayback()
		{
			//IL_0073: 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_0029: Invalid comparison between Unknown and I4
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			while ((int)playbackState != 0)
			{
				if (!callbackEvent.WaitOne(DesiredLatency))
				{
					_ = playbackState;
					_ = 1;
				}
				if ((int)playbackState != 1)
				{
					continue;
				}
				int num = 0;
				WaveOutBuffer[] array = buffers;
				foreach (WaveOutBuffer waveOutBuffer in array)
				{
					if (waveOutBuffer.InQueue || waveOutBuffer.OnDone())
					{
						num++;
					}
				}
				if (num == 0)
				{
					playbackState = (PlaybackState)0;
					callbackEvent.Set();
				}
			}
		}

		public void Pause()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if ((int)playbackState == 1)
			{
				playbackState = (PlaybackState)2;
				MmResult val;
				lock (waveOutLock)
				{
					val = WaveInterop.waveOutPause(hWaveOut);
				}
				if ((int)val != 0)
				{
					throw new MmException(val, "waveOutPause");
				}
			}
		}

		private void Resume()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			//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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			if ((int)playbackState == 2)
			{
				MmResult val;
				lock (waveOutLock)
				{
					val = WaveInterop.waveOutRestart(hWaveOut);
				}
				if ((int)val != 0)
				{
					throw new MmException(val, "waveOutRestart");
				}
				playbackState = (PlaybackState)1;
			}
		}

		public void Stop()
		{
			//IL_0001: 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_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)
			//IL_003c: 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)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if ((int)playbackState != 0)
			{
				playbackState = (PlaybackState)0;
				MmResult val;
				lock (waveOutLock)
				{
					val = WaveInterop.waveOutReset(hWaveOut);
				}
				if ((int)val != 0)
				{
					throw new MmException(val, "waveOutReset");
				}
				callbackEvent.Set();
			}
		}

		public long GetPosition()
		{
			return WaveOutUtils.GetPositionBytes(hWaveOut, waveOutLock);
		}

		public void Dispose()
		{
			GC.SuppressFinalize(this);
			Dispose(disposing: true);
		}

		protected void Dispose(bool disposing)
		{
			Stop();
			if (disposing)
			{
				DisposeBuffers();
			}
			CloseWaveOut();
		}

		private void CloseWaveOut()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (callbackEvent != null)
			{
				callbackEvent.Close();
				callbackEvent = null;
			}
			lock (waveOutLock)
			{
				if (hWaveOut != IntPtr.Zero)
				{
					WaveInterop.waveOutClose(hWaveOut);
					hWaveOut = IntPtr.Zero;
				}
			}
		}

		private void DisposeBuffers()
		{
			if (buffers != null)
			{
				WaveOutBuffer[] array = buffers;
				for (int i = 0; i < array.Length; i++)
				{
					array[i].Dispose();
				}
				buffers = null;
			}
		}

		~WaveOutEvent()
		{
			Dispose(disposing: false);
		}

		private void RaisePlaybackStoppedEvent(Exception e)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			EventHandler<StoppedEventArgs> handler = this.PlaybackStopped;
			if (handler == null)
			{
				return;
			}
			if (syncContext == null)
			{
				handler(this, new StoppedEventArgs(e));
				return;
			}
			syncContext.Post(delegate
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Expected O, but got Unknown
				handler(this, new StoppedEventArgs(e));
			}, null);
		}
	}
	public static class WaveOutUtils
	{
		public static float GetWaveOutVolume(IntPtr hWaveOut, object lockObject)
		{
			//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_0021: Unknown result type (might be due to invalid IL or missing references)
			MmResult val;
			int dwVolume;
			lock (lockObject)
			{
				val = WaveInterop.waveOutGetVolume(hWaveOut, out dwVolume);
			}
			MmException.Try(val, "waveOutGetVolume");
			return (float)(dwVolume & 0xFFFF) / 65535f;
		}

		public static void SetWaveOutVolume(float value, IntPtr hWaveOut, object lockObject)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			if (value < 0f)
			{
				throw new ArgumentOutOfRangeException("value", "Volume must be between 0.0 and 1.0");
			}
			if (value > 1f)
			{
				throw new ArgumentOutOfRangeException("value", "Volume must be between 0.0 and 1.0");
			}
			int dwVolume = (int)(value * 65535f) + ((int)(value * 65535f) << 16);
			MmResult val;
			lock (lockObject)
			{
				val = WaveInterop.waveOutSetVolume(hWaveOut, dwVolume);
			}
			MmException.Try(val, "waveOutSetVolume");
		}

		public static long GetPositionBytes(IntPtr hWaveOut, object lockObject)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			lock (lockObject)
			{
				MmTime mmTime = default(MmTime);
				mmTime.wType = 4u;
				MmException.Try(WaveInterop.waveOutGetPosition(hWaveOut, ref mmTime, Marshal.SizeOf(mmTime)), "waveOutGetPosition");
				if (mmTime.wType != 4)
				{
					throw new Exception($"waveOutGetPosition: wType -> Expected {4}, Received {mmTime.wType}");
				}
				return mmTime.cb;
			}
		}
	}
}
namespace NAudio.Wave.Compression
{
	public class AcmDriver : IDisposable
	{
		private static List<AcmDriver> drivers;

		private AcmDriverDetails details;

		private IntPtr driverId;

		private IntPtr driverHandle;

		private List<AcmFormatTag> formatTags;

		private List<AcmFormat> tempFormatsList;

		private IntPtr localDllHandle;

		public int MaxFormatSize
		{
			get
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				MmException.Try(AcmInterop.acmMetrics(driverHandle, AcmMetrics.MaxSizeFormat, out var output), "acmMetrics");
				return output;
			}
		}

		public string ShortName => details.shortName;

		public string LongName => details.longName;

		public IntPtr DriverId => driverId;

		public IEnumerable<AcmFormatTag> FormatTags
		{
			get
			{
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				if (formatTags == null)
				{
					if (driverHandle == IntPtr.Zero)
					{
						throw new InvalidOperationException("Driver must be opened first");
					}
					formatTags = new List<AcmFormatTag>();
					AcmFormatTagDetails formatTagDetails = default(AcmFormatTagDetails);
					formatTagDetails.structureSize = Marshal.SizeOf(formatTagDetails);
					MmException.Try(AcmInterop.acmFormatTagEnum(driverHandle, ref formatTagDetails, AcmFormatTagEnumCallback, IntPtr.Zero, 0), "acmFormatTagEnum");
				}
				return formatTags;
			}
		}

		public static bool IsCodecInstalled(string shortName)
		{
			foreach (AcmDriver item in EnumerateAcmDrivers())
			{
				if (item.ShortName == shortName)
				{
					return true;
				}
			}
			return false;
		}

		public static AcmDriver AddLocalDriver(string driverFile)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			IntPtr intPtr = NativeMethods.LoadLibrary(driverFile);
			if (intPtr == IntPtr.Zero)
			{
				throw new ArgumentException("Failed to load driver file");
			}
			IntPtr procAddress = NativeMethods.GetProcAddress(intPtr, "DriverProc");
			if (procAddress == IntPtr.Zero)
			{
				NativeMethods.FreeLibrary(intPtr);
				throw new ArgumentException("Failed to discover DriverProc");
			}
			IntPtr hAcmDriver;
			MmResult val = AcmInterop.acmDriverAdd(out hAcmDriver, intPtr, procAddress, 0, AcmDriverAddFlags.Function);
			if ((int)val != 0)
			{
				NativeMethods.FreeLibrary(intPtr);
				throw new MmException(val, "acmDriverAdd");
			}
			AcmDriver acmDriver = new AcmDriver(hAcmDriver);
			if (string.IsNullOrEmpty(acmDriver.details.longName))
			{
				acmDriver.details.longName = "Local driver: " + Path.GetFileName(driverFile);
				acmDriver.localDllHandle = intPtr;
			}
			return acmDriver;
		}

		public static void RemoveLocalDriver(AcmDriver localDriver)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (localDriver.localDllHandle == IntPtr.Zero)
			{
				throw new ArgumentException("Please pass in the AcmDriver returned by the AddLocalDriver method");
			}
			MmResult val = AcmInterop.acmDriverRemove(localDriver.driverId, 0);
			NativeMethods.FreeLibrary(localDriver.localDllHandle);
			MmException.Try(val, "acmDriverRemove");
		}

		public static bool ShowFormatChooseDialog(IntPtr ownerWindowHandle, string windowTitle, AcmFormatEnumFlags enumFlags, WaveFormat enumFormat, out WaveFormat selectedFormat, out string selectedFormatDescription, out string selectedFormatTagDescription)
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: 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_00ea: Invalid comparison between Unknown and I4
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Invalid comparison between Unknown and I4
			//IL_00ec: 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_00f5: Unknown result type (might be due to invalid IL or missing references)
			AcmFormatChoose formatChoose = default(AcmFormatChoose);
			formatChoose.structureSize = Marshal.SizeOf(formatChoose);
			formatChoose.styleFlags = AcmFormatChooseStyleFlags.None;
			formatChoose.ownerWindowHandle = ownerWindowHandle;
			int num = 200;
			formatChoose.selectedWaveFormatPointer = Marshal.AllocHGlobal(num);
			formatChoose.selectedWaveFormatByteSize = num;
			formatChoose.title = windowTitle;
			formatChoose.name = null;
			formatChoose.formatEnumFlags = enumFlags;
			formatChoose.waveFormatEnumPointer = IntPtr.Zero;
			if (enumFormat != null)
			{
				IntPtr intPtr = Marshal.AllocHGlobal(Marshal.SizeOf<WaveFormat>(enumFormat));
				Marshal.StructureToPtr<WaveFormat>(enumFormat, intPtr, fDeleteOld: false);
				formatChoose.waveFormatEnumPointer = intPtr;
			}
			formatChoose.instanceHandle = IntPtr.Zero;
			formatChoose.templateName = null;
			MmResult val = AcmInterop.acmFormatChoose(ref formatChoose);
			selectedFormat = null;
			selectedFormatDescription = null;
			selectedFormatTagDescription = null;
			if ((int)val == 0)
			{
				selectedFormat = WaveFormat.MarshalFromPtr(formatChoose.selectedWaveFormatPointer);
				selectedFormatDescription = formatChoose.formatDescription;
				selectedFormatTagDescription = formatChoose.formatTagDescription;
			}
			Marshal.FreeHGlobal(formatChoose.waveFormatEnumPointer);
			Marshal.FreeHGlobal(formatChoose.selectedWaveFormatPointer);
			if ((int)val != 515 && (int)val != 0)
			{
				throw new MmException(val, "acmFormatChoose");
			}
			return (int)val == 0;
		}

		public static AcmDriver FindByShortName(string shortName)
		{
			foreach (AcmDriver item in EnumerateAcmDrivers())
			{
				if (item.ShortName == shortName)
				{
					return item;
				}
			}
			return null;
		}

		public static IEnumerable<AcmDriver> EnumerateAcmDrivers()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			drivers = new List<AcmDriver>();
			MmException.Try(AcmInterop.acmDriverEnum(DriverEnumCallback, IntPtr.Zero, (AcmDriverEnumFlags)0), "acmDriverEnum");
			return drivers;
		}

		private static bool DriverEnumCallback(IntPtr hAcmDriver, IntPtr dwInstance, AcmDriverDetailsSupportFlags flags)
		{
			drivers.Add(new AcmDriver(hAcmDriver));
			return true;
		}

		private AcmDriver(IntPtr hAcmDriver)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			driverId = hAcmDriver;
			details = default(AcmDriverDetails);
			details.structureSize = Marshal.SizeOf(details);
			MmException.Try(AcmInterop.acmDriverDetails(hAcmDriver, ref details, 0), "acmDriverDetails");
		}

		public override string ToString()
		{
			return LongName;
		}

		public IEnumerable<AcmFormat> GetFormats(AcmFormatTag formatTag)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected I4, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			if (driverHandle == IntPtr.Zero)
			{
				throw new InvalidOperationException("Driver must be opened first");
			}
			tempFormatsList = new List<AcmFormat>();
			AcmFormatDetails formatDetails = default(AcmFormatDetails);
			formatDetails.structSize = Marshal.SizeOf(formatDetails);
			formatDetails.waveFormatByteSize = 1024;
			formatDetails.waveFormatPointer = Marshal.AllocHGlobal(formatDetails.waveFormatByteSize);
			formatDetails.formatTag = (int)formatTag.FormatTag;
			MmResult val = AcmInterop.acmFormatEnum(driverHandle, ref formatDetails, AcmFormatEnumCallback, IntPtr.Zero, AcmFormatEnumFlags.None);
			Marshal.FreeHGlobal(formatDetails.waveFormatPointer);
			MmException.Try(val, "acmFormatEnum");
			return tempFormatsList;
		}

		public void Open()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if (driverHandle == IntPtr.Zero)
			{
				MmException.Try(AcmInterop.acmDriverOpen(out driverHandle, DriverId, 0), "acmDriverOpen");
			}
		}

		public void Close()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (driverHandle != IntPtr.Zero)
			{
				MmException.Try(AcmInterop.acmDriverClose(driverHandle, 0), "acmDriverClose");
				driverHandle = IntPtr.Zero;
			}
		}

		private bool AcmFormatTagEnumCallback(IntPtr hAcmDriverId, ref AcmFormatTagDetails formatTagDetails, IntPtr dwInstance, AcmDriverDetailsSupportFlags flags)
		{
			formatTags.Add(new AcmFormatTag(formatTagDetails));
			return true;
		}

		private bool AcmFormatEnumCallback(IntPtr hAcmDriverId, ref AcmFormatDetails formatDetails, IntPtr dwInstance, AcmDriverDetailsSupportFlags flags)
		{
			tempFormatsList.Add(new AcmFormat(formatDetails));
			return true;
		}

		public void Dispose()
		{
			if (driverHandle != IntPtr.Zero)
			{
				Close();
				GC.SuppressFinalize(this);
			}
		}
	}
	internal enum AcmDriverAddFlags
	{
		Local = 0,
		Global = 8,
		Function = 3,
		NotifyWindowHandle = 4
	}
	[StructLayout(LayoutKind.Sequential, Pack = 2)]
	internal struct AcmDriverDetails
	{
		public int structureSize;

		public uint fccType;

		public uint fccComp;

		public ushort manufacturerId;

		public ushort productId;

		public uint acmVersion;

		public uint driverVersion;

		public AcmDriverDetailsSupportFlags supportFlags;

		public int formatTagsCount;

		public int filterTagsCount;

		public IntPtr hicon;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
		public string shortName;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
		public string longName;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
		public string copyright;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
		public string licensing;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 512)]
		public string features;

		private const int ShortNameChars = 32;

		private const int LongNameChars = 128;

		private const int CopyrightChars = 80;

		private const int LicensingChars = 128;

		private const int FeaturesChars = 512;
	}
	[Flags]
	public enum AcmDriverDetailsSupportFlags
	{
		Codec = 1,
		Converter = 2,
		Filter = 4,
		Hardware = 8,
		Async = 0x10,
		Local = 0x40000000,
		Disabled = int.MinValue
	}
	[Flags]
	internal enum AcmDriverEnumFlags
	{
		NoLocal = 0x40000000,
		Disabled = int.MinValue
	}
	public class AcmFormat
	{
		private readonly AcmFormatDetails formatDetails;

		public int FormatIndex => formatDetails.formatIndex;

		public WaveFormatEncoding FormatTag => (WaveFormatEncoding)(ushort)formatDetails.formatTag;

		public AcmDriverDetailsSupportFlags SupportFlags => formatDetails.supportFlags;

		public WaveFormat WaveFormat { get; private set; }

		public int WaveFormatByteSize => formatDetails.waveFormatByteSize;

		public string FormatDescription => formatDetails.formatDescription;

		internal AcmFormat(AcmFormatDetails formatDetails)
		{
			this.formatDetails = formatDetails;
			WaveFormat = WaveFormat.MarshalFromPtr(formatDetails.waveFormatPointer);
		}
	}
	[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
	internal struct AcmFormatChoose
	{
		public int structureSize;

		public AcmFormatChooseStyleFlags styleFlags;

		public IntPtr ownerWindowHandle;

		public IntPtr selectedWaveFormatPointer;

		public int selectedWaveFormatByteSize;

		[MarshalAs(UnmanagedType.LPTStr)]
		public string title;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 48)]
		public string formatTagDescription;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
		public string formatDescription;

		[MarshalAs(UnmanagedType.LPTStr)]
		public string name;

		public int nameByteSize;

		public AcmFormatEnumFlags formatEnumFlags;

		public IntPtr waveFormatEnumPointer;

		public IntPtr instanceHandle;

		[MarshalAs(UnmanagedType.LPTStr)]
		public string templateName;

		public IntPtr customData;

		public AcmInterop.AcmFormatChooseHookProc windowCallbackFunction;
	}
	[Flags]
	internal enum AcmFormatChooseStyleFlags
	{
		None = 0,
		ShowHelp = 4,
		EnableHook = 8,
		EnableTemplate = 0x10,
		EnableTemplateHandle = 0x20,
		InitToWfxStruct = 0x40,
		ContextHelp = 0x80
	}
	[StructLayout(LayoutKind.Sequential, Pack = 4)]
	internal struct AcmFormatDetails
	{
		public int structSize;

		public int formatIndex;

		public int formatTag;

		public AcmDriverDetailsSupportFlags supportFlags;

		public IntPtr waveFormatPointer;

		public int waveFormatByteSize;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
		public string formatDescription;

		public const int FormatDescriptionChars = 128;
	}
	[Flags]
	public enum AcmFormatEnumFlags
	{
		None = 0,
		Convert = 0x100000,
		Hardware = 0x400000,
		Input = 0x800000,
		Channels = 0x20000,
		SamplesPerSecond = 0x40000,
		Output = 0x1000000,
		Suggest = 0x200000,
		BitsPerSample = 0x80000,
		FormatTag = 0x10000
	}
	[Flags]
	internal enum AcmFormatSuggestFlags
	{
		FormatTag = 0x10000,
		Channels = 0x20000,
		SamplesPerSecond = 0x40000,
		BitsPerSample = 0x80000,
		TypeMask = 0xFF0000
	}
	public class AcmFormatTag
	{
		private AcmFormatTagDetails formatTagDetails;

		public int FormatTagIndex => formatTagDetails.formatTagIndex;

		public WaveFormatEncoding FormatTag => (WaveFormatEncoding)(ushort)formatTagDetails.formatTag;

		public int FormatSize => formatTagDetails.formatSize;

		public AcmDriverDetailsSupportFlags SupportFlags => formatTagDetails.supportFlags;

		public int StandardFormatsCount => formatTagDetails.standardFormatsCount;

		public string FormatDescription => formatTagDetails.formatDescription;

		internal AcmFormatTag(AcmFormatTagDetails formatTagDetails)
		{
			this.formatTagDetails = formatTagDetails;
		}
	}
	internal struct AcmFormatTagDetails
	{
		public int structureSize;

		public int formatTagIndex;

		public int formatTag;

		public int formatSize;

		public AcmDriverDetailsSupportFlags supportFlags;

		public int standardFormatsCount;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 48)]
		public string formatDescription;

		public const int FormatTagDescriptionChars = 48;
	}
	internal class AcmInterop
	{
		public delegate bool AcmDriverEnumCallback(IntPtr hAcmDriverId, IntPtr instance, AcmDriverDetailsSupportFlags flags);

		public delegate bool AcmFormatEnumCallback(IntPtr hAcmDriverId, ref AcmFormatDetails formatDetails, IntPtr dwInstance, AcmDriverDetailsSupportFlags flags);

		public delegate bool AcmFormatTagEnumCallback(IntPtr hAcmDriverId, ref AcmFormatTagDetails formatTagDetails, IntPtr dwInstance, AcmDriverDetailsSupportFlags flags);

		public delegate bool AcmFormatChooseHookProc(IntPtr windowHandle, int message, IntPtr wParam, IntPtr lParam);

		[DllImport("msacm32.dll")]
		public static extern MmResult acmDriverAdd(out IntPtr driverHandle, IntPtr driverModule, IntPtr driverFunctionAddress, int priority, AcmDriverAddFlags flags);

		[DllImport("msacm32.dll")]
		public static extern MmResult acmDriverRemove(IntPtr driverHandle, int removeFlags);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmDriverClose(IntPtr hAcmDriver, int closeFlags);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmDriverEnum(AcmDriverEnumCallback fnCallback, IntPtr dwInstance, AcmDriverEnumFlags flags);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmDriverDetails(IntPtr hAcmDriver, ref AcmDriverDetails driverDetails, int reserved);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmDriverOpen(out IntPtr pAcmDriver, IntPtr hAcmDriverId, int openFlags);

		[DllImport("Msacm32.dll", EntryPoint = "acmFormatChooseW")]
		public static extern MmResult acmFormatChoose(ref AcmFormatChoose formatChoose);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmFormatEnum(IntPtr hAcmDriver, ref AcmFormatDetails formatDetails, AcmFormatEnumCallback callback, IntPtr instance, AcmFormatEnumFlags flags);

		[DllImport("Msacm32.dll", EntryPoint = "acmFormatSuggest")]
		public static extern MmResult acmFormatSuggest2(IntPtr hAcmDriver, IntPtr sourceFormatPointer, IntPtr destFormatPointer, int sizeDestFormat, AcmFormatSuggestFlags suggestFlags);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmFormatTagEnum(IntPtr hAcmDriver, ref AcmFormatTagDetails formatTagDetails, AcmFormatTagEnumCallback callback, IntPtr instance, int reserved);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmMetrics(IntPtr hAcmObject, AcmMetrics metric, out int output);

		[DllImport("Msacm32.dll", EntryPoint = "acmStreamOpen")]
		public static extern MmResult acmStreamOpen2(out IntPtr hAcmStream, IntPtr hAcmDriver, IntPtr sourceFormatPointer, IntPtr destFormatPointer, [In] WaveFilter waveFilter, IntPtr callback, IntPtr instance, AcmStreamOpenFlags openFlags);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmStreamClose(IntPtr hAcmStream, int closeFlags);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmStreamConvert(IntPtr hAcmStream, [In][Out] AcmStreamHeaderStruct streamHeader, AcmStreamConvertFlags streamConvertFlags);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmStreamPrepareHeader(IntPtr hAcmStream, [In][Out] AcmStreamHeaderStruct streamHeader, int prepareFlags);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmStreamReset(IntPtr hAcmStream, int resetFlags);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmStreamSize(IntPtr hAcmStream, int inputBufferSize, out int outputBufferSize, AcmStreamSizeFlags flags);

		[DllImport("Msacm32.dll")]
		public static extern MmResult acmStreamUnprepareHeader(IntPtr hAcmStream, [In][Out] AcmStreamHeaderStruct streamHeader, int flags);
	}
	public class AcmStream : IDisposable
	{
		private IntPtr streamHandle;

		private IntPtr driverHandle;

		private AcmStreamHeader streamHeader;

		private readonly WaveFormat sourceFormat;

		public byte[] SourceBuffer => streamHeader.SourceBuffer;

		public byte[] DestBuffer => streamHeader.DestBuffer;

		public AcmStream(WaveFormat sourceFormat, WaveFormat destFormat)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				streamHandle = IntPtr.Zero;
				this.sourceFormat = sourceFormat;
				int num = Math.Max(65536, sourceFormat.AverageBytesPerSecond);
				num -= num % sourceFormat.BlockAlign;
				IntPtr intPtr = WaveFormat.MarshalToPtr(sourceFormat);
				IntPtr intPtr2 = WaveFormat.MarshalToPtr(destFormat);
				try
				{
					MmException.Try(AcmInterop.acmStreamOpen2(out streamHandle, IntPtr.Zero, intPtr, intPtr2, null, IntPtr.Zero, IntPtr.Zero, AcmStreamOpenFlags.NonRealTime), "acmStreamOpen");
				}
				finally
				{
					Marshal.FreeHGlobal(intPtr);
					Marshal.FreeHGlobal(intPtr2);
				}
				int destBufferLength = SourceToDest(num);
				streamHeader = new AcmStreamHeader(streamHandle, num, destBufferLength);
				driverHandle = IntPtr.Zero;
			}
			catch
			{
				Dispose();
				throw;
			}
		}

		public AcmStream(IntPtr driverId, WaveFormat sourceFormat, WaveFilter waveFilter)
		{
			//IL_0031: 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)
			int num = Math.Max(16384, sourceFormat.AverageBytesPerSecond);
			this.sourceFormat = sourceFormat;
			num -= num % sourceFormat.BlockAlign;
			MmException.Try(AcmInterop.acmDriverOpen(out driverHandle, driverId, 0), "acmDriverOpen");
			IntPtr intPtr = WaveFormat.MarshalToPtr(sourceFormat);
			try
			{
				MmException.Try(AcmInterop.acmStreamOpen2(out streamHandle, driverHandle, intPtr, intPtr, waveFilter, IntPtr.Zero, IntPtr.Zero, AcmStreamOpenFlags.NonRealTime), "acmStreamOpen");
			}
			finally
			{
				Marshal.FreeHGlobal(intPtr);
			}
			streamHeader = new AcmStreamHeader(streamHandle, num, SourceToDest(num));
		}

		public int SourceToDest(int source)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (source == 0)
			{
				return 0;
			}
			MmException.Try(AcmInterop.acmStreamSize(streamHandle, source, out var outputBufferSize, AcmStreamSizeFlags.Source), "acmStreamSize");
			return outputBufferSize;
		}

		public int DestToSource(int dest)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (dest == 0)
			{
				return 0;
			}
			MmException.Try(AcmInterop.acmStreamSize(streamHandle, dest, out var outputBufferSize, AcmStreamSizeFlags.Destination), "acmStreamSize");
			return outputBufferSize;
		}

		public static WaveFormat SuggestPcmFormat(WaveFormat compressedFormat)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			WaveFormat val = new WaveFormat(compressedFormat.SampleRate, 16, compressedFormat.Channels);
			IntPtr intPtr = WaveFormat.MarshalToPtr(val);
			IntPtr intPtr2 = WaveFormat.MarshalToPtr(compressedFormat);
			try
			{
				MmResult val2 = AcmInterop.acmFormatSuggest2(IntPtr.Zero, intPtr2, intPtr, Marshal.SizeOf<WaveFormat>(val), AcmFormatSuggestFlags.FormatTag);
				val = WaveFormat.MarshalFromPtr(intPtr);
				MmException.Try(val2, "acmFormatSuggest");
				return val;
			}
			finally
			{
				Marshal.FreeHGlobal(intPtr);
				Marshal.FreeHGlobal(intPtr2);
			}
		}

		public void Reposition()
		{
			streamHeader.Reposition();
		}

		public int Convert(int bytesToConvert, out int sourceBytesConverted)
		{
			if (bytesToConvert % sourceFormat.BlockAlign != 0)
			{
				bytesToConvert -= bytesToConvert % sourceFormat.BlockAlign;
			}
			return streamHeader.Convert(bytesToConvert, out sourceBytesConverted);
		}

		[Obsolete("Call the version returning sourceBytesConverted instead")]
		public int Convert(int bytesToConvert)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			int sourceBytesConverted;
			int result = Convert(bytesToConvert, out sourceBytesConverted);
			if (sourceBytesConverted != bytesToConvert)
			{
				throw new MmException((MmResult)8, "AcmStreamHeader.Convert didn't convert everything");
			}
			return result;
		}

		public void Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}

		protected virtual void Dispose(bool disposing)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			if (disposing && streamHeader != null)
			{
				streamHeader.Dispose();
				streamHeader = null;
			}
			if (streamHandle != IntPtr.Zero)
			{
				MmResult val = AcmInterop.acmStreamClose(streamHandle, 0);
				streamHandle = IntPtr.Zero;
				if ((int)val != 0)
				{
					throw new MmException(val, "acmStreamClose");
				}
			}
			if (driverHandle != IntPtr.Zero)
			{
				AcmInterop.acmDriverClose(driverHandle, 0);
				driverHandle = IntPtr.Zero;
			}
		}

		~AcmStream()
		{
			Dispose(disposing: false);
		}
	}
	internal class AcmStreamHeader : IDisposable
	{
		private AcmStreamHeaderStruct streamHeader;

		private GCHandle hSourceBuffer;

		private GCHandle hDestBuffer;

		private IntPtr streamHandle;

		private bool firstTime;

		private bool disposed;

		public byte[] SourceBuffer { get; private set; }

		public byte[] DestBuffer { get; private set; }

		public AcmStreamHeader(IntPtr streamHandle, int sourceBufferLength, int destBufferLength)
		{
			streamHeader = new AcmStreamHeaderStruct();
			SourceBuffer = new byte[sourceBufferLength];
			hSourceBuffer = GCHandle.Alloc(SourceBuffer, GCHandleType.Pinned);
			DestBuffer = new byte[destBufferLength];
			hDestBuffer = GCHandle.Alloc(DestBuffer, GCHandleType.Pinned);
			this.streamHandle = streamHandle;
			firstTime = true;
		}

		private void Prepare()
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			streamHeader.cbStruct = Marshal.SizeOf(streamHeader);
			streamHeader.sourceBufferLength = SourceBuffer.Length;
			streamHeader.sourceBufferPointer = hSourceBuffer.AddrOfPinnedObject();
			streamHeader.destBufferLength = DestBuffer.Length;
			streamHeader.destBufferPointer = hDestBuffer.AddrOfPinnedObject();
			MmException.Try(AcmInterop.acmStreamPrepareHeader(streamHandle, streamHeader, 0), "acmStreamPrepareHeader");
		}

		private void Unprepare()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			streamHeader.sourceBufferLength = SourceBuffer.Length;
			streamHeader.sourceBufferPointer = hSourceBuffer.AddrOfPinnedObject();
			streamHeader.destBufferLength = DestBuffer.Length;
			streamHeader.destBufferPointer = hDestBuffer.AddrOfPinnedObject();
			MmResult val = AcmInterop.acmStreamUnprepareHeader(streamHandle, streamHeader, 0);
			if ((int)val != 0)
			{
				throw new MmException(val, "acmStreamUnprepareHeader");
			}
		}

		public void Reposition()
		{
			firstTime = true;
		}

		public int Convert(int bytesToConvert, out int sourceBytesConverted)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			Prepare();
			try
			{
				streamHeader.sourceBufferLength = bytesToConvert;
				streamHeader.sourceBufferLengthUsed = bytesToConvert;
				AcmStreamConvertFlags streamConvertFlags = (firstTime ? (AcmStreamConvertFlags.BlockAlign | AcmStreamConvertFlags.Start) : AcmStreamConvertFlags.BlockAlign);
				MmException.Try(AcmInterop.acmStreamConvert(streamHandle, streamHeader, streamConvertFlags), "acmStreamConvert");
				firstTime = false;
				sourceBytesConverted = streamHeader.sourceBufferLengthUsed;
			}
			finally
			{
				Unprepare();
			}
			return streamHeader.destBufferLengthUsed;
		}

		public void Dispose()
		{
			GC.SuppressFinalize(this);
			Dispose(disposing: true);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (!disposed)
			{
				SourceBuffer = null;
				DestBuffer = null;
				hSourceBuffer.Free();
				hDestBuffer.Free();
			}
			disposed = true;
		}

		~AcmStreamHeader()
		{
			Dispose(disposing: false);
		}
	}
	[Flags]
	internal enum AcmStreamHeaderStatusFlags
	{
		Done = 0x10000,
		Prepared = 0x20000,
		InQueue = 0x100000
	}
	[StructLayout(LayoutKind.Sequential, Size = 128)]
	internal class AcmStreamHeaderStruct
	{
		public int cbStruct;

		public AcmStreamHeaderStatusFlags fdwStatus;

		public IntPtr userData;

		public IntPtr sourceBufferPointer;

		public int sourceBufferLength;

		public int sourceBufferLengthUsed;

		public IntPtr sourceUserData;

		public IntPtr destBufferPointer;

		public int destBufferLength;

		public int destBufferLengthUsed;

		public IntPtr destUserData;
	}
	[Flags]
	internal enum AcmStreamOpenFlags
	{
		Query = 1,
		Async = 2,
		NonRealTime = 4,
		CallbackTypeMask = 0x70000,
		CallbackNull = 0,
		CallbackWindow = 0x10000,
		CallbackTask = 0x20000,
		CallbackFunction = 0x30000,
		CallbackThread = 0x20000,
		CallbackEvent = 0x50000
	}
	internal enum AcmStreamSizeFlags
	{
		Source,
		Destination
	}
	[StructLayout(LayoutKind.Sequential)]
	public class WaveFilter
	{
		public int StructureSize = Marshal.SizeOf(typeof(WaveFilter));

		public int FilterTag;

		public int Filter;

		[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
		public int[] Reserved;
	}
}

Mods/RealRadio/NAudio.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using NAudio.Wave.SampleProviders;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("Mark Heath & Contributors")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("© Mark Heath 2023")]
[assembly: AssemblyDescription("NAudio, an audio library for .NET")]
[assembly: AssemblyFileVersion("2.2.1.0")]
[assembly: AssemblyInformationalVersion("2.2.1")]
[assembly: AssemblyProduct("NAudio")]
[assembly: AssemblyTitle("NAudio")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/naudio/NAudio")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.2.1.0")]
[module: UnverifiableCode]
namespace NAudio.Wave;

public class AudioFileReader : WaveStream, ISampleProvider
{
	private WaveStream readerStream;

	private readonly SampleChannel sampleChannel;

	private readonly int destBytesPerSample;

	private readonly int sourceBytesPerSample;

	private readonly long length;

	private readonly object lockObject;

	public string FileName { get; }

	public override WaveFormat WaveFormat => sampleChannel.WaveFormat;

	public override long Length => length;

	public override long Position
	{
		get
		{
			return SourceToDest(((Stream)(object)readerStream).Position);
		}
		set
		{
			lock (lockObject)
			{
				((Stream)(object)readerStream).Position = DestToSource(value);
			}
		}
	}

	public float Volume
	{
		get
		{
			return sampleChannel.Volume;
		}
		set
		{
			sampleChannel.Volume = value;
		}
	}

	public AudioFileReader(string fileName)
	{
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Expected O, but got Unknown
		lockObject = new object();
		FileName = fileName;
		CreateReaderStream(fileName);
		sourceBytesPerSample = readerStream.WaveFormat.BitsPerSample / 8 * readerStream.WaveFormat.Channels;
		sampleChannel = new SampleChannel((IWaveProvider)(object)readerStream, false);
		destBytesPerSample = 4 * sampleChannel.WaveFormat.Channels;
		length = SourceToDest(((Stream)(object)readerStream).Length);
	}

	private void CreateReaderStream(string fileName)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Expected O, but got Unknown
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Invalid comparison between Unknown and I4
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Invalid comparison between Unknown and I4
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Expected O, but got Unknown
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Expected O, but got Unknown
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Expected O, but got Unknown
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Expected O, but got Unknown
		if (fileName.EndsWith(".wav", StringComparison.OrdinalIgnoreCase))
		{
			readerStream = (WaveStream)new WaveFileReader(fileName);
			if ((int)readerStream.WaveFormat.Encoding != 1 && (int)readerStream.WaveFormat.Encoding != 3)
			{
				readerStream = WaveFormatConversionStream.CreatePcmStream(readerStream);
				readerStream = (WaveStream)new BlockAlignReductionStream(readerStream);
			}
		}
		else if (fileName.EndsWith(".mp3", StringComparison.OrdinalIgnoreCase))
		{
			if (Environment.OSVersion.Version.Major < 6)
			{
				readerStream = (WaveStream)(object)new Mp3FileReader(fileName);
			}
			else
			{
				readerStream = (WaveStream)new MediaFoundationReader(fileName);
			}
		}
		else if (fileName.EndsWith(".aiff", StringComparison.OrdinalIgnoreCase) || fileName.EndsWith(".aif", StringComparison.OrdinalIgnoreCase))
		{
			readerStream = (WaveStream)new AiffFileReader(fileName);
		}
		else
		{
			readerStream = (WaveStream)new MediaFoundationReader(fileName);
		}
	}

	public override int Read(byte[] buffer, int offset, int count)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		WaveBuffer val = new WaveBuffer(buffer);
		int count2 = count / 4;
		return Read(val.FloatBuffer, offset / 4, count2) * 4;
	}

	public int Read(float[] buffer, int offset, int count)
	{
		lock (lockObject)
		{
			return sampleChannel.Read(buffer, offset, count);
		}
	}

	private long SourceToDest(long sourceBytes)
	{
		return destBytesPerSample * (sourceBytes / sourceBytesPerSample);
	}

	private long DestToSource(long destBytes)
	{
		return sourceBytesPerSample * (destBytes / destBytesPerSample);
	}

	protected override void Dispose(bool disposing)
	{
		if (disposing && readerStream != null)
		{
			((Stream)(object)readerStream).Dispose();
			readerStream = null;
		}
		((Stream)this).Dispose(disposing);
	}
}
public class Mp3FileReader : Mp3FileReaderBase
{
	public Mp3FileReader(string mp3FileName)
		: base((Stream)File.OpenRead(mp3FileName), new FrameDecompressorBuilder(CreateAcmFrameDecompressor), true)
	{
	}//IL_000e: Unknown result type (might be due to invalid IL or missing references)
	//IL_0019: Expected O, but got Unknown


	public Mp3FileReader(Stream inputStream)
		: base(inputStream, new FrameDecompressorBuilder(CreateAcmFrameDecompressor), false)
	{
	}//IL_0009: Unknown result type (might be due to invalid IL or missing references)
	//IL_0014: Expected O, but got Unknown


	public static IMp3FrameDecompressor CreateAcmFrameDecompressor(WaveFormat mp3Format)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		return (IMp3FrameDecompressor)new AcmMp3FrameDecompressor(mp3Format);
	}
}

Mods/RealRadio/RealRadio.Plugin.ML.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using RealRadio.Plugin.ML;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(MLMod), "Real Radio", "1.0.1", "Skipcast", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: HarmonyDontPatchAll]
[assembly: MelonPlatformDomain(/*Could not decode attribute arguments.*/)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("RealRadio.Plugin.ML")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+1cd90b6bdac1f314159cb7e67c99a8412d514dd2")]
[assembly: AssemblyProduct("RealRadio.Plugin.ML")]
[assembly: AssemblyTitle("RealRadio.Plugin.ML")]
[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 RealRadio.Plugin.ML
{
	public class MLMod : MelonMod
	{
		private class MLConfig : IConfig
		{
			internal readonly MelonPreferences_Category Category;

			public IConfigData Data { get; internal set; }

			public event Action<string, IConfigData>? ValueChanged;

			public MLConfig(MelonPreferences_Category category)
			{
				Category = category;
				Data = (IConfigData)(object)new MLConfigData(this);
			}

			internal void OnValueChanged(string propertyName)
			{
				this.ValueChanged?.Invoke(propertyName, Data);
			}
		}

		private class MLConfigData : IConfigData
		{
			private readonly MelonPreferences_Entry<float> maxAudioHostInactivityTimeEntry;

			private readonly MelonPreferences_Entry<uint> maxInaudibleAudioClientsEntry;

			public float MaxAudioHostInactivityTime
			{
				get
				{
					return maxAudioHostInactivityTimeEntry.Value;
				}
				set
				{
					maxAudioHostInactivityTimeEntry.Value = value;
				}
			}

			public uint MaxInactiveAudioHosts
			{
				get
				{
					return maxInaudibleAudioClientsEntry.Value;
				}
				set
				{
					maxInaudibleAudioClientsEntry.Value = value;
				}
			}

			public MLConfigData(MLConfig config)
			{
				MLConfig config2 = config;
				base..ctor();
				maxAudioHostInactivityTimeEntry = config2.Category.CreateEntry<float>("MaxAudioHostInactivityTime", 30f, "Max audio host inactivity time", "The maximum amount of time (in seconds) that an audio host can be inactive (no audible sound sources) before being stopped.", false, false, (ValueValidator)(object)new ValueRange<float>(0f, 4.2949673E+09f), (string)null);
				maxInaudibleAudioClientsEntry = config2.Category.CreateEntry<uint>("MaxInactiveAudioHosts", 5u, "Max inaudible audio hosts", "The maximum number of audio hosts that can be inactive (not audible) before stopping the least recently played host.", false, false, (ValueValidator)(object)new ValueRange<uint>(0u, uint.MaxValue), (string)null);
				((MelonEventBase<LemonAction<float, float>>)(object)maxAudioHostInactivityTimeEntry.OnEntryValueChanged).Subscribe((LemonAction<float, float>)delegate
				{
					config2.OnValueChanged("MaxAudioHostInactivityTime");
				}, 0, false);
				((MelonEventBase<LemonAction<uint, uint>>)(object)maxInaudibleAudioClientsEntry.OnEntryValueChanged).Subscribe((LemonAction<uint, uint>)delegate
				{
					config2.OnValueChanged("MaxInactiveAudioHosts");
				}, 0, false);
			}
		}

		private RealRadioPlugin? plugin;

		public override void OnInitializeMelon()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			Logger.OnLog += OnLog;
			InitConfig();
			plugin = new RealRadioPlugin();
		}

		private static void OnLog(object data, LogLevel level)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected I4, but got Unknown
			Instance logger = Melon<MLMod>.Logger;
			switch ((int)level)
			{
			case 0:
				if (LoaderConfig.Current.Loader.DebugMode)
				{
					logger.Msg(ConsoleColor.Cyan, data);
				}
				break;
			case 1:
				logger.Msg(ConsoleColor.White, data);
				break;
			case 2:
				logger.Warning(data);
				break;
			case 3:
				logger.Error(data);
				break;
			}
		}

		private void InitConfig()
		{
			MelonPreferences_Category obj = MelonPreferences.CreateCategory("RealRadio", "Real Radio");
			obj.SetFilePath(Path.Combine(MelonEnvironment.UserDataDirectory, "RealRadio.cfg"), false);
			Config.Instance = (IConfig)(object)new MLConfig(obj);
			obj.LoadFromFile(true);
		}
	}
}

Mods/RealRadio/RealRadio.Plugin.dll

Decompiled a day ago
using System;
using System.Collections;
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.Security;
using System.Security.Permissions;
using FishNet;
using FishNet.Connection;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using RealRadio.Assets;
using RealRadio.Components.UI.Phone;
using RealRadio.Patches;
using RealRadio.Persistence;
using ScheduleOne;
using ScheduleOne.Audio;
using ScheduleOne.DevUtilities;
using ScheduleOne.NPCs.CharacterClasses;
using ScheduleOne.Persistence;
using ScheduleOne.PlayerScripts;
using ScheduleOne.UI.Phone;
using ScheduleOne.UI.Shop;
using ScheduleOne.Vehicles;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("RealRadio.Plugin")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+1cd90b6bdac1f314159cb7e67c99a8412d514dd2")]
[assembly: AssemblyProduct("RealRadio.Plugin")]
[assembly: AssemblyTitle("RealRadio.Plugin")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
[HarmonyPatch(typeof(LoadManager))]
internal static class LoadManagerPatches
{
	public static Action<LoadManager>? InitializeObjectLoaders;

	public static Action<LoadManager>? InitializeItemLoaders;

	[HarmonyPatch("InitializeObjectLoaders")]
	[HarmonyPostfix]
	private static void InitializeObjectLoadersPostfix(LoadManager __instance)
	{
		InitializeObjectLoaders?.Invoke(__instance);
	}

	[HarmonyPatch("InitializeItemLoaders")]
	[HarmonyPostfix]
	private static void InitializeItemLoadersPostfix(LoadManager __instance)
	{
		InitializeItemLoaders?.Invoke(__instance);
	}
}
[HarmonyPatch(typeof(MusicTrack))]
internal static class MusicTrackPatches
{
	public static Action<MusicTrack, bool>? MusicTrackToggled { get; set; }

	public static Action<MusicTrack>? MusicTrackPlay { get; set; }

	[HarmonyPatch("Enable")]
	[HarmonyPostfix]
	public static void MusicTrackEnabledPostFix(MusicTrack __instance)
	{
		MusicTrackToggled?.Invoke(__instance, arg2: true);
	}

	[HarmonyPatch("Disable")]
	[HarmonyPostfix]
	public static void MusicTrackDisabledPostFix(MusicTrack __instance)
	{
		MusicTrackToggled?.Invoke(__instance, arg2: false);
	}

	[HarmonyPatch("Play")]
	[HarmonyPostfix]
	public static void MusicTrackPlayPostFix(MusicTrack __instance)
	{
		MusicTrackPlay?.Invoke(__instance);
	}
}
namespace RealRadio.Plugin
{
	public class RealRadioPlugin
	{
		private class InitNetworkSingletons : MonoBehaviour
		{
			[CompilerGenerated]
			private sealed class <WaitForNetwork>d__1 : IEnumerator<object>, IEnumerator, IDisposable
			{
				private int <>1__state;

				private object <>2__current;

				public InitNetworkSingletons <>4__this;

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

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

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

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

				private bool MoveNext()
				{
					//IL_003e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0048: Expected O, but got Unknown
					int num = <>1__state;
					InitNetworkSingletons initNetworkSingletons = <>4__this;
					switch (num)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>2__current = (object)new WaitUntil((Func<bool>)(() => InstanceFinder.IsServer || InstanceFinder.IsClient));
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -1;
						if (InstanceFinder.IsServer)
						{
							initNetworkSingletons.CreateMainSceneServerSingletons();
						}
						initNetworkSingletons.CreateMainSceneClientSingletons();
						Object.Destroy((Object)(object)((Component)initNetworkSingletons).gameObject);
						return false;
					}
				}

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

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

			private void Awake()
			{
				((MonoBehaviour)this).StartCoroutine(WaitForNetwork());
			}

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

			private void CreateMainSceneServerSingletons()
			{
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: 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_008e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0094: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00de: 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)
				if ((Object)(object)assets == (Object)null)
				{
					throw new InvalidOperationException("Assets have not been set");
				}
				Logger.LogDebug((object)"Creating main scene server singletons");
				InstanceFinder.ServerManager.Spawn(Object.Instantiate<GameObject>(assets.Singletons.OffGridBuildManager), (NetworkConnection)null, default(Scene));
				InstanceFinder.ServerManager.Spawn(Object.Instantiate<GameObject>(assets.Singletons.RadioSyncManager), (NetworkConnection)null, default(Scene));
				InstanceFinder.ServerManager.Spawn(Object.Instantiate<GameObject>(assets.Singletons.VehicleRadioManager), (NetworkConnection)null, default(Scene));
				InstanceFinder.ServerManager.Spawn(Object.Instantiate<GameObject>(assets.Singletons.BuildingRadioManager), (NetworkConnection)null, default(Scene));
				InstanceFinder.ServerManager.Spawn(Object.Instantiate<GameObject>(assets.Singletons.UserStationsManager), (NetworkConnection)null, default(Scene));
			}

			private void CreateMainSceneClientSingletons()
			{
				if ((Object)(object)assets == (Object)null)
				{
					throw new InvalidOperationException("Assets have not been set");
				}
				Logger.LogDebug((object)"Creating main scene client singletons");
				Object.Instantiate<GameObject>(assets.Singletons.RadialMenu);
				Object.Instantiate<GameObject>(assets.Singletons.Modal);
				Object.Instantiate<GameObject>(assets.Singletons.GameMusicManager);
				Object.Instantiate<GameObject>(assets.Singletons.SpeakerConnectionManager);
			}
		}

		private static AssetBundle assetBundle;

		private bool visitedMenu;

		private Harmony? harmony;

		private static AssetRegistry? assets => AssetRegistry.Instance;

		public RealRadioPlugin()
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			assetBundle = LoadAssetBundle();
			Logger.LogDebug((object)("Loaded asset bundle: " + ((Object)assetBundle).name));
			string[] allAssetNames = assetBundle.GetAllAssetNames();
			foreach (string text in allAssetNames)
			{
				Logger.LogDebug((object)("- Found asset: " + text));
			}
			harmony = new Harmony("com.skipcast.realradio");
			harmony.PatchAll();
			LoadManagerPatches.InitializeObjectLoaders = (Action<LoadManager>)Delegate.Combine(LoadManagerPatches.InitializeObjectLoaders, new Action<LoadManager>(Persistence.AddObjectInitializers));
			LoadManagerPatches.InitializeItemLoaders = (Action<LoadManager>)Delegate.Combine(LoadManagerPatches.InitializeItemLoaders, new Action<LoadManager>(Persistence.AddItemInitializers));
			AppsCanvasPatches.CanvasCreated = (Action<AppsCanvas>)Delegate.Combine(AppsCanvasPatches.CanvasCreated, new Action<AppsCanvas>(OnAppsCanvasCreated));
			DanAwakePatch.OnDanAwake += OnDanAwake;
			LandVehicleStartPatch.OnVehicleSpawned = (Action<LandVehicle>)Delegate.Combine(LandVehicleStartPatch.OnVehicleSpawned, (Action<LandVehicle>)delegate(LandVehicle vehicle)
			{
				GameEvents.VehicleSpawned?.Invoke(vehicle);
			});
			MusicTrackPatches.MusicTrackPlay = (Action<MusicTrack>)Delegate.Combine(MusicTrackPatches.MusicTrackPlay, (Action<MusicTrack>)delegate(MusicTrack track)
			{
				GameEvents.MusicTrackPlay?.Invoke(track);
			});
			MusicTrackPatches.MusicTrackToggled = (Action<MusicTrack, bool>)Delegate.Combine(MusicTrackPatches.MusicTrackToggled, (Action<MusicTrack, bool>)delegate(MusicTrack track, bool enabled)
			{
				GameEvents.MusicTrackToggled?.Invoke(track, enabled);
			});
			RegistryAwakePatch.RegistryAwake += OnRegistryAwake;
			if ((Object)(object)Singleton<Registry>.Instance != (Object)null)
			{
				OnRegistryAwake(Singleton<Registry>.Instance);
			}
			InitFishNet();
			Logger.LogInfo((object)"Plugin RealRadio is loaded!");
			SceneManager.activeSceneChanged += delegate(Scene oldScene, Scene newScene)
			{
				if (((Scene)(ref newScene)).name == "Menu")
				{
					OnEnterMainMenu();
				}
				if (((Scene)(ref newScene)).name == "Main")
				{
					OnMainSceneLoadComplete();
				}
			};
		}

		private void OnRegistryAwake(Registry registry)
		{
			if ((Object)(object)AssetRegistry.Instance == (Object)null)
			{
				AssetRegistry.Instance = AssetRegistry.LoadFromAssetBundle(assetBundle);
			}
			AssetRegistry.Register(registry, InstanceFinder.NetworkManager, assetBundle);
		}

		private void InitFishNet()
		{
			foreach (Type item in from t in typeof(Logger).Assembly.GetExportedTypes()
				where t.Namespace == "FishNet.Serializing.Generated"
				select t)
			{
				item.GetMethod("InitializeOnce", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, Array.Empty<object>());
			}
		}

		private void OnAppsCanvasCreated(AppsCanvas canvas)
		{
			Player componentInParent = ((Component)canvas).GetComponentInParent<Player>();
			if ((Object)(object)componentInParent == (Object)null || !componentInParent.IsLocalPlayer)
			{
				Logger.LogWarning((object)"Detected AppsCanvas creation from non-local player, ignoring...");
			}
			else
			{
				PhoneBootstrap.CreateApp(canvas);
			}
		}

		private void OnDanAwake(Dan dan)
		{
			if ((Object)(object)assets == (Object)null)
			{
				throw new InvalidOperationException("Assets have not been set");
			}
			ShopListing[] listings = assets.ShopListings.Listings;
			foreach (ShopListing val in listings)
			{
				dan.ShopInterface.CreateListingUI(val);
			}
		}

		private AssetBundle LoadAssetBundle()
		{
			string assetBundlePath = GetAssetBundlePath();
			try
			{
				AssetBundle obj = AssetBundle.LoadFromFile(assetBundlePath);
				if ((Object)(object)obj == (Object)null)
				{
					if (!File.Exists(assetBundlePath))
					{
						throw new FileNotFoundException("Asset bundle file not found", assetBundlePath);
					}
					throw new Exception("Failed to load asset bundle");
				}
				return obj;
			}
			catch (Exception)
			{
				Logger.LogError((object)"Failed to load asset bundle!");
				throw;
			}
		}

		internal static string GetAssetBundlePath()
		{
			return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Assets", "assets");
		}

		private void OnEnterMainMenu()
		{
			if (!visitedMenu)
			{
				visitedMenu = false;
				Logger.LogDebug((object)"Menu scene loaded for the first time");
				visitedMenu = true;
				CreatePersistentSingletons();
			}
		}

		private void OnMainSceneLoadComplete()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			new GameObject("InitNetworkSingletons", new Type[1] { typeof(InitNetworkSingletons) });
		}

		private void CreatePersistentSingletons()
		{
			if ((Object)(object)assets == (Object)null)
			{
				throw new InvalidOperationException("Assets have not been set");
			}
			Logger.LogDebug((object)"Creating persistent singletons");
			Object.Instantiate<GameObject>(assets.Singletons.RadioStationManager);
			Object.Instantiate<GameObject>(assets.Singletons.RadioStationInfoManager);
			Object.Instantiate<GameObject>(assets.Singletons.YtDlpManager);
			Object.Instantiate<GameObject>(assets.Singletons.YtDlpUiManager);
			Object.Instantiate<GameObject>(assets.Singletons.APIManager);
		}
	}
}
namespace RealRadio.Patches
{
	[HarmonyPatch(typeof(Dan), "Awake")]
	public static class DanAwakePatch
	{
		public static event Action<Dan>? OnDanAwake;

		private static void Prefix(Dan __instance)
		{
			DanAwakePatch.OnDanAwake?.Invoke(__instance);
		}
	}
	[HarmonyPatch(typeof(LandVehicle), "Start")]
	public class LandVehicleStartPatch
	{
		public static Action<LandVehicle>? OnVehicleSpawned;

		public static void Postfix(LandVehicle __instance)
		{
			OnVehicleSpawned?.Invoke(__instance);
		}
	}
	[HarmonyPatch(typeof(AppsCanvas))]
	internal static class AppsCanvasPatches
	{
		public static Action<AppsCanvas>? CanvasCreated;

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void AppsCanvasStartPostFix(AppsCanvas __instance)
		{
			CanvasCreated?.Invoke(__instance);
		}
	}
	[HarmonyPatch(typeof(Registry), "Awake")]
	public static class RegistryAwakePatch
	{
		public static event Action<Registry>? RegistryAwake;

		public static void Prefix(Registry __instance)
		{
			RegistryAwakePatch.RegistryAwake?.Invoke(__instance);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}

Mods/RealRadio/RealRadio.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using AudioStreamer;
using AudioStreamer.MediaFoundation;
using FishNet;
using FishNet.Connection;
using FishNet.Managing;
using FishNet.Managing.Object;
using FishNet.Object;
using FishNet.Object.Delegating;
using FishNet.Object.Synchronizing;
using FishNet.Object.Synchronizing.Internal;
using FishNet.Serializing;
using FishNet.Serializing.Generated;
using FishNet.Transporting;
using HashUtility;
using Microsoft.CodeAnalysis;
using NAudio.Wave;
using Newtonsoft.Json;
using RealRadio;
using RealRadio.Assets;
using RealRadio.Components.API.Data;
using RealRadio.Components.Audio;
using RealRadio.Components.Audio.HostControllers;
using RealRadio.Components.Building;
using RealRadio.Components.Building.Buildables;
using RealRadio.Components.Buildings;
using RealRadio.Components.NPCs;
using RealRadio.Components.Radio;
using RealRadio.Components.UI;
using RealRadio.Components.UI.Phone.UIElements;
using RealRadio.Components.Vehicles;
using RealRadio.Components.WorldUI;
using RealRadio.Components.YoutubeDL;
using RealRadio.Data;
using RealRadio.Events;
using RealRadio.Helpers;
using RealRadio.Peristence.Data;
using RealRadio.Persistence.Data;
using RealRadio.Persistence.Loaders;
using ScheduleOne;
using ScheduleOne.Audio;
using ScheduleOne.AvatarFramework;
using ScheduleOne.AvatarFramework.Customization;
using ScheduleOne.Building;
using ScheduleOne.Cartel;
using ScheduleOne.Casino;
using ScheduleOne.Clothing;
using ScheduleOne.Combat;
using ScheduleOne.Delivery;
using ScheduleOne.DevUtilities;
using ScheduleOne.Doors;
using ScheduleOne.Economy;
using ScheduleOne.Employees;
using ScheduleOne.EntityFramework;
using ScheduleOne.GameTime;
using ScheduleOne.Graffiti;
using ScheduleOne.Interaction;
using ScheduleOne.ItemFramework;
using ScheduleOne.Law;
using ScheduleOne.Levelling;
using ScheduleOne.Management;
using ScheduleOne.Map;
using ScheduleOne.Messaging;
using ScheduleOne.NPCs;
using ScheduleOne.NPCs.Behaviour;
using ScheduleOne.NPCs.Schedules;
using ScheduleOne.ObjectScripts;
using ScheduleOne.ObjectScripts.WateringCan;
using ScheduleOne.Persistence;
using ScheduleOne.Persistence.Datas;
using ScheduleOne.Persistence.Loaders;
using ScheduleOne.PlayerScripts;
using ScheduleOne.Product;
using ScheduleOne.Property;
using ScheduleOne.Quests;
using ScheduleOne.Storage;
using ScheduleOne.Tiles;
using ScheduleOne.UI;
using ScheduleOne.UI.Compass;
using ScheduleOne.UI.Handover;
using ScheduleOne.UI.Phone;
using ScheduleOne.UI.Phone.Messages;
using ScheduleOne.UI.Shop;
using ScheduleOne.Vehicles;
using ScheduleOne.Vehicles.Modification;
using ScheduleOne.Vision;
using ScheduleOne.VoiceOver;
using SongInfoFetcher;
using SongInfoFetcher.GlobalPlayer;
using SongInfoFetcher.OneFM;
using SongInfoFetcher.SimulatorRadio;
using SongInfoFetcher.TruckersFM;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityEngine.UIElements;
using YoutubeDLSharp;
using YoutubeDLSharp.Metadata;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("RealRadio.Plugin")]
[assembly: InternalsVisibleTo("RealRadio.Plugin.ML")]
[assembly: InternalsVisibleTo("RealRadio.Plugin.BepInEx")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("RealRadio")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+1cd90b6bdac1f314159cb7e67c99a8412d514dd2")]
[assembly: AssemblyProduct("Real Radio")]
[assembly: AssemblyTitle("RealRadio")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public class BuildStartOffGrid : BuildStart_Base
{
	public LayerMask DetectionMask = (Layers.Default | Layers.Tile | Layers.Terrain).ToLayerMask();

	public Vector2 MinMaxNormalX = new Vector2(-1f, 1f);

	public Vector2 MinMaxNormalY = new Vector2(-1f, 1f);

	public Vector2 MinMaxNormalZ = new Vector2(-1f, 1f);

	public float RotationIncrement = 22.5f;

	public bool RestrictToProperties = true;

	public GameObject? GhostObject { get; private set; }

	public BuildableItem? BuildableItem { get; private set; }

	public ItemInstance? ItemInstance { get; private set; }

	public BuildableItemDefinition? ItemDefinition
	{
		get
		{
			if (ItemInstance == null)
			{
				return null;
			}
			ItemDefinition definition = ItemInstance.Definition;
			return (BuildableItemDefinition?)(object)(((definition is BuildableItemDefinition) ? definition : null) ?? throw new InvalidOperationException("ItemInstance.Definition is not BuildableItemDefinition"));
		}
	}

	public override void StartBuilding(ItemInstance item)
	{
		ItemDefinition definition = item.Definition;
		BuildableItemDefinition val = (BuildableItemDefinition)(object)((definition is BuildableItemDefinition) ? definition : null);
		if (val == null)
		{
			Logger.LogError($"item.Definition is not BuildableItemDefinition: {item.Definition}");
			return;
		}
		if ((Object)(object)GhostObject != (Object)null)
		{
			throw new InvalidOperationException("StartBuilding was called while a ghost object already exists");
		}
		Singleton<HUD>.Instance.SetCrosshairVisible(false);
		Singleton<InputPromptsCanvas>.Instance.LoadModule("building");
		ItemInstance = item;
		GhostObject = CreateGhostModel(val);
		BuildableItem = GhostObject.GetComponent<BuildableItem>() ?? throw new InvalidOperationException("BuildableItem component not found on BuiltItem prefab");
	}

	public void DestroyGhostObject()
	{
		if (!((Object)(object)GhostObject == (Object)null))
		{
			Object.Destroy((Object)(object)GhostObject);
			GhostObject = null;
			BuildableItem = null;
			ItemInstance = null;
		}
	}

	private GameObject CreateGhostModel(BuildableItemDefinition itemDef)
	{
		itemDef.BuiltItem.isGhost = true;
		((Component)itemDef.BuiltItem).gameObject.SetActive(false);
		GameObject val = Object.Instantiate<GameObject>(((Component)itemDef.BuiltItem).gameObject, ((Component)this).transform);
		itemDef.BuiltItem.isGhost = false;
		((Component)itemDef.BuiltItem).gameObject.SetActive(true);
		BuildManager instance = Singleton<BuildManager>.Instance;
		instance.DisableColliders(val);
		instance.DisableNavigation(val);
		instance.DisableNetworking(val);
		instance.DisableCanvases(val);
		ActivateDuringBuild[] componentsInChildren = ((Component)this).gameObject.GetComponentsInChildren<ActivateDuringBuild>();
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			((Component)componentsInChildren[i]).gameObject.SetActive(true);
		}
		DestroyWhenGhost[] componentsInChildren2 = ((Component)this).gameObject.GetComponentsInChildren<DestroyWhenGhost>();
		for (int i = 0; i < componentsInChildren2.Length; i++)
		{
			Object.Destroy((Object)(object)((Component)componentsInChildren2[i]).gameObject);
		}
		val.SetActive(true);
		return val;
	}
}
public class BuildUpdateOffGrid : BuildUpdate_Base
{
	private BuildStartOffGrid buildStart;

	private Vector3 lastPosition;

	private Quaternion lastRotation;

	private Vector3 lastValidPosition;

	private Quaternion lastValidRotation;

	private float desiredRotation;

	private bool positionIsValid;

	private float sqrDistanceDiff;

	private Collider[] intersections = (Collider[])(object)new Collider[8];

	private Material? currentGhostMaterial;

	private const float MaxSnapDistanceSqr = 0.010000001f;

	private GameObject GhostObject => buildStart?.GhostObject ?? throw new InvalidOperationException("buildStart or buildStart.GhostObject is null");

	public override void Stop()
	{
		buildStart.DestroyGhostObject();
	}

	private void Awake()
	{
		buildStart = ((Component)this).GetComponent<BuildStartOffGrid>() ?? throw new InvalidOperationException("No BuildStartOffGrid component found on game object");
	}

	private void Update()
	{
		//IL_0022: 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_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: 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)
		if (!((Object)(object)buildStart.GhostObject == (Object)null))
		{
			UpdateDesiredRotationFromInput();
			UpdatePositions();
			Vector3 val = lastPosition - lastValidPosition;
			sqrDistanceDiff = ((Vector3)(ref val)).sqrMagnitude;
			if (sqrDistanceDiff > 0.010000001f)
			{
				lastValidPosition = Vector3.zero;
			}
			UpdateGhostTransform();
			UpdateGhostMaterial();
			SpawnItemIfValid();
		}
	}

	private void UpdateDesiredRotationFromInput()
	{
		if (GameInput.GetButtonDown((ButtonCode)17))
		{
			desiredRotation -= buildStart.RotationIncrement;
		}
		if (GameInput.GetButtonDown((ButtonCode)18))
		{
			desiredRotation += buildStart.RotationIncrement;
		}
	}

	private void UpdatePositions()
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: 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_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//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_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: 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_0073: 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_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_017e: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)buildStart.BuildableItem == (Object)null)
		{
			throw new InvalidOperationException("buildStart.BuildableItem is null");
		}
		float holdDistance = buildStart.BuildableItem.HoldDistance;
		PlayerCamera instance = PlayerSingleton<PlayerCamera>.Instance;
		RaycastHit val = default(RaycastHit);
		if (!instance.LookRaycast(holdDistance, ref val, buildStart.DetectionMask, false, 0f))
		{
			lastPosition = ((Component)instance).transform.position + ((Component)instance).transform.forward * holdDistance;
			lastPosition -= buildStart.BuildableItem.MidAirCenterPoint.localPosition;
			lastRotation = ((Component)instance).transform.rotation * Quaternion.Euler(0f, 180f, 0f);
			positionIsValid = false;
			return;
		}
		lastRotation = Quaternion.FromToRotation(Vector3.up, ((RaycastHit)(ref val)).normal) * Quaternion.Euler(0f, desiredRotation, 0f);
		Transform transform = ((Component)buildStart.BuildableItem.BuildPoint).transform;
		Vector3 val2 = lastRotation * transform.localPosition;
		lastPosition = ((RaycastHit)(ref val)).point - val2;
		if (TestForObstructions())
		{
			positionIsValid = false;
			return;
		}
		if (!TestForValidAngle(((RaycastHit)(ref val)).normal))
		{
			positionIsValid = false;
			return;
		}
		if (!TestForValidSurface(((RaycastHit)(ref val)).collider))
		{
			positionIsValid = false;
			return;
		}
		if (!TestForValidLocation(lastPosition))
		{
			positionIsValid = false;
			return;
		}
		positionIsValid = true;
		lastValidPosition = lastPosition;
		lastValidRotation = lastRotation;
	}

	private bool TestForObstructions()
	{
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: 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)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: 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_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: 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_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)buildStart.BuildableItem == (Object)null)
		{
			throw new InvalidOperationException("buildStart.BuildableItem is null");
		}
		BoxCollider boundingCollider = buildStart.BuildableItem.BoundingCollider;
		((Collider)boundingCollider).enabled = true;
		Vector3 position = GhostObject.transform.position;
		Quaternion rotation = GhostObject.transform.rotation;
		GhostObject.transform.position = lastPosition;
		GhostObject.transform.rotation = lastRotation;
		try
		{
			bool result = false;
			Vector3 val = lastPosition;
			Bounds bounds = ((Collider)boundingCollider).bounds;
			Vector3 extents = ((Bounds)(ref bounds)).extents;
			float magnitude = ((Vector3)(ref extents)).magnitude;
			int num = LayerMask.op_Implicit(buildStart.DetectionMask);
			int num2 = Physics.OverlapSphereNonAlloc(val, magnitude, intersections, num);
			float num3 = default(float);
			for (int i = 0; i < num2; i++)
			{
				Collider val2 = intersections[i];
				if (!((Object)(object)val2 == (Object)(object)boundingCollider) && !val2.isTrigger && Physics.ComputePenetration((Collider)(object)boundingCollider, ((Component)boundingCollider).transform.position, ((Component)boundingCollider).transform.rotation, val2, ((Component)val2).transform.position, ((Component)val2).transform.rotation, ref extents, ref num3) && num3 > 0.001f)
				{
					result = true;
					break;
				}
			}
			return result;
		}
		finally
		{
			GhostObject.transform.position = position;
			GhostObject.transform.rotation = rotation;
			((Collider)boundingCollider).enabled = false;
		}
	}

	private bool TestForValidAngle(Vector3 surfaceNormal)
	{
		//IL_0000: 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_003e: 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_009a: Unknown result type (might be due to invalid IL or missing references)
		if (surfaceNormal.x < buildStart.MinMaxNormalX.x - 1E-05f || surfaceNormal.x > buildStart.MinMaxNormalX.y + 1E-05f)
		{
			return false;
		}
		if (surfaceNormal.y < buildStart.MinMaxNormalY.x - 1E-05f || surfaceNormal.y > buildStart.MinMaxNormalY.y + 1E-05f)
		{
			return false;
		}
		if (surfaceNormal.z < buildStart.MinMaxNormalZ.x - 1E-05f || surfaceNormal.z > buildStart.MinMaxNormalZ.y + 1E-05f)
		{
			return false;
		}
		return true;
	}

	private bool TestForValidSurface(Collider surface)
	{
		if ((Object)(object)(((Component)surface).GetComponent<InteractableObject>() ?? ((Component)surface).GetComponentInParent<InteractableObject>()) != (Object)null)
		{
			return false;
		}
		return true;
	}

	private bool TestForValidLocation(Vector3 position)
	{
		//IL_0007: 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)
		if (buildStart.RestrictToProperties)
		{
			return (Object)(object)((IEnumerable<Property>)Property.OwnedProperties).FirstOrDefault((Func<Property, bool>)((Property property) => property.DistanceFromPropertyBoundsSquared(position, 0.0025000000000000005) <= 0.0025000000000000005)) != (Object)null;
		}
		return true;
	}

	private void UpdateGhostTransform()
	{
		//IL_0032: 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_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//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_0029: 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_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)buildStart.GhostObject == (Object)null))
		{
			Vector3 position;
			Quaternion rotation;
			if (sqrDistanceDiff > 0.010000001f)
			{
				position = lastPosition;
				rotation = lastRotation;
			}
			else
			{
				position = lastValidPosition;
				rotation = lastValidRotation;
			}
			buildStart.GhostObject.transform.position = position;
			buildStart.GhostObject.transform.rotation = rotation;
		}
	}

	private void UpdateGhostMaterial()
	{
		if (!((Object)(object)buildStart.GhostObject == (Object)null))
		{
			BuildManager instance = Singleton<BuildManager>.Instance;
			Material val = ((!positionIsValid && !(sqrDistanceDiff <= 0.010000001f)) ? instance.ghostMaterial_Red : instance.ghostMaterial_White);
			if (!((Object)(object)currentGhostMaterial == (Object)(object)val))
			{
				currentGhostMaterial = val;
				instance.ApplyMaterial(GhostObject, val, true);
			}
		}
	}

	private void SpawnItemIfValid()
	{
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: 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_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: 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_008a: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)buildStart.ItemDefinition == (Object)null) && buildStart.ItemInstance != null && (positionIsValid || !(sqrDistanceDiff > 0.010000001f)) && GameInput.GetButtonDown((ButtonCode)0))
		{
			Vector3 val = lastValidPosition;
			Quaternion rotation = lastValidRotation;
			NetworkSingleton<OffGridBuildManager>.Instance.SpawnBuilding(buildStart.ItemInstance.GetCopy(1), val, rotation);
			Singleton<BuildManager>.Instance.PlayBuildSound(buildStart.ItemDefinition.BuildSoundType, val);
			((ItemSlot)PlayerSingleton<PlayerInventory>.Instance.equippedSlot).ChangeQuantity(-1, false);
		}
	}
}
public class BuildStopOffGrid : BuildStop_Base
{
}
[Serializable]
public enum RadioType : byte
{
	InternetRadio,
	YtDlp
}
namespace RealRadio
{
	public static class Config
	{
		private static IConfig? instance;

		public static IConfig Instance
		{
			get
			{
				return instance ?? throw new InvalidOperationException("Config has not been set");
			}
			internal set
			{
				instance = value ?? throw new ArgumentNullException("value");
			}
		}
	}
	public interface IConfigData
	{
		float MaxAudioHostInactivityTime { get; set; }

		uint MaxInactiveAudioHosts { get; set; }
	}
	public interface IConfig
	{
		IConfigData Data { get; }

		event Action<string, IConfigData>? ValueChanged;
	}
	public static class GameEvents
	{
		public static Action<LandVehicle>? VehicleSpawned;

		public static Action<MusicTrack, bool>? MusicTrackToggled;

		public static Action<MusicTrack>? MusicTrackPlay;
	}
	[Flags]
	public enum Layers
	{
		Default = 1,
		TransparentFX = 2,
		IgnoreRaycast = 4,
		Unused1 = 8,
		Water = 0x10,
		UI = 0x20,
		Player = 0x40,
		Tile = 0x80,
		ViewModel = 0x100,
		Temporary = 0x200,
		Trash = 0x400,
		NPC = 0x800,
		WorldGrid = 0x1000,
		Overlay = 0x2000,
		WaterPipe = 0x4000,
		Vehicle = 0x8000,
		Pallet = 0x10000,
		StoredItem = 0x20000,
		Door = 0x40000,
		Invisible = 0x80000,
		IconGeneration = 0x100000,
		VehicleObstacle = 0x200000,
		Grass = 0x400000,
		VehicleBlocker = 0x800000,
		Terrain = 0x1000000,
		LightSource = 0x2000000,
		Task = 0x8000000,
		Glass = 0x10000000,
		Skateboard = 0x20000000,
		PlayerBlocker = 0x40000000,
		LOD = int.MinValue,
		Unused2 = 1,
		All = -67108865
	}
	public static class LayersExtensions
	{
		public static LayerMask ToLayerMask(this Layers layers)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return LayerMask.op_Implicit((int)layers);
		}
	}
	internal static class Logger
	{
		public enum LogLevel
		{
			Debug,
			Info,
			Warning,
			Error
		}

		public static event Action<object, LogLevel>? OnLog;

		public static void LogInfo(object data)
		{
			Logger.OnLog?.Invoke(data, LogLevel.Info);
		}

		public static void LogWarning(object data)
		{
			Logger.OnLog?.Invoke(data, LogLevel.Warning);
		}

		public static void LogError(object data)
		{
			Logger.OnLog?.Invoke(data, LogLevel.Error);
		}

		public static void LogDebug(object data)
		{
			Logger.OnLog?.Invoke(data, LogLevel.Debug);
		}
	}
	public static class UITKHelper
	{
		[return: NotNullIfNotNull("text")]
		public static string? EscapeRichText(this string? text)
		{
			if (text == null)
			{
				return null;
			}
			StringBuilder stringBuilder = new StringBuilder(text);
			while (true)
			{
				int num = text.IndexOf("<noparse>", StringComparison.OrdinalIgnoreCase);
				int num2 = text.IndexOf("</noparse>", StringComparison.OrdinalIgnoreCase);
				if (num == -1 && num2 == -1)
				{
					break;
				}
				if (num != -1)
				{
					stringBuilder.Remove(num, "<noparse>".Length);
					if (num2 > num)
					{
						num2 -= "<noparse>".Length;
					}
				}
				if (num2 != -1)
				{
					stringBuilder.Remove(num2, "</noparse>".Length);
				}
				text = stringBuilder.ToString();
			}
			stringBuilder.Insert(0, "<noparse>");
			stringBuilder.Append("</noparse>");
			return stringBuilder.ToString();
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "RealRadio";

		public const string PLUGIN_NAME = "Real Radio";

		public const string PLUGIN_VERSION = "1.0.1";
	}
}
namespace RealRadio.Peristence.Data
{
	public class UserStationsData : SaveData
	{
		public List<RealRadio.Components.API.Data.RadioStation> Stations;

		public UserStationsData(List<RealRadio.Components.API.Data.RadioStation> stations)
		{
			Stations = stations;
		}

		public override string GetJson(bool prettyPrint = true)
		{
			return JsonConvert.SerializeObject((object)this, (Formatting)(prettyPrint ? 1 : 0));
		}
	}
}
namespace RealRadio.Persistence
{
	internal static class Persistence
	{
		public static void AddObjectInitializers(LoadManager loadManager)
		{
			new OffGridItemLoader<OffGridItem, OffGridItemData>();
			new TogglableOffGridItemLoader<TogglableOffGridItem, TogglableOffGridItemData>();
			new RadioLoader<Radio, RadioData>();
			new SpeakerLoader<Speaker, SpeakerData>();
		}

		public static void AddItemInitializers(LoadManager loadManager)
		{
		}
	}
}
namespace RealRadio.Persistence.Loaders
{
	[Serializable]
	public class SpeakerData : OffGridItemData
	{
		public string? MasterGuid = masterGuid?.ToString();

		public Speaker.AudioChannel Channel;

		public bool StereoOutput;

		public Vector2 MountRotation;

		public SpeakerData(Guid guid, ItemInstance item, int loadOrder, Vector3 position, Vector3 rotation, Guid? masterGuid, Speaker.AudioChannel channel, bool stereoOutput, Vector2 mountRotation)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			Channel = channel;
			StereoOutput = stereoOutput;
			MountRotation = mountRotation;
			base..ctor(guid, item, loadOrder, position, rotation);
		}
	}
	public class OffGridItemLoader<TItem, TLoadData> : BuildableItemLoader where TItem : OffGridItem where TLoadData : OffGridItemData
	{
		public override string ItemType => "RealRadio_" + typeof(TLoadData).Name;

		protected TLoadData? Data { get; private set; }

		protected TItem? Item { get; private set; }

		public override void Load(DynamicSaveData data)
		{
			TryLoadAndCreate(data, out TItem _);
		}

		[MemberNotNullWhen(true, new string[] { "Data", "Item" })]
		protected virtual bool TryLoadAndCreate(DynamicSaveData data, out TItem? item)
		{
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			Item = null;
			item = null;
			Data = null;
			try
			{
				Data = JsonUtility.FromJson<TLoadData>(data.BaseData);
				if (Data == null)
				{
					Logger.LogError(((object)this).GetType().Name + " failed to deserialize data of type '" + ((SaveData)data).DataType + "'");
					return false;
				}
			}
			catch (Exception arg)
			{
				Logger.LogError($"{((object)this).GetType().Name} failed to read data of type '{((SaveData)data).DataType}': {arg}");
				return false;
			}
			ItemInstance val = ItemDeserializer.LoadItem(((BuildableItemData)Data).ItemString);
			ItemDefinition definition = val.Definition;
			BuildableItemDefinition val2 = (BuildableItemDefinition)(object)((definition is BuildableItemDefinition) ? definition : null);
			if (val2 == null)
			{
				Logger.LogError($"{((object)this).GetType()} failed to get buildable item definition from '{((BuildableItemData)Data).ItemString}'");
				return false;
			}
			if (!(val2.BuiltItem is TItem))
			{
				Logger.LogError($"{((object)this).GetType()} failed to get correct item type from '{((BuildableItemData)Data).ItemString}' (expected {typeof(TItem).Name} but got {((object)val2.BuiltItem).GetType().Name})");
				return false;
			}
			if (val == null)
			{
				Logger.LogError($"{((object)this).GetType()} failed to get item instance from '{((BuildableItemData)Data).ItemString}'");
				return false;
			}
			if (!Guid.TryParse(((BuildableItemData)Data).GUID, out var result))
			{
				Logger.LogError($"{((object)this).GetType()} failed to parse guid: '{((BuildableItemData)Data).GUID}'");
				return false;
			}
			Item = (item = NetworkSingleton<OffGridBuildManager>.Instance.SpawnBuilding(val, Data.Position, Quaternion.Euler(Data.Rotation), result) as TItem);
			return (Object)(object)Item != (Object)null;
		}
	}
	public class RadioLoader<TRadio, TRadioData> : TogglableOffGridItemLoader<TRadio, TRadioData> where TRadio : Radio where TRadioData : RadioData
	{
		[CompilerGenerated]
		private sealed class <<Load>g__WaitForUserStationsToLoad|0_0>d : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public RadioLoader<TRadio, TRadioData> <>4__this;

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

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

			[DebuggerHidden]
			public <<Load>g__WaitForUserStationsToLoad|0_0>d(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

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

			private bool MoveNext()
			{
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0048: Expected O, but got Unknown
				int num = <>1__state;
				RadioLoader<TRadio, TRadioData> radioLoader = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitUntil((Func<bool>)(() => NetworkSingleton<UserStationsManager>.Instance.SaveDataLoaded));
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					if (radioLoader.Data.StationIdHash == 0 || !Singleton<RadioStationManager>.Instance.StationsByHashedId.TryGetValue(radioLoader.Data.StationIdHash, out RealRadio.Data.RadioStation _))
					{
						if (radioLoader.Data.StationIdHash != 0)
						{
							Logger.LogWarning($"Could not find radio station with id {radioLoader.Data.StationIdHash}");
						}
					}
					else
					{
						radioLoader.Item.SetRadioStationIdHash(radioLoader.Data.StationIdHash);
					}
					for (byte b = 0; b < Math.Min(radioLoader.Item.MaxFavoriteStations, radioLoader.Data.FavoriteStations.Length); b++)
					{
						uint num2 = radioLoader.Data.FavoriteStations[b];
						if (num2 != 0)
						{
							if (!Singleton<RadioStationManager>.Instance.StationsByHashedId.TryGetValue(num2, out RealRadio.Data.RadioStation value2))
							{
								Logger.LogWarning($"Could not find favorite radio station with id {num2}");
							}
							else
							{
								radioLoader.Item.SetFavoriteStation(b, value2);
							}
						}
					}
					return false;
				}
				}
			}

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

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

		public override void Load(DynamicSaveData data)
		{
			base.Load(data);
			if (!((Object)(object)base.Item == (Object)null) && base.Data != null)
			{
				base.Item.SetVolume(base.Data.Volume);
				((MonoBehaviour)base.Item).StartCoroutine(WaitForUserStationsToLoad());
			}
			[IteratorStateMachine(typeof(RadioLoader<, >.<<Load>g__WaitForUserStationsToLoad|0_0>d))]
			IEnumerator WaitForUserStationsToLoad()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <<Load>g__WaitForUserStationsToLoad|0_0>d(0)
				{
					<>4__this = this
				};
			}
		}
	}
	public class SpeakerLoader<TSpeaker, TSpeakerData> : OffGridItemLoader<TSpeaker, TSpeakerData> where TSpeaker : Speaker where TSpeakerData : SpeakerData
	{
		public override void Load(DynamicSaveData data)
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			base.Load(data);
			if ((Object)(object)base.Item == (Object)null || base.Data == null)
			{
				return;
			}
			base.Item.SelectedAudioChannel = base.Data.Channel;
			base.Item.StereoOutput = base.Data.StereoOutput;
			base.Item.MountRotation = base.Data.MountRotation;
			if (!string.IsNullOrEmpty(base.Data.MasterGuid))
			{
				if (!Guid.TryParse(base.Data.MasterGuid, out var result))
				{
					throw new ArgumentException("Invalid radio guid in save data: " + base.Data.MasterGuid);
				}
				if ((Object)(object)GUIDManager.GetObject<Radio>(result) == (Object)null)
				{
					Logger.LogWarning("Could not find radio while loading speaker. Radio guid: " + base.Data.MasterGuid);
				}
				base.Item.MasterGuid = result;
			}
		}
	}
	public class TogglableOffGridItemLoader<TItem, TLoadData> : OffGridItemLoader<TItem, TLoadData> where TItem : TogglableOffGridItem where TLoadData : TogglableOffGridItemData
	{
		public override void Load(DynamicSaveData data)
		{
			if (TryLoadAndCreate(data, out TItem _))
			{
				base.Item.IsOn = base.Data.IsOn;
			}
		}
	}
	public class UserStationsLoader : Loader
	{
		public override void Load(string mainPath)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				string text = default(string);
				if (!((Loader)this).TryLoadFile(mainPath, ref text, true))
				{
					return;
				}
				UserStationsData userStationsData;
				try
				{
					userStationsData = JsonConvert.DeserializeObject<UserStationsData>(text) ?? throw new JsonSerializationException("Deserialized object is null");
				}
				catch (Exception arg)
				{
					Logger.LogError($"Failed to read user radio stations from '{mainPath}': {arg}");
					return;
				}
				if (userStationsData.Stations == null)
				{
					Logger.LogError("Loaded user radio stations from '" + mainPath + "' are null");
					return;
				}
				List<RealRadio.Components.API.Data.RadioStation> list = new List<RealRadio.Components.API.Data.RadioStation>(userStationsData.Stations.Count);
				foreach (RealRadio.Components.API.Data.RadioStation station in userStationsData.Stations)
				{
					if (!station.IsValid(out List<string> invalidReasons))
					{
						Logger.LogError("Could not validate user radio station '" + station.Id + " (" + station.Name + ")':\n- " + string.Join("\n- ", invalidReasons));
					}
					else
					{
						list.Add(station);
					}
				}
				try
				{
					NetworkSingleton<UserStationsManager>.Instance.AddOrUpdateStations(list);
					if (list.Count != userStationsData.Stations.Count)
					{
						Logger.LogWarning($"Loaded {list.Count} out of {userStationsData.Stations.Count} user radio station(s)");
					}
					else
					{
						Logger.LogDebug($"Successfully loaded {userStationsData.Stations.Count} user radio station(s)");
					}
				}
				catch (Exception arg2)
				{
					Logger.LogError($"Failed to register user radio stations: {arg2}");
				}
			}
			finally
			{
				NetworkSingleton<UserStationsManager>.Instance.OnStationsLoaded?.Invoke();
			}
		}
	}
}
namespace RealRadio.Persistence.Data
{
	[Serializable]
	public class OffGridItemData : BuildableItemData
	{
		public Vector3 Position;

		public Vector3 Rotation;

		public OffGridItemData(Guid guid, ItemInstance item, int loadOrder, Vector3 position, Vector3 rotation)
			: base(guid, item, loadOrder)
		{
			//IL_000a: 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_0012: 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)
			Position = position;
			Rotation = rotation;
			((SaveData)this).DataType = "RealRadio_" + ((object)this).GetType().Name;
		}
	}
	[Serializable]
	public class RadioData : TogglableOffGridItemData
	{
		public uint StationIdHash = stationIdHash.GetValueOrDefault();

		public float Volume;

		public uint[] FavoriteStations;

		public RadioData(Guid guid, ItemInstance item, int loadOrder, bool isOn, Vector3 position, Vector3 rotation, uint? stationIdHash, float volume, uint[] favoriteStations)
		{
			//IL_0023: 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)
			Volume = volume;
			FavoriteStations = favoriteStations;
			base..ctor(guid, item, loadOrder, isOn, position, rotation);
		}
	}
	[Serializable]
	public class TogglableOffGridItemData : OffGridItemData
	{
		public bool IsOn;

		public TogglableOffGridItemData(Guid guid, ItemInstance item, int loadOrder, bool isOn, Vector3 position, Vector3 rotation)
		{
			//IL_000c: 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)
			IsOn = isOn;
			base..ctor(guid, item, loadOrder, position, rotation);
		}
	}
}
namespace RealRadio.Helpers
{
	public static class HashHelper
	{
		private const uint FNVOffsetBasis32 = 2166136261u;

		private const uint FNVPrim32 = 16777619u;

		public static ushort Get16BitHash(this AssetBundle assetBundle)
		{
			if ((Object)(object)assetBundle == (Object)null)
			{
				throw new ArgumentNullException("assetBundle");
			}
			uint num = 2166136261u;
			string[] allAssetNames = assetBundle.GetAllAssetNames();
			foreach (string text in allAssetNames)
			{
				foreach (char c in text)
				{
					num ^= c;
					num *= 16777619;
				}
			}
			return (ushort)((num >> 16) ^ (num & 0xFFFFu));
		}
	}
	public static class PropertyHelper
	{
		public static double DistanceFromPropertyBoundsSquared(this Property property, Vector3 position, double? minAcceptableDistanceSquared)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			BoxCollider[] propertyBoundsColliders = property.propertyBoundsColliders;
			double num = double.MaxValue;
			BoxCollider[] array = propertyBoundsColliders;
			foreach (BoxCollider val in array)
			{
				if (((Collider)val).enabled && ((Component)val).gameObject.activeSelf)
				{
					double num2 = DistanceFromColliderSquared(position, val);
					if (num2 < num)
					{
						num = num2;
					}
					if (num <= minAcceptableDistanceSquared)
					{
						return num;
					}
				}
			}
			return num;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static double DistanceFromColliderSquared(Vector3 position, BoxCollider box)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: 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_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ((Collider)box).ClosestPoint(position);
			Vector3 val2 = position - val;
			return ((Vector3)(ref val2)).sqrMagnitude;
		}
	}
}
namespace RealRadio.Events
{
	public class EventRefData<T>
	{
		public T? Value { get; set; }

		public EventRefData(T? value = default(T?))
		{
			Value = value;
			base..ctor();
		}
	}
}
namespace RealRadio.Data
{
	[Serializable]
	[CreateAssetMenu(fileName = "RadioStation", menuName = "RealRadio/ScriptableObjects/RadioStation")]
	public class RadioStation : ScriptableObject
	{
		public string? Id;

		public string? Name;

		public string? Abbreviation;

		public RadioType Type;

		public string? Url;

		public string[]? Urls;

		public bool CanBePlayedByNPCs = true;

		public Sprite? Icon;

		public Color BackgroundColor = Color.clear;

		public bool RoundedBackground = true;

		public Color TextColor = Color.white;

		public override string ToString()
		{
			return $"{Name} ({Type}): {TypeDataToString()}";
		}

		public RealRadio.Components.API.Data.RadioStation ToDataType()
		{
			//IL_006a: 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)
			return new RealRadio.Components.API.Data.RadioStation
			{
				Id = Id,
				Name = Name,
				Abbreviation = Abbreviation,
				Type = Type,
				Url = Url,
				Urls = Urls.ToArray(),
				CanBePlayedByNPCs = CanBePlayedByNPCs,
				TextColor = "#" + ColorUtility.ToHtmlStringRGBA(TextColor),
				BackgroundColor = "#" + ColorUtility.ToHtmlStringRGBA(BackgroundColor),
				RoundedBackground = RoundedBackground
			};
		}

		private string TypeDataToString()
		{
			return Type switch
			{
				RadioType.InternetRadio => Url ?? string.Empty, 
				RadioType.YtDlp => (Urls != null) ? $" ({Urls.Length} songs)" : string.Empty, 
				_ => throw new NotImplementedException($"Unknown type: {Type}"), 
			};
		}
	}
	public static class RadioStationNetworkExtensions
	{
		public static void WriteRadioStation(this Writer writer, RadioStation? value)
		{
			if ((Object)(object)value == (Object)null)
			{
				writer.WriteByte((byte)1);
				return;
			}
			if (value.Id == null)
			{
				throw new ArgumentNullException("Id", "Station id cannot be null");
			}
			writer.WriteByte((byte)0);
			writer.WriteUInt32(StringHashing.GetStableHashCode(value.Id), (AutoPackType)1);
		}

		public static RadioStation? ReadRadioStation(this Reader reader)
		{
			if (reader.ReadByte() == 1)
			{
				return null;
			}
			uint num = reader.ReadUInt32((AutoPackType)1);
			if (!Singleton<RadioStationManager>.InstanceExists)
			{
				throw new InvalidOperationException("RadioStationManager does not exist at the time of reading a radio station from the network");
			}
			if (!Singleton<RadioStationManager>.Instance.StationsByHashedId.TryGetValue(num, out RadioStation value))
			{
				throw new InvalidOperationException($"Could not find radio station with id {num}");
			}
			return value;
		}
	}
	public enum StationSource
	{
		DefaultStation,
		FileAPI,
		UserCreated
	}
}
namespace RealRadio.GameMusic
{
	public class GameMusicManager : Singleton<GameMusicManager>
	{
		[CompilerGenerated]
		private sealed class <RemoveTrackAfterDelay>d__8 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public GameMusicManager <>4__this;

			public MusicTrack track;

			public float delay;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Expected O, but got Unknown
				int num = <>1__state;
				GameMusicManager gameMusicManager = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					gameMusicManager.soonStopping.Add(track);
					track.volumeMultiplier = gameMusicManager.currentVolume;
					<>2__current = (object)new WaitForSeconds(delay);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					gameMusicManager.RemoveTrack(track);
					return false;
				}
			}

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

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

		private Dictionary<MusicTrack, AudioSourceController> activeMusicTracks = new Dictionary<MusicTrack, AudioSourceController>();

		private HashSet<MusicTrack> soonStopping = new HashSet<MusicTrack>();

		private StreamAudioClient? globalClient;

		private float currentVolume;

		public override void Awake()
		{
			AmbientTrack[] array = Object.FindObjectsOfType<AmbientTrack>();
			for (int i = 0; i < array.Length; i++)
			{
				((Component)array[i]).gameObject.SetActive(false);
			}
			GameEvents.MusicTrackToggled = (Action<MusicTrack, bool>)Delegate.Combine(GameEvents.MusicTrackToggled, new Action<MusicTrack, bool>(OnMusicTrackToggled));
			GameEvents.MusicTrackPlay = (Action<MusicTrack>)Delegate.Combine(GameEvents.MusicTrackPlay, new Action<MusicTrack>(OnMusicTrackPlay));
		}

		public override void OnDestroy()
		{
			base.OnDestroy();
			GameEvents.MusicTrackToggled = (Action<MusicTrack, bool>)Delegate.Remove(GameEvents.MusicTrackToggled, new Action<MusicTrack, bool>(OnMusicTrackToggled));
			GameEvents.MusicTrackPlay = (Action<MusicTrack>)Delegate.Remove(GameEvents.MusicTrackPlay, new Action<MusicTrack>(OnMusicTrackPlay));
		}

		private void OnMusicTrackToggled(MusicTrack track, bool enabled)
		{
			bool flag = activeMusicTracks.ContainsKey(track);
			if (enabled && !flag)
			{
				activeMusicTracks.Add(track, track.Controller);
			}
			else if (!enabled && flag)
			{
				if (track.FadeOutTime > 0f)
				{
					((MonoBehaviour)this).StartCoroutine(RemoveTrackAfterDelay(track, track.FadeOutTime));
				}
				else
				{
					RemoveTrack(track);
				}
			}
		}

		private void OnMusicTrackPlay(MusicTrack track)
		{
			activeMusicTracks.TryAdd(track, track.Controller);
		}

		[IteratorStateMachine(typeof(<RemoveTrackAfterDelay>d__8))]
		private IEnumerator RemoveTrackAfterDelay(MusicTrack track, float delay)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <RemoveTrackAfterDelay>d__8(0)
			{
				<>4__this = this,
				track = track,
				delay = delay
			};
		}

		private void RemoveTrack(MusicTrack track)
		{
			activeMusicTracks.Remove(track);
			soonStopping.Remove(track);
		}

		private void Update()
		{
			if ((Object)(object)globalClient != (Object)null && IsClientQuietOrSpatial(globalClient))
			{
				globalClient = null;
			}
			if (!((Object)(object)globalClient == (Object)null))
			{
				return;
			}
			foreach (StreamAudioHost host in AudioStreamManager.Instance.Hosts)
			{
				if (host.NumActiveClients == 0)
				{
					continue;
				}
				foreach (StreamAudioClient activeClient in host.ActiveClients)
				{
					if (!IsClientQuietOrSpatial(activeClient))
					{
						globalClient = activeClient;
						break;
					}
				}
			}
		}

		private static bool IsClientQuietOrSpatial(StreamAudioClient client)
		{
			bool flag = !((Behaviour)client).enabled || !client.AudioSource.isPlaying;
			if (!flag)
			{
				AudioStream val = client.Host?.AudioStream;
				bool flag2 = ((val == null || !val.Started) ? true : false);
				flag = flag2;
			}
			if (!flag && !(client.AudioSource.spatialBlend > 0f) && !(client.AudioSource.volume <= 0f))
			{
				return client.AudioSource.mute;
			}
			return true;
		}

		private void LateUpdate()
		{
			float num = (((Object)(object)globalClient == (Object)null) ? 1f : 0f);
			foreach (var (val3, val4) in activeMusicTracks)
			{
				if (!soonStopping.Contains(val3))
				{
					if (currentVolume < num)
					{
						currentVolume = Mathf.Min(currentVolume + Time.unscaledDeltaTime / 3f, num);
					}
					else if (currentVolume > num)
					{
						currentVolume = num;
					}
					val4.VolumeMultiplier = val3.VolumeMultiplier * currentVolume;
					val4.ApplyVolume();
					StartLoopMusicTrack val5 = (StartLoopMusicTrack)(object)((val3 is StartLoopMusicTrack) ? val3 : null);
					if (val5 != null && ((MusicTrack)val5).IsPlaying)
					{
						val5.LoopSound.VolumeMultiplier = val3.VolumeMultiplier * currentVolume;
						val5.LoopSound.ApplyVolume();
					}
				}
			}
		}
	}
}
namespace RealRadio.Components.YoutubeDL
{
	public class YtDlpManager : PersistentSingleton<YtDlpManager>
	{
		private class ReportDownloadProgress : IProgress<DownloadProgress>
		{
			[CompilerGenerated]
			private YtDlpManager <manager>P;

			[CompilerGenerated]
			private string <url>P;

			public ReportDownloadProgress(YtDlpManager manager, string url)
			{
				<manager>P = manager;
				<url>P = url;
				base..ctor();
			}

			public void Report(DownloadProgress value)
			{
				lock (<manager>P.downloadProgressUpdatesLock)
				{
					<manager>P.downloadProgressUpdates[<url>P] = value;
				}
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass22_0
		{
			public Task<string> task;

			internal bool <DownloadAudioFileCoroutine>b__0()
			{
				return task.IsCompleted;
			}
		}

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

			private object <>2__current;

			public YtDlpManager <>4__this;

			public string url;

			private <>c__DisplayClass22_0 <>8__1;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Expected O, but got Unknown
				int num = <>1__state;
				YtDlpManager ytDlpManager = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>8__1 = new <>c__DisplayClass22_0();
					<>8__1.task = ytDlpManager.DownloadAudioFile(url);
					<>2__current = (object)new WaitUntil((Func<bool>)(() => <>8__1.task.IsCompleted));
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (<>8__1.task.IsFaulted)
					{
						Logger.LogError($"Failed to download audio file '{url}':\n{<>8__1.task.Exception}");
						return false;
					}
					Logger.LogInfo("Audio file '" + url + "' downloaded: " + <>8__1.task.Result);
					return false;
				}
			}

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

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

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

			private object <>2__current;

			public YtDlpManager <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: Expected O, but got Unknown
				int num = <>1__state;
				YtDlpManager CS$<>8__locals0 = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					Logger.LogInfo("Downloading YtDlp binaries...");
					CS$<>8__locals0.downloadBinariesTask = CS$<>8__locals0.ytDlp.DownloadBinaries();
					<>2__current = (object)new WaitUntil((Func<bool>)(() => CS$<>8__locals0.downloadBinariesTask.IsCompleted));
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (CS$<>8__locals0.downloadBinariesTask.IsFaulted)
					{
						Logger.LogError($"Failed to download YtDlp binaries:\n{CS$<>8__locals0.downloadBinariesTask.Exception}");
						return false;
					}
					Logger.LogInfo("YtDlp binaries downloaded");
					return false;
				}
			}

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

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

		public readonly IReadOnlyDictionary<string, VideoData> AudioMetaData;

		public readonly IReadOnlyDictionary<string, string> AudioFilePaths;

		public readonly IReadOnlyDictionary<string, DownloadProgress> DownloadProgresses;

		public Action<string, DownloadProgress>? OnDownloadProgress;

		private YtDlp ytDlp;

		private Task downloadBinariesTask;

		private readonly CancellationTokenSource ytDlpCts = new CancellationTokenSource();

		private readonly Dictionary<string, VideoData> metaData = new Dictionary<string, VideoData>();

		private readonly Dictionary<string, string> audioFilePaths = new Dictionary<string, string>();

		private readonly Dictionary<string, DownloadProgress> downloadProgresses = new Dictionary<string, DownloadProgress>();

		private readonly Dictionary<string, DownloadProgress> downloadProgressUpdates = new Dictionary<string, DownloadProgress>();

		private readonly object downloadProgressUpdatesLock = new object();

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

		public YtDlpManager()
		{
			AudioMetaData = new ReadOnlyDictionary<string, VideoData>(metaData);
			AudioFilePaths = new ReadOnlyDictionary<string, string>(audioFilePaths);
			DownloadProgresses = new ReadOnlyDictionary<string, DownloadProgress>(downloadProgresses);
		}

		public override void Awake()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			base.Awake();
			string cachePath = GetCachePath();
			ytDlp = new YtDlp(cachePath, (byte)4);
			((MonoBehaviour)this).StartCoroutine(DownloadBinaries());
			Singleton<RadioStationManager>.Instance.StationUpdated += OnRadioStationUpdated;
			foreach (RealRadio.Data.RadioStation station in Singleton<RadioStationManager>.Instance.Stations)
			{
				OnRadioStationUpdated(station, null);
			}
		}

		private void LateUpdate()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Invalid comparison between Unknown and I4
			finishedDownloads.Clear();
			string key;
			DownloadProgress value;
			foreach (KeyValuePair<string, DownloadProgress> downloadProgress in downloadProgresses)
			{
				downloadProgress.Deconstruct(out key, out value);
				string item = key;
				if ((int)value.State == 5)
				{
					finishedDownloads.Add(item);
				}
			}
			foreach (string finishedDownload in finishedDownloads)
			{
				downloadProgresses.Remove(finishedDownload);
			}
			lock (downloadProgressUpdatesLock)
			{
				foreach (KeyValuePair<string, DownloadProgress> downloadProgressUpdate in downloadProgressUpdates)
				{
					downloadProgressUpdate.Deconstruct(out key, out value);
					string text = key;
					DownloadProgress val = value;
					downloadProgresses[text] = val;
					OnDownloadProgress?.Invoke(text, val);
				}
				downloadProgressUpdates.Clear();
			}
		}

		private static string GetCachePath()
		{
			return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Cache");
		}

		private void OnRadioStationUpdated(RealRadio.Data.RadioStation station, RealRadio.Data.RadioStation? oldStation)
		{
			if (station.Type != RadioType.YtDlp)
			{
				return;
			}
			string[] urls = station.Urls;
			if ((urls == null || urls.Length == 0) ? true : false)
			{
				Logger.LogWarning("YtDlp radio station '" + station.Name + "' has no URLs");
				return;
			}
			urls = station.Urls;
			foreach (string url in urls)
			{
				((MonoBehaviour)this).StartCoroutine(DownloadAudioFileCoroutine(url));
			}
		}

		public override void OnDestroy()
		{
			((Singleton<YtDlpManager>)(object)this).OnDestroy();
			ytDlpCts.Cancel();
		}

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

		public async Task<VideoData> FetchMetaData(string url)
		{
			if (metaData.TryGetValue(url, out VideoData value))
			{
				return value;
			}
			if (!Uri.TryCreate(url, UriKind.Absolute, out Uri _))
			{
				throw new UriFormatException("Invalid URL '" + url + "'");
			}
			value = await ytDlp.DownloadMetaData(url, ytDlpCts.Token);
			metaData[url] = value;
			return value;
		}

		public async Task<string> DownloadAudioFile(string url)
		{
			if (audioFilePaths.TryGetValue(url, out string value))
			{
				return value;
			}
			if (!Uri.TryCreate(url, UriKind.Absolute, out Uri _))
			{
				throw new UriFormatException("Invalid URL '" + url + "'");
			}
			Logger.LogDebug("Downloading (if not cached) audio file '" + url + "'...");
			OnDownloadProgress?.Invoke(url, new DownloadProgress((DownloadState)1, 0f, (string)null, (string)null, (string)null, 1, (string)null));
			VideoData metaData;
			try
			{
				metaData = await FetchMetaData(url);
			}
			catch (YtDlpFetchMetaDataException val)
			{
				YtDlpFetchMetaDataException val2 = val;
				OnDownloadProgress?.Invoke(url, new DownloadProgress((DownloadState)4, 0f, (string)null, (string)null, (string)null, 1, string.Join("\n", ((YtDlpException)val2).Errors)));
				throw;
			}
			OnDownloadProgress?.Invoke(url, new DownloadProgress((DownloadState)1, 0f, (string)null, (string)null, (string)null, 1, (string)null));
			if (metaData.IsLive.GetValueOrDefault())
			{
				throw new ArgumentException("Live streams are not supported");
			}
			string filePath;
			try
			{
				filePath = await ytDlp.DownloadAudioFile(url, ytDlpCts.Token, (IProgress<DownloadProgress>)new ReportDownloadProgress(this, url), (IProgress<string>)null);
			}
			catch (YtDlpVideoDownloadException val3)
			{
				YtDlpVideoDownloadException val4 = val3;
				OnDownloadProgress?.Invoke(url, new DownloadProgress((DownloadState)4, 0f, (string)null, (string)null, (string)null, 1, string.Join("\n", ((YtDlpException)val4).Errors)));
				throw;
			}
			audioFilePaths[url] = filePath;
			if (!metaData.Duration.HasValue)
			{
				Logger.LogDebug("Attempting to get duration from audio file '" + filePath + "'...");
				try
				{
					VideoData val5 = metaData;
					val5.Duration = await GetAudioFileDuration(filePath);
					Logger.LogDebug($"Duration of audio file '{filePath}' is {metaData.Duration} seconds");
					try
					{
						await ytDlp.UpdateCachedMetaData(url, metaData);
					}
					catch (Exception arg)
					{
						Logger.LogError($"Failed to update cached metadata for audio file '{filePath}': {arg}");
					}
				}
				catch (Exception arg2)
				{
					Logger.LogError($"Failed to get duration from audio file '{filePath}': {arg2}");
				}
			}
			OnDownloadProgress?.Invoke(url, new DownloadProgress((DownloadState)5, 0f, (string)null, (string)null, (string)null, 1, (string)null));
			return filePath;
		}

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

		public async Task<float> GetAudioFileDuration(string filePath)
		{
			string filePath2 = filePath;
			return await Task.Run(() => (float)((WaveStream)new AudioFileReader(filePath2)).TotalTime.TotalSeconds);
		}

		public Task<VideoData[]> FetchPlaylistMetaData(string[] urls, CancellationToken token)
		{
			return ytDlp.DownloadPlaylistUrls(urls, token);
		}
	}
	[RequireComponent(typeof(UIDocument))]
	public class YtDlpUiManager : PersistentSingleton<YtDlpUiManager>
	{
		private class ListItem
		{
			public readonly string Url;

			private readonly YtDlpUiManager parent;

			private Label name;

			private Label state;

			private ProgressBar progressBar;

			private Button logButton;

			private Button downloadButton;

			private Button removeButton;

			public DownloadProgress? DownloadProgress { get; set; }

			public string Name
			{
				get
				{
					return ((TextElement)name).text;
				}
				set
				{
					((TextElement)name).text = value;
				}
			}

			public float Progress
			{
				get
				{
					return ((AbstractProgressBar)progressBar).value;
				}
				set
				{
					((AbstractProgressBar)progressBar).value = value;
				}
			}

			public string StateText
			{
				get
				{
					return ((TextElement)state).text;
				}
				set
				{
					((TextElement)state).text = value;
				}
			}

			public string LogText { get; set; } = "";


			public bool ProgressBarErrorState
			{
				get
				{
					return ((VisualElement)progressBar).classList.Contains("error");
				}
				set
				{
					if (value && !ProgressBarErrorState)
					{
						((VisualElement)progressBar).AddToClassList("error");
					}
					else if (!value && ProgressBarErrorState)
					{
						((VisualElement)progressBar).RemoveFromClassList("error");
					}
				}
			}

			public bool LogButtonEnabled
			{
				get
				{
					return ((VisualElement)logButton).classList.Contains("enabled");
				}
				set
				{
					if (value && !LogButtonEnabled)
					{
						((VisualElement)logButton).AddToClassList("enabled");
					}
					else if (!value && LogButtonEnabled)
					{
						((VisualElement)logButton).RemoveFromClassList("enabled");
					}
				}
			}

			public bool DownloadButtonEnabled
			{
				get
				{
					return ((VisualElement)downloadButton).classList.Contains("enabled");
				}
				set
				{
					if (value && !DownloadButtonEnabled)
					{
						((VisualElement)downloadButton).AddToClassList("enabled");
					}
					else if (!value && DownloadButtonEnabled)
					{
						((VisualElement)downloadButton).RemoveFromClassList("enabled");
					}
				}
			}

			public bool RemoveButtonEnabled
			{
				get
				{
					return ((VisualElement)removeButton).classList.Contains("enabled");
				}
				set
				{
					if (value && !RemoveButtonEnabled)
					{
						((VisualElement)removeButton).AddToClassList("enabled");
					}
					else if (!value && RemoveButtonEnabled)
					{
						((VisualElement)removeButton).RemoveFromClassList("enabled");
					}
				}
			}

			public VisualElement Element { get; private set; }

			public ListItem(YtDlpUiManager parent, VisualElement element, string url)
			{
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: 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_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0080: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00be: Unknown result type (might be due to invalid IL or missing references)
				//IL_0101: Unknown result type (might be due to invalid IL or missing references)
				//IL_0106: Unknown result type (might be due to invalid IL or missing references)
				//IL_0149: Unknown result type (might be due to invalid IL or missing references)
				//IL_014e: Unknown result type (might be due to invalid IL or missing references)
				this.parent = parent;
				Element = element;
				Url = url;
				name = UQueryExtensions.Query<Label>(element, "Name", (string)null).First() ?? throw new InvalidOperationException("Could not find name ui element");
				state = UQueryExtensions.Query<Label>(element, "State", (string)null).First() ?? throw new InvalidOperationException("Could not find state ui element");
				progressBar = UQueryExtensions.Query<ProgressBar>(element, "ProgressBar", (string)null).First() ?? throw new InvalidOperationException("Could not find progress bar ui element");
				((AbstractProgressBar)progressBar).value = 0f;
				logButton = UQueryExtensions.Query<Button>(element, "LogButton", (string)null).First() ?? throw new InvalidOperationException("Could not find remove button ui element");
				((CallbackEventHandler)logButton).RegisterCallback<ClickEvent>((EventCallback<ClickEvent>)OnLogButtonClicked, (TrickleDown)0);
				LogButtonEnabled = false;
				downloadButton = UQueryExtensions.Query<Button>(element, "DownloadButton", (string)null).First() ?? throw new InvalidOperationException("Could not find download button ui element");
				((CallbackEventHandler)downloadButton).RegisterCallback<ClickEvent>((EventCallback<ClickEvent>)OnDownloadButtonClicked, (TrickleDown)0);
				DownloadButtonEnabled = false;
				removeButton = UQueryExtensions.Query<Button>(element, "RemoveButton", (string)null).First() ?? throw new InvalidOperationException("Could not find remove button ui element");
				((CallbackEventHandler)removeButton).RegisterCallback<ClickEvent>((EventCallback<ClickEvent>)OnRemoveButtonClicked, (TrickleDown)0);
				RemoveButtonEnabled = false;
			}

			private void OnLogButtonClicked(ClickEvent evt)
			{
				if (((VisualElement)logButton).enabledSelf)
				{
					Singleton<Modal>.Instance.ShowModal("Error Log", LogText.Trim(), Element.GetRoot());
				}
			}

			private void OnDownloadButtonClicked(ClickEvent evt)
			{
				if (((VisualElement)downloadButton).enabledSelf)
				{
					LogText = "";
					ProgressBarErrorState = false;
					StateText = "";
					Singleton<YtDlpManager>.Instance.DownloadAudioFile(Url);
				}
			}

			private void OnRemoveButtonClicked(ClickEvent evt)
			{
				if (((VisualElement)removeButton).enabledSelf)
				{
					((VisualElement)parent.itemsContainer).Remove(Element);
					parent.items.Remove(Url);
				}
			}
		}

		public float LoadingIconSpinDegreesPerSecond = 360f;

		private VisualElement downloadIndicator;

		private VisualElement downloadIndicatorSpinIcon;

		private VisualElement downloadList;

		private Label noActiveDownloadsLabel;

		private ScrollView itemsContainer;

		private Dictionary<string, ListItem> items = new Dictionary<string, ListItem>();

		public UIDocument Document { get; private set; }

		[field: SerializeField]
		public VisualTreeAsset ListItemAsset { get; private set; }

		public bool DownloadIndicatorVisible
		{
			get
			{
				return downloadIndicator.classList.Contains("visible");
			}
			set
			{
				if (value && !DownloadIndicatorVisible)
				{
					downloadIndicator.AddToClassList("visible");
				}
				else if (!value && DownloadIndicatorVisible)
				{
					downloadIndicator.RemoveFromClassList("visible");
				}
			}
		}

		public bool DownloadIndicatorEnabled
		{
			get
			{
				return downloadIndicator.classList.Contains("enabled");
			}
			set
			{
				if (value && !DownloadIndicatorEnabled)
				{
					downloadIndicator.AddToClassList("enabled");
				}
				else if (!value && DownloadIndicatorEnabled)
				{
					downloadIndicator.RemoveFromClassList("enabled");
				}
			}
		}

		public bool NoActiveDownloadsLabelVisible
		{
			get
			{
				return ((VisualElement)noActiveDownloadsLabel).classList.Contains("visible");
			}
			set
			{
				if (value && !NoActiveDownloadsLabelVisible)
				{
					((VisualElement)noActiveDownloadsLabel).AddToClassList("visible");
				}
				else if (!value && NoActiveDownloadsLabelVisible)
				{
					((VisualElement)noActiveDownloadsLabel).RemoveFromClassList("visible");
				}
			}
		}

		public bool DownloadListEnabled
		{
			get
			{
				return downloadList.classList.Contains("enabled");
			}
			set
			{
				if (value && !DownloadListEnabled)
				{
					downloadList.AddToClassList("enabled");
					SortItemsContainer();
				}
				else if (!value && DownloadListEnabled)
				{
					downloadList.RemoveFromClassList("enabled");
				}
			}
		}

		public override void Awake()
		{
			//IL_0033: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: 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)
			//IL_00cc: 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)
			base.Awake();
			Document = ((Component)this).GetComponent<UIDocument>() ?? throw new InvalidOperationException("No UIDocument component found on game object");
			downloadIndicator = UQueryExtensions.Query(Document.rootVisualElement, "DownloadIndicator", (string)null).First() ?? throw new InvalidOperationException("Could not find download indicator ui element");
			downloadIndicatorSpinIcon = UQueryExtensions.Query(downloadIndicator, (string)null, "icon-spinning").First() ?? throw new InvalidOperationException("Could not find download indicator's spin icon ui element");
			downloadList = UQueryExtensions.Query(Document.rootVisualElement, "DownloadList", (string)null).First() ?? throw new InvalidOperationException("Could not find download list ui element");
			noActiveDownloadsLabel = UQueryExtensions.Query<Label>(Document.rootVisualElement, "NoActiveDownloadsLabel", (string)null).First() ?? throw new InvalidOperationException("Could not find no active downloads label ui element");
			itemsContainer = UQueryExtensions.Query<ScrollView>(Document.rootVisualElement, "ListItemsContainer", (string)null).First() ?? throw new InvalidOperationException("Could not find item list container ui element");
			if ((Object)(object)ListItemAsset == (Object)null)
			{
				throw new InvalidOperationException("ListItemAsset is not set");
			}
			foreach (var (url, progress) in Singleton<YtDlpManager>.Instance.DownloadProgresses)
			{
				OnDownloadProgressUpdate(url, progress);
			}
			YtDlpManager instance = Singleton<YtDlpManager>.Instance;
			instance.OnDownloadProgress = (Action<string, DownloadProgress>)Delegate.Combine(instance.OnDownloadProgress, new Action<string, DownloadProgress>(OnDownloadProgressUpdate));
		}

		private void OnDownloadProgressUpdate(string url, DownloadProgress progress)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Invalid comparison between Unknown and I4
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Invalid comparison between Unknown and I4
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Invalid comparison between Unknown and I4
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Invalid comparison between Unknown and I4
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Invalid comparison between Unknown and I4
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: 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_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Expected I4, but got Unknown
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Invalid comparison between Unknown and I4
			if (!items.TryGetValue(url, out ListItem value))
			{
				if ((int)progress.State == 5)
				{
					return;
				}
				VisualElement val = (VisualElement)(object)ListItemAsset.Instantiate();
				((VisualElement)itemsContainer).Add(val);
				value = (ListItem)(val.userData = new ListItem(this, val, url));
				items.Add(url, value);
			}
			value.DownloadProgress = progress;
			VideoData valueOrDefault = CollectionExtensions.GetValueOrDefault(Singleton<YtDlpManager>.Instance.AudioMetaData, url);
			if (valueOrDefault != null)
			{
				value.Name = (valueOrDefault.Title ?? url) + " (" + (valueOrDefault.Uploader ?? "Unknown uploader") + ")";
			}
			else
			{
				value.Name = url;
			}
			ListItem listItem2 = value;
			DownloadState state = progress.State;
			listItem2.StateText = ((object)(DownloadState)(ref state)).ToString();
			value.ProgressBarErrorState = (int)progress.State == 4;
			value.LogButtonEnabled = (int)progress.State == 4;
			value.DownloadButtonEnabled = (int)progress.State == 4;
			value.RemoveButtonEnabled = (int)progress.State == 4;
			if ((int)progress.State == 4 && !string.IsNullOrEmpty(progress.Data))
			{
				ListItem listItem3 = value;
				listItem3.LogText = listItem3.LogText + progress.Data + "\n";
			}
			state = progress.State;
			switch (state - 1)
			{
			case 0:
				value.Progress = 0f;
				break;
			case 1:
				if (progress.Progress > 0f)
				{
					value.Progress = progress.Progress * 0.9f;
				}
				break;
			case 4:
				value.Progress = 1f;
				break;
			case 3:
				value.Progress = 1f;
				value.StateText = "Failed - check the log for more info";
				break;
			default:
				value.Progress = 0.9f;
				break;
			}
			if ((int)progress.State == 5)
			{
				items.Remove(url);
				((VisualElement)itemsContainer).Remove(value.Element);
			}
			if (DownloadListEnabled)
			{
				SortItemsContainer();
			}
		}

		private void SortItemsContainer()
		{
			((VisualElement)itemsContainer).Sort((Comparison<VisualElement>)delegate(VisualElement a, VisualElement b)
			{
				ListItem listItem = a.userData as ListItem;
				ListItem listItem2 = b.userData as ListItem;
				if (listItem == null || listItem2 == null)
				{
					return 0;
				}
				if (listItem.DownloadProgress == null || listItem2.DownloadProgress == null)
				{
					return 0;
				}
				int num = listItem2.DownloadProgress.Progress.CompareTo(listItem.DownloadProgress.Progress);
				return (num != 0) ? num : listItem.Name.CompareTo(listItem2.Name);
			});
		}

		private void Update()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			bool flag = Singleton<PauseMenu>.InstanceExists && !Singleton<PauseMenu>.Instance.IsPaused;
			bool downloadIndicatorVisible = Singleton<YtDlpManager>.Instance.DownloadProgresses.Count > 0;
			DownloadIndicatorVisible = downloadIndicatorVisible;
			DownloadIndicatorEnabled = flag;
			NoActiveDownloadsLabelVisible = items.Count == 0;
			DownloadListEnabled = !flag;
			if (flag)
			{
				downloadIndicatorSpinIcon.style.rotate = new StyleRotate(new Rotate(new Angle((float)(Time.realtimeSinceStartupAsDouble * (double)LoadingIconSpinDegreesPerSecond % 360.0), (AngleUnit)0)));
			}
		}
	}
}
namespace RealRadio.Components.Vehicles
{
	public class VehicleRadioProxy : RadioProxy
	{
		[CompilerGenerated]
		private sealed class <DelayedEnableAudioClientObject>d__9 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public VehicleRadioProxy <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Expected O, but got Unknown
				int num = <>1__state;
				VehicleRadioProxy vehicleRadioProxy = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.23f);
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					GameObject? audioClientObject = vehicleRadioProxy.audioClientObject;
					if (audioClientObject != null)
					{
						audioClientObject.SetActive(true);
					}
					if ((Object)(object)vehicleRadioProxy.audioClient != (Object)null)
					{
						vehicleRadioProxy.UpdateAudioEffects();
					}
					return false;
				}
				}
			}

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

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

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

			private object <>2__current;

			public VehicleRadioProxy <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0048: Expected O, but got Unknown
				int num = <>1__state;
				VehicleRadioProxy CS$<>8__locals0 = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if (((NetworkBehaviour)CS$<>8__locals0).IsServer)
					{
						throw new InvalidOperationException("This coroutine should only run on clients");
					}
					<>2__current = (object)new WaitUntil((Func<bool>)(() => (Object)(object)CS$<>8__locals0.Vehicle != (Object)null));
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					CS$<>8__locals0.InitAudioClient();
					return false;
				}
			}

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

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

		private bool NetworkInitialize___EarlyRealRadio.Components.Vehicles.VehicleRadioProxyRealRadio.dll_Excuted;

		private bool NetworkInitialize__LateRealRadio.Components.Vehicles.VehicleRadioProxyRealRadio.dll_Excuted;

		public LandVehicle? Vehicle { get; set; }

		protected override void OnDestroy()
		{
			base.OnDestroy();
			if (Object.op_Implicit((Object)(object)Vehicle))
			{
				LandVehicle? vehicle = Vehicle;
				VehicleRadioProxyReference vehicleRadioProxyReference = ((vehicle != null) ? ((Component)vehicle).gameObject.GetComponent<VehicleRadioProxyReference>() : null);
				if (Object.op_Implicit((Object)(object)vehicleRadioProxyReference))
				{
					Object.Destroy((Object)(object)vehicleRadioProxyReference);
				}
			}
		}

		public override void OnStartServer()
		{
			((NetworkBehaviour)this).OnStartServer();
			if (((NetworkBehaviour)this).IsServer && (Object)(object)Vehicle == (Object)null)
			{
				throw new InvalidOperationException("Vehicle is null");
			}
		}

		public override void OnStartClient()
		{
			((NetworkBehaviour)this).OnStartClient();
			RequestVehicleInfo();
		}

		protected override void InitAudioClient(bool delayStart = true)
		{
			if (((NetworkBehaviour)this).IsClientOnly && (Object)(object)Vehicle == (Object)null)
			{
				((MonoBehaviour)this).StartCoroutine(WaitForReceiveVehicleThenInitAudioClient());
				return;
			}
			if ((Object)(object)audioClientObject == (Object)null)
			{
				throw new InvalidOperationException("AudioClientObject is null after receiving vehicle info");
			}
			base.InitAudioClient(delayStart);
			if (HasOccupants())
			{
				if (delayStart)
				{
					audioClientObject.SetActive(false);
					((MonoBehaviour)this).StartCoroutine(DelayedEnableAudioClientObject());
				}
				else
				{
					audioClientObject.SetActive(true);
				}
			}
			else
			{
				audioClientObject.SetActive(false);
			}
			if ((Object)(object)audioClient != (Object)null)
			{
				UpdateAudioEffects();
			}
		}

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

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

		[ServerRpc(RequireOwnership = false)]
		private void RequestVehicleInfo(NetworkConnection conn = null)
		{
			RpcWriter___Server_RequestVehicleInfo_328543758(conn);
		}

		[TargetRpc]
		private void ReceiveVehicleInfo(NetworkConnection conn, GameObject vehicleObject)
		{
			RpcWriter___Target_ReceiveVehicleInfo_2640020820(conn, vehicleObject);
		}

		private void OnVehicleSet()
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Expected O, but got Unknown
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Expected O, but got Unknown
			if ((Object)(object)Vehicle == (Object)null)
			{
				throw new InvalidOperationException("Vehicle is null");
			}
			((Object)this).name = ((Object)this).name + " (" + ((Object)Vehicle).name + ")";
			audioClientObject = Object.Instantiate<GameObject>(base.AudioClientPrefab);
			audioClientObject.transform.SetParent(((Component)Vehicle).transform, false);
			audioClientObject.SetActive(false);
			Vehicle.onVehicleStart.AddListener(new UnityAction(OnVehicleStart));
			Vehicle.onVehicleStop.AddListener(new UnityAction(OnVehicleStop));
			LandVehicle? vehicle = Vehicle;
			vehicle.onPlayerEnterVehicle = (VehiclePlayerEvent)Delegate.Combine((Delegate?)(object)vehicle.onPlayerEnterVehicle, (Delegate?)new VehiclePlayerEvent(OnPlayerEnterVehicle));
			LandVehicle? vehicle2 = Vehicle;
			vehicle2.onPlayerExitVehicle = (VehiclePlayerEvent)Delegate.Combine((Delegate?)(object)vehicle2.onPlayerExitVehicle, (Delegate?)new VehiclePlayerEvent(OnPlayerExitVehicle));
			((Component)Vehicle).gameObject.AddComponent<VehicleRadioProxyReference>().Proxy = this;
			if (HasOccupants())
			{
				OnEngineToggled(started: true);
			}
			else
			{
				OnEngineToggled(started: false);
			}
		}

		private void Update()
		{
			if (!((Object)(object)Vehicle == (Object)null) && ((NetworkBehaviour)this).IsServer && !Object.op_Implicit((Object)(object)Vehicle))
			{
				((NetworkBehaviour)this).Despawn((DespawnType?)(DespawnType)0);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private bool HasOccupants()
		{
			if (!HasPlayerOccupants())
			{
				return HasNPCOccupants();
			}
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private bool HasPlayerOccupants()
		{
			LandVehicle? vehicle = Vehicle;
			if (vehicle == null)
			{
				return false;
			}
			return vehicle.OccupantPlayers.Count > 0;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private bool HasNPCOccupants()
		{
			LandVehicle? vehicle = Vehicle;
			if (vehicle == null)
			{
				return false;
			}
			return vehicle.OccupantNPCs.Any((NPC x) => (Object)(object)x != (Object)null);
		}

		private void OnVehicleStart()
		{
			OnEngineToggled(HasOccupants());
		}

		private void OnVehicleStop()
		{
			OnEngineToggled(HasOccupants());
		}

		private void OnEngineToggled(bool started)
		{
			if (((NetworkBehaviour)this).IsServer && started && HasNPCOccupants())
			{
				if (Random.Range(0f, 1f) <= 0.5f)
				{
					SetRadioStationIdHash(StringHashing.GetStableHashCode(Singleton<RadioStationManager>.Instance.GetRandomNPCStation().Id));
				}
				else
				{
					SetRadioStationIdHash(null);
				}
			}
			if (started)
			{
				if (!Object.op_Implicit((Object)(object)audioClient))
				{
					InitAudioClient();
					return;
				}
				GameObject? obj = audioClientObject;
				if (obj != null && !obj.activeSelf)
				{
					((MonoBehaviour)this).StartCoroutine(DelayedEnableAudioClientObject());
				}
			}
			else
			{
				GameObject? obj2 = audioClientObject;
				if (obj2 != null)
				{
					obj2.SetActive(false);
				}
			}
		}

		private void OnPlayerEnterVehicle(Player player)
		{
			if (!((Object)(object)player == (Object)null) && player.IsLocalPlayer && (Object)(object)base.RadioStation != (Object)null)
			{
				UpdateAudioEffects();
			}
		}

		private void OnPlayerExitVehicle(Player player)
		{
			if (!((Object)(object)player == (Object)null) && player.IsLocalPlayer)
			{
				OnEngineToggled(HasOccupants());
				if ((Object)(object)base.RadioStation != (Object)null)
				{
					UpdateAudioEffects();
				}
			}
		}

		private void UpdateAudioEffects()
		{
			if ((Object)(object)audioClient == (Object)null)
			{
				Logger.LogWarning("Tried to update audio effects but audio client is null");
				return;
			}
			LandVehicle? vehicle = Vehicle;
			bool flag = vehicle != null && vehicle.OccupantPlayers.Contains(Player.Local);
			AudioSource obj = audioClient.AudioSource;
			obj.spatialBlend = ((!flag) ? 1 : 0);
			((Behaviour)((Component)obj).GetComponent<AudioLowPassFilter>()).enabled = !flag;
			audioClient.ConvertToMono = !flag;
		}

		public override void NetworkInitialize___Early()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			if (!NetworkInitialize___EarlyRealRadio.Components.Vehicles.VehicleRadioProxyRealRadio.dll_Excuted)
			{
				NetworkInitialize___EarlyRealRadio.Components.Vehicles.VehicleRadioProxyRealRadio.dll_Excuted = true;
				base.NetworkInitialize___Early();
				((NetworkBehaviour)this).RegisterServerRpc(1u, new ServerRpcDelegate(RpcReader___Server_RequestVehicleInfo_328543758));
				((NetworkBehaviour)this).RegisterTargetRpc(2u, new ClientRpcDelegate(RpcReader___Target_ReceiveVehicleInfo_2640020820));
			}
		}

		public override void NetworkInitialize__Late()
		{
			if (!NetworkInitialize__LateRealRadio.Components.Vehicles.VehicleRadioProxyRealRadio.dll_Excuted)
			{
				NetworkInitialize__LateRealRadio.Components.Vehicles.VehicleRadioProxyRealRadio.dll_Excuted = true;
				base.NetworkInitialize__Late();
			}
		}

		public override void NetworkInitializeIfDisabled()
		{
			NetworkInitialize___Early();
			NetworkInitialize__Late();
		}

		private void RpcWriter___Server_RequestVehicleInfo_328543758(NetworkConnection conn = null)
		{
			//IL_005f: 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)
			if (!((NetworkBehaviour)this).IsClientInitialized)
			{
				NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
				if (networkManager == null)
				{
					networkManager = InstanceFinder.NetworkManager;
				}
				if (networkManager != null)
				{
					networkManager.LogWarning("Cannot complete action because client is not active. This may also occur if the object is not yet initialized, has deinitialized, or if it does not contain a NetworkObject component.");
				}
				else
				{
					Debug.LogWarning((object)"Cannot complete action because client is not active. This may also occur if the object is not yet initialized, has deinitialized, or if it does not contain a NetworkObject component.");
				}
			}
			else
			{
				Channel val = (Channel)0;
				PooledWriter writer = WriterPool.GetWriter();
				((NetworkBehaviour)this).SendServerRpc(1u, writer, val, (DataOrderType)0);
				writer.Store();
			}
		}

		private void RpcLogic___RequestVehicleInfo_328543758(NetworkConnection conn = null)
		{
			if ((Object)(object)Vehicle == (Object)null)
			{
				throw new InvalidOperationException("Vehicle is null");
			}
			ReceiveVehicleInfo(conn, ((Component)Vehicle).gameObject);
		}

		private void RpcReader___Server_RequestVehicleInfo_328543758(PooledReader PooledReader0, Channel channel, NetworkConnection conn)
		{
			if (((NetworkBehaviour)this).IsServerInitialized)
			{
				RpcLogic___RequestVehicleInfo_328543758(conn);
			}
		}

		private void RpcWriter___Target_ReceiveVehicleInfo_2640020820(NetworkConnection conn, GameObject vehicleObject)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			if (!((NetworkBehaviour)this).IsServerInitialized)
			{
				NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
				if (networkManager == null)
				{
					networkManager = InstanceFinder.NetworkManager;
				}
				if (networkManager != null)
				{
					networkManager.LogWarning("Cannot complete action because server is not active. This may also occur if the object is not yet initialized, has deinitialized, or if it does not contain a NetworkObject component.");
				}
				else
				{
					Debug.LogWarning((object)"Cannot complete action because server is not active. This may also occur if the object is not yet initialized, has deinitialized, or if it does not contain a NetworkObject component.");
				}
			}
			else
			{
				Channel val = (Channel)0;
				PooledWriter writer = WriterPool.GetWriter();
				((Writer)writer).WriteGameObject(vehicleObject);
				((NetworkBehaviour)this).SendTargetRpc(2u, writer, val, (DataOrderType)0, conn, false, true);
				writer.Store();
			}
		}

		private void RpcLogic___ReceiveVehicleInfo_2640020820(NetworkConnection conn, GameObject vehicleObject)
		{
			if ((Object)(object)Vehicle != (Object)null && ((NetworkBehaviour)this).IsClientOnly)
			{
				Logger.LogWarning("Received vehicle again");
				return;
			}
			Vehicle = vehicleObject.GetComponent<LandVehicle>() ?? throw new InvalidOperationException("Could not find LandVehicle component on received vehicle object (" + ((vehicleObject != null) ? ((Object)vehicleObject).name : null) + ")");
			OnVehicleSet();
		}

		private void RpcReader___Target_ReceiveVehicleInfo_2640020820(PooledReader PooledReader0, Channel channel)
		{
			GameObject vehicleObject = ((Reader)PooledReader0).ReadGameObject();
			if (((NetworkBehaviour)this).IsClientInitialized)
			{
				RpcLogic___ReceiveVehicleInfo_2640020820(((NetworkBehaviour)this).LocalConnection, vehicleObject);
			}
		}

		public override void Awake()
		{
			NetworkInitialize___Early();
			base.Awake();
			NetworkInitialize__Late();
		}
	}
	public class VehicleRadioProxyReference : MonoBehaviour
	{
		public VehicleRadioProxy? Proxy;

		public bool DestroyProxyOnDestroy = true;

		private void OnDestroy()
		{
			if (DestroyProxyOnDestroy && Object.op_Implicit((Object)(object)Proxy))
			{
				Object.Destroy((Object)(object)((Component)Proxy).gameObject);
			}
		}
	}
}
namespace RealRadio.Components.WorldUI
{
	[RequireComponent(typeof(Collider))]
	public class Button : MonoBehaviour
	{
		public Vector3 ClickOffset = -Vector3.forward * 0.01f;

		public AudioSourceController? CursorDownSound;

		public AudioSourceController? CursorUpSound;

		private bool cursorIsPushedDown;

		private RaycastHit[] hits = (RaycastHit[])(object)new RaycastHit[8];

		private Collider collider;

		private Vector3 initialPosition;

		private Vector3 targetPosition;

		private float lerpSpeed;

		public event Action? CursorDown;

		public event Action? CursorUp;

		public event Action? Click;

		private void Awake()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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)
			collider = ((Component)this).GetComponent<Collider>();
			initialPosition = ((Component)this).transform.localPosition;
			targetPosition = initialPosition;
			CursorDown += OnCursorDown;
			CursorUp += OnCursorUp;
		}

		private void OnCursorDown()
		{
			//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)
			//IL_0012: 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)
			targetPosition = ((Component)this).transform.localPosition + ClickOffset;
			lerpSpeed = 80f;
			AudioSourceController? cursorUpSound = CursorUpSound;
			if (cursorUpSound != null)
			{
				cursorUpSound.Stop();
			}
			AudioSourceController? cursorDownSound = CursorDownSound;
			if (cursorDownSound != null)
			{
				cursorDownSound.Play();
			}
		}

		private void OnCursorUp()
		{
			//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)
			targetPosition = initialPosition;
			lerpSpeed = 20f;
			AudioSourceController? cursorDownSound = CursorDownSound;
			if (cursorDownSound != null)
			{
				cursorDownSound.Stop();
			}
			AudioSourceController? cursorUpSound = CursorUpSound;
			if (cursorUpSound != null)
			{
				cursorUpSound.Play();
			}
		}

		private void Update()
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			if (GameInput.GetButtonDown((ButtonCode)0))
			{
				if (!TestRayHit())
				{
					return;
				}
				this.CursorDown?.Invoke();
				cursorIsPushedDown = true;
			}
			else if (GameInput.GetButtonUp((ButtonCode)0) && cursorIsPushedDown)
			{
				cursorIsPushedDown = false;
				this.CursorUp?.Invoke();
				if (TestRayHit())
				{
					this.Click?.Invoke();
				}
			}
			if (cursorIsPushedDown && !GameInput.GetButton((ButtonCode)0))
			{
				cursorIsPushedDown = false;
				this.CursorUp?.Invoke();
			}
			((Component)this).transform.localPosition = Vector3.Lerp(((Component)this).transform.localPosition, targetPosition, Time.deltaTime * lerpSpeed);
		}

		private bool TestRayHit()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			int num = Physics.RaycastNonAlloc(PlayerSingleton<PlayerCamera>.Instance.Camera.ScreenPointToRay(Input.mousePosition), hits, 1f, LayerMask.op_Implicit(Layers.Default.ToLayerMask()));
			if (num == 0)
			{
				return false;
			}
			return hits.Take(num).Any((RaycastHit hit) => (Object)(object)((RaycastHit)(ref hit)).collider == (Object)(object)collider);
		}
	}
}
namespace RealRadio.Components.UI
{
	public class Modal : Singleton<Modal>
	{
		[CompilerGenerated]
		private sealed class <AddVisibleClassNextFrame>d__12 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public VisualElement element;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					element.AddToClassList("visible");
					return false;
				}
			}

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

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

		[field: SerializeField]
		public VisualTreeAsset ModalTemplate { get; private set; }

		[field: SerializeField]
		public VisualTreeAsset MessageContentTemplate { get; private set; }

		public override void Awake()
		{
			base.Awake();
			if ((Object)(object)ModalTemplate == (Object)null)
			{
				throw new InvalidOperationException("ModalTemplate is null");
			}
		}

		public ModalInstance ShowModal(string title, string message, VisualElement context, string? confirmText = "OK", string? cancelText = null, ModalInstance.ConfirmedDelegate? onConfirm = null, Action<ModalInstance>? onCancel = null, Action<ModalInstance>? onClosed = null)
		{
			string message2 = message;
			return ShowModal(MessageContentTemplate, SetupContent, context, title, confirmText, cancelText, onConfirm, onCancel, onClosed);
			void SetupContent(ModalInstance instance)
			{
				//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)
				((Text

Mods/RealRadio/SocketIO.Core.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("doghappy")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("3.1.2.0")]
[assembly: AssemblyInformationalVersion("3.1.2+dc5e7d9d6c26d04d924351c8e242b6e8a8807f7a")]
[assembly: AssemblyProduct("SocketIO.Core")]
[assembly: AssemblyTitle("SocketIO.Core")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/doghappy/socket.io-client-csharp")]
[assembly: AssemblyVersion("3.1.2.0")]
namespace SocketIO.Core;

public enum EngineIO
{
	V3 = 3,
	V4
}
public enum EngineIOProtocol
{
	Open,
	Close,
	Ping,
	Pong,
	Message,
	Upgrade,
	Noop
}
public interface IMessage
{
	MessageType Type { get; }

	string Sid { get; set; }

	int PingInterval { get; set; }

	int PingTimeout { get; set; }

	List<string> Upgrades { get; set; }

	int BinaryCount { get; set; }

	string Namespace { get; set; }

	TimeSpan Duration { get; set; }

	int Id { get; set; }

	string Event { get; }

	string Error { get; set; }

	string ReceivedText { get; set; }

	List<byte[]> ReceivedBinary { get; set; }
}
public enum MessageType
{
	Opened = 0,
	Ping = 2,
	Pong = 3,
	Connected = 40,
	Disconnected = 41,
	Event = 42,
	Ack = 43,
	Error = 44,
	Binary = 45,
	BinaryAck = 46
}

Mods/RealRadio/SocketIO.Serializer.Core.dll

Decompiled a day 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 Microsoft.CodeAnalysis;
using SocketIO.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("doghappy")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("3.1.2.0")]
[assembly: AssemblyInformationalVersion("3.1.2+dc5e7d9d6c26d04d924351c8e242b6e8a8807f7a")]
[assembly: AssemblyProduct("SocketIO.Serializer.Core")]
[assembly: AssemblyTitle("SocketIO.Serializer.Core")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/doghappy/socket.io-client-csharp")]
[assembly: AssemblyVersion("3.1.2.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 SocketIO.Serializer.Core
{
	public static class EnumerableExtensions
	{
		public static bool AnyBinary(this IEnumerable<SerializedItem> serializedItems)
		{
			return serializedItems.Any((SerializedItem x) => x.Type == SerializedMessageType.Binary);
		}

		public static string FirstText(this IEnumerable<SerializedItem> serializedItems)
		{
			return serializedItems.First((SerializedItem x) => x.Type == SerializedMessageType.Text).Text;
		}

		public static List<byte[]> AllBinary(this IEnumerable<SerializedItem> serializedItems)
		{
			return (from x in serializedItems
				where x.Type == SerializedMessageType.Binary
				select x.Binary).ToList();
		}
	}
	public interface ISerializer
	{
		List<SerializedItem> Serialize(EngineIO eio, string eventName, int packetId, string ns, object[] data);

		List<SerializedItem> Serialize(EngineIO eio, int packetId, string nsp, object[] data);

		List<SerializedItem> Serialize(EngineIO eio, string eventName, string nsp, object[] data);

		T Deserialize<T>(IMessage message, int index);

		IMessage Deserialize(EngineIO eio, string text);

		IMessage Deserialize(EngineIO eio, byte[] bytes);

		string MessageToJson(IMessage message);

		IMessage NewMessage(MessageType type);

		SerializedItem SerializeConnectedMessage(EngineIO eio, string ns, object auth, IEnumerable<KeyValuePair<string, string>> queries);

		SerializedItem SerializePingMessage();

		SerializedItem SerializePongMessage();

		SerializedItem SerializeUpgradeMessage();
	}
	public class SerializedItem
	{
		public SerializedMessageType Type { get; set; }

		public string Text { get; set; }

		public byte[] Binary { get; set; }
	}
	public enum SerializedMessageType
	{
		Text,
		Binary
	}
}

Mods/RealRadio/SocketIO.Serializer.NewtonsoftJson.dll

Decompiled a day ago
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using SocketIO.Core;
using SocketIO.Serializer.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("doghappy")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("3.1.2.0")]
[assembly: AssemblyInformationalVersion("3.1.2+dc5e7d9d6c26d04d924351c8e242b6e8a8807f7a")]
[assembly: AssemblyProduct("SocketIO.Serializer.NewtonsoftJson")]
[assembly: AssemblyTitle("SocketIO.Serializer.NewtonsoftJson")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/doghappy/socket.io-client-csharp")]
[assembly: AssemblyVersion("3.1.2.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 SocketIO.Serializer.NewtonsoftJson
{
	internal class ByteArrayConverter : JsonConverter
	{
		public List<byte[]> Bytes { get; }

		public ByteArrayConverter()
		{
			Bytes = new List<byte[]>();
		}

		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			byte[] source = (byte[])value;
			Bytes.Add(source.ToArray());
			writer.WriteStartObject();
			writer.WritePropertyName("_placeholder");
			writer.WriteValue(true);
			writer.WritePropertyName("num");
			writer.WriteValue(Bytes.Count - 1);
			writer.WriteEndObject();
		}

		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Invalid comparison between Unknown and I4
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Invalid comparison between Unknown and I4
			if ((int)reader.TokenType != 1)
			{
				return null;
			}
			reader.Read();
			if ((int)reader.TokenType != 4 || reader.Value?.ToString() != "_placeholder")
			{
				return null;
			}
			reader.Read();
			if ((int)reader.TokenType != 10 || !(bool)reader.Value)
			{
				return null;
			}
			reader.Read();
			if ((int)reader.TokenType != 4 || reader.Value?.ToString() != "num")
			{
				return null;
			}
			reader.Read();
			if (reader.Value == null)
			{
				return null;
			}
			if (!int.TryParse(reader.Value.ToString(), out var result))
			{
				return null;
			}
			byte[] result2 = Bytes[result];
			reader.Read();
			return result2;
		}

		public override bool CanConvert(Type objectType)
		{
			return objectType == typeof(byte[]);
		}
	}
	public class JsonMessage : IMessage
	{
		private bool _parsed;

		private JArray _jsonArray;

		private string _event;

		public MessageType Type { get; }

		public string Sid { get; set; }

		public int PingInterval { get; set; }

		public int PingTimeout { get; set; }

		public List<string> Upgrades { get; set; }

		public int BinaryCount { get; set; }

		public string Namespace { get; set; }

		public TimeSpan Duration { get; set; }

		public int Id { get; set; }

		public string Error { get; set; }

		public string ReceivedText { get; set; }

		public List<byte[]> ReceivedBinary { get; set; }

		public JArray JsonArray
		{
			get
			{
				Parse();
				return _jsonArray;
			}
		}

		public string Event
		{
			get
			{
				Parse();
				return _event;
			}
			set
			{
				_event = value;
			}
		}

		public JsonMessage(MessageType type)
		{
			//IL_0007: 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)
			Type = type;
			Id = -1;
		}

		private void Parse()
		{
			if (!_parsed)
			{
				JArray val = JArray.Parse(ReceivedText);
				SetEvent(val);
				_jsonArray = val;
				_parsed = true;
			}
		}

		private void SetEvent(JArray jsonArray)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			if ((int)Type == 42 || (int)Type == 45)
			{
				if (((JContainer)jsonArray).Count < 1)
				{
					throw new ArgumentException("Cannot get event name from an empty json array");
				}
				if (jsonArray[0] == null)
				{
					throw new ArgumentException("Event name is null");
				}
				Event = Extensions.Value<string>((IEnumerable<JToken>)jsonArray[0]);
				jsonArray.RemoveAt(0);
			}
		}
	}
	public class NewtonsoftJsonSerializer : ISerializer
	{
		private readonly JsonSerializerSettings _options;

		private readonly ConcurrentQueue<IMessage> _messageQueue;

		public NewtonsoftJsonSerializer()
			: this(new JsonSerializerSettings())
		{
		}//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown


		public NewtonsoftJsonSerializer(JsonSerializerSettings options)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			_options = (JsonSerializerSettings)(((object)options) ?? ((object)new JsonSerializerSettings()));
			_messageQueue = new ConcurrentQueue<IMessage>();
		}

		private JsonSerializerSettings NewSettings(JsonConverter converter)
		{
			//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_0018: Expected O, but got Unknown
			return new JsonSerializerSettings(_options)
			{
				Converters = { converter }
			};
		}

		private string Serialize(object data)
		{
			return JsonConvert.SerializeObject(data, _options);
		}

		private static List<SerializedItem> NewSerializedItems(StringBuilder builder, IEnumerable<byte[]> bytes)
		{
			//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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			List<SerializedItem> list = new List<SerializedItem>();
			list.Add(new SerializedItem
			{
				Type = (SerializedMessageType)0,
				Text = builder.ToString()
			});
			list.AddRange(bytes.Select((Func<byte[], SerializedItem>)((byte[] x) => new SerializedItem
			{
				Type = (SerializedMessageType)1,
				Binary = x
			})));
			return list;
		}

		private static object[] InsertEventToData(string eventName, object[] data)
		{
			object[] array = new object[data.Length + 1];
			array[0] = eventName;
			Array.Copy(data, 0, array, 1, data.Length);
			return array;
		}

		public List<SerializedItem> Serialize(EngineIO _, string eventName, int packetId, string ns, object[] data)
		{
			return InternalSerialize(eventName, packetId, ns, data);
		}

		public List<SerializedItem> Serialize(EngineIO _, int packetId, string nsp, object[] data)
		{
			ByteArrayConverter byteArrayConverter = new ByteArrayConverter();
			JsonSerializerSettings val = NewSettings((JsonConverter)(object)byteArrayConverter);
			string value = ((data != null && data.Length > 0) ? JsonConvert.SerializeObject((object)data, val) : "[]");
			StringBuilder stringBuilder = new StringBuilder();
			if (byteArrayConverter.Bytes.Count == 0)
			{
				stringBuilder.Append("43");
			}
			else
			{
				stringBuilder.Append("46").Append(byteArrayConverter.Bytes.Count).Append('-');
			}
			if (!string.IsNullOrEmpty(nsp))
			{
				stringBuilder.Append(nsp).Append(',');
			}
			stringBuilder.Append(packetId).Append(value);
			return NewSerializedItems(stringBuilder, byteArrayConverter.Bytes);
		}

		public List<SerializedItem> Serialize(EngineIO _, string eventName, string nsp, object[] data)
		{
			return InternalSerialize(eventName, null, nsp, data);
		}

		private List<SerializedItem> InternalSerialize(string eventName, int? packetId, string ns, object[] data)
		{
			object[] array = InsertEventToData(eventName, data);
			ByteArrayConverter byteArrayConverter = new ByteArrayConverter();
			JsonSerializerSettings val = NewSettings((JsonConverter)(object)byteArrayConverter);
			string value = JsonConvert.SerializeObject((object)array, val);
			StringBuilder stringBuilder = new StringBuilder();
			if (byteArrayConverter.Bytes.Count == 0)
			{
				stringBuilder.Append("42");
			}
			else
			{
				stringBuilder.Append("45").Append(byteArrayConverter.Bytes.Count).Append('-');
			}
			if (!string.IsNullOrEmpty(ns))
			{
				stringBuilder.Append(ns).Append(',');
			}
			if (packetId.HasValue)
			{
				stringBuilder.Append(packetId);
			}
			stringBuilder.Append(value);
			return NewSerializedItems(stringBuilder, byteArrayConverter.Bytes);
		}

		private (JToken jsonNode, JsonSerializer serializer) GetSerializationData(IMessage message, int index)
		{
			JsonMessage jsonMessage = (JsonMessage)(object)message;
			JToken item = jsonMessage.JsonArray[index];
			ByteArrayConverter byteArrayConverter = new ByteArrayConverter();
			if (jsonMessage.ReceivedBinary != null)
			{
				byteArrayConverter.Bytes.AddRange(jsonMessage.ReceivedBinary);
			}
			JsonSerializerSettings val = NewSettings((JsonConverter)(object)byteArrayConverter);
			return (item, JsonSerializer.Create(val));
		}

		public T Deserialize<T>(IMessage message, int index)
		{
			var (val, val2) = GetSerializationData(message, index);
			return val.ToObject<T>(val2);
		}

		public object Deserialize(IMessage message, int index, Type returnType)
		{
			var (val, val2) = GetSerializationData(message, index);
			return val.ToObject(returnType, val2);
		}

		public IMessage Deserialize(EngineIO eio, string text)
		{
			//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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected I4, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			foreach (MessageType value in Enum.GetValues(typeof(MessageType)))
			{
				string text2 = ((int)value).ToString();
				if (text.StartsWith(text2))
				{
					IMessage val2 = NewMessage(value);
					ReadMessage(val2, eio, text.Substring(text2.Length));
					if (val2.BinaryCount > 0)
					{
						_messageQueue.Enqueue(val2);
						val2.ReceivedBinary = new List<byte[]>(val2.BinaryCount);
						return null;
					}
					return val2;
				}
			}
			return null;
		}

		public IMessage Deserialize(EngineIO _, byte[] bytes)
		{
			if (_messageQueue.Count <= 0)
			{
				return null;
			}
			if (!_messageQueue.TryPeek(out var result))
			{
				return null;
			}
			result.ReceivedBinary.Add(bytes);
			if (result.ReceivedBinary.Count < result.BinaryCount)
			{
				return null;
			}
			_messageQueue.TryDequeue(out var result2);
			return result2;
		}

		public string MessageToJson(IMessage message)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			return ((JToken)((JsonMessage)(object)message).JsonArray).ToString(_options.Formatting, Array.Empty<JsonConverter>());
		}

		public IMessage NewMessage(MessageType type)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return (IMessage)(object)new JsonMessage(type);
		}

		public SerializedItem SerializePingMessage()
		{
			//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: Expected O, but got Unknown
			return new SerializedItem
			{
				Text = "2"
			};
		}

		public SerializedItem SerializePongMessage()
		{
			//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: Expected O, but got Unknown
			return new SerializedItem
			{
				Text = "3"
			};
		}

		public SerializedItem SerializeUpgradeMessage()
		{
			//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: Expected O, but got Unknown
			return new SerializedItem
			{
				Text = "5"
			};
		}

		public SerializedItem SerializeConnectedMessage(EngineIO eio, string ns, object auth, IEnumerable<KeyValuePair<string, string>> queries)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if ((int)eio != 3)
			{
				if ((int)eio == 4)
				{
					return SerializeEio4ConnectedMessage(ns, auth);
				}
				throw new ArgumentOutOfRangeException("EngineIO", eio, null);
			}
			return SerializeEio3ConnectedMessage(ns, queries);
		}

		private static SerializedItem SerializeEio3ConnectedMessage(string ns, IEnumerable<KeyValuePair<string, string>> queries)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			if (string.IsNullOrEmpty(ns))
			{
				return null;
			}
			SerializedItem val = new SerializedItem();
			StringBuilder stringBuilder = new StringBuilder("40");
			stringBuilder.Append(ns);
			if (queries != null)
			{
				int num = -1;
				foreach (KeyValuePair<string, string> query in queries)
				{
					num++;
					stringBuilder.Append((num == 0) ? '?' : '&');
					stringBuilder.Append(query.Key).Append('=').Append(query.Value);
				}
			}
			stringBuilder.Append(',');
			val.Text = stringBuilder.ToString();
			return val;
		}

		private SerializedItem SerializeEio4ConnectedMessage(string ns, object auth)
		{
			//IL_0033: 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_0045: Expected O, but got Unknown
			StringBuilder stringBuilder = new StringBuilder("40");
			if (!string.IsNullOrEmpty(ns))
			{
				stringBuilder.Append(ns).Append(',');
			}
			if (auth != null)
			{
				stringBuilder.Append(Serialize(auth));
			}
			return new SerializedItem
			{
				Text = stringBuilder.ToString()
			};
		}

		private static void ReadMessage(IMessage message, EngineIO eio, string text)
		{
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected I4, but got Unknown
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected I4, but got Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			MessageType type = message.Type;
			switch ((int)type)
			{
			default:
				switch (type - 40)
				{
				case 0:
					ReadConnectedMessage(message, text, eio);
					return;
				case 1:
					ReadDisconnectedMessage(message, text);
					return;
				case 2:
					ReadEventMessage(message, text);
					return;
				case 3:
					ReadAckMessage(message, text);
					return;
				case 4:
					ReadErrorMessage(message, text, eio);
					return;
				case 5:
					ReadBinaryMessage(message, text);
					return;
				case 6:
					ReadBinaryAckMessage(message, text);
					return;
				}
				break;
			case 0:
				ReadOpenedMessage(message, text);
				return;
			case 1:
				break;
			case 2:
			case 3:
				return;
			}
			throw new ArgumentOutOfRangeException("Type", message.Type, null);
		}

		private static void ReadOpenedMessage(IMessage message, string text)
		{
			//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_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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_001d: Expected O, but got Unknown
			//IL_0022: Expected O, but got Unknown
			JsonConvert.PopulateObject(text, (object)message, new JsonSerializerSettings
			{
				ContractResolver = (IContractResolver)new DefaultContractResolver
				{
					NamingStrategy = (NamingStrategy)new CamelCaseNamingStrategy()
				}
			});
		}

		private static void ReadConnectedMessage(IMessage message, string text, EngineIO eio)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if ((int)eio != 3)
			{
				if ((int)eio != 4)
				{
					throw new ArgumentOutOfRangeException("eio", eio, null);
				}
				ReadEio4ConnectedMessage(message, text);
			}
			else
			{
				ReadEio3ConnectedMessage(message, text);
			}
		}

		private static void ReadDisconnectedMessage(IMessage message, string text)
		{
			message.Namespace = text.TrimEnd(new char[1] { ',' });
		}

		private static void ReadEio4ConnectedMessage(IMessage message, string text)
		{
			int num = text.IndexOf('{');
			if (num > 0)
			{
				message.Namespace = text.Substring(0, num - 1);
				text = text.Substring(num);
			}
			else
			{
				message.Namespace = string.Empty;
			}
			message.Sid = ((JToken)JObject.Parse(text)).Value<string>((object)"sid");
		}

		private static void ReadEio3ConnectedMessage(IMessage message, string text)
		{
			if (text.Length < 2)
			{
				return;
			}
			int num = text.IndexOf('/');
			if (num != -1)
			{
				int num2 = text.IndexOf('?', num);
				if (num2 == -1)
				{
					num2 = text.IndexOf(',', num);
				}
				if (num2 == -1)
				{
					num2 = text.Length;
				}
				message.Namespace = text.Substring(num, num2);
			}
		}

		private static void ReadEventMessage(IMessage message, string text)
		{
			int num = text.IndexOf('[');
			int num2 = text.LastIndexOf(',', num);
			if (num2 > -1)
			{
				string text2 = text.Substring(0, num);
				message.Namespace = text2.Substring(0, num2);
				if (num - num2 > 1)
				{
					message.Id = int.Parse(text2.Substring(num2 + 1));
				}
			}
			else if (num > 0)
			{
				message.Id = int.Parse(text.Substring(0, num));
			}
			message.ReceivedText = text.Substring(num);
		}

		private static void ReadAckMessage(IMessage message, string text)
		{
			int num = text.IndexOf('[');
			int num2 = text.LastIndexOf(',', num);
			if (num2 > -1)
			{
				string text2 = text.Substring(0, num);
				message.Namespace = text2.Substring(0, num2);
				message.Id = int.Parse(text2.Substring(num2 + 1));
			}
			else
			{
				message.Id = int.Parse(text.Substring(0, num));
			}
			message.ReceivedText = text.Substring(num);
		}

		private static void ReadErrorMessage(IMessage message, string text, EngineIO eio)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			if ((int)eio == 3)
			{
				message.Error = text.Trim(new char[1] { '"' });
				return;
			}
			int num = text.IndexOf('{');
			if (num > 0)
			{
				message.Namespace = text.Substring(0, num - 1);
				text = text.Substring(num);
			}
			JObject val = JObject.Parse(text);
			message.Error = ((JToken)val).Value<string>((object)"message");
		}

		private static void ReadBinaryMessage(IMessage message, string text)
		{
			message.ReceivedBinary = new List<byte[]>();
			int num = text.IndexOf('-');
			message.BinaryCount = int.Parse(text.Substring(0, num));
			int num2 = text.IndexOf('[');
			int num3 = text.LastIndexOf(',', num2);
			if (num3 > -1)
			{
				message.Namespace = text.Substring(num + 1, num3 - num - 1);
				int num4 = num2 - num3 - 1;
				if (num4 > 0)
				{
					message.Id = int.Parse(text.Substring(num3 + 1, num4));
				}
			}
			else
			{
				int num5 = num2 - num - 1;
				if (num5 > 0)
				{
					message.Id = int.Parse(text.Substring(num + 1, num5));
				}
			}
			message.ReceivedText = text.Substring(num2);
		}

		private static void ReadBinaryAckMessage(IMessage message, string text)
		{
			int num = text.IndexOf('-');
			message.BinaryCount = int.Parse(text.Substring(0, num));
			int num2 = text.IndexOf('[');
			int num3 = text.LastIndexOf(',', num2);
			if (num3 > -1)
			{
				message.Namespace = text.Substring(num + 1, num3 - num - 1);
				message.Id = int.Parse(text.Substring(num3 + 1, num2 - num3 - 1));
			}
			else
			{
				message.Id = int.Parse(text.Substring(num + 1, num2 - num - 1));
			}
			message.ReceivedText = text.Substring(num2);
		}
	}
}

Mods/RealRadio/SocketIO.Serializer.SystemTextJson.dll

Decompiled a day ago
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using Microsoft.CodeAnalysis;
using SocketIO.Core;
using SocketIO.Serializer.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("doghappy")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("3.1.2.0")]
[assembly: AssemblyInformationalVersion("3.1.2+dc5e7d9d6c26d04d924351c8e242b6e8a8807f7a")]
[assembly: AssemblyProduct("SocketIO.Serializer.SystemTextJson")]
[assembly: AssemblyTitle("SocketIO.Serializer.SystemTextJson")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/doghappy/socket.io-client-csharp")]
[assembly: AssemblyVersion("3.1.2.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 SocketIO.Serializer.SystemTextJson
{
	internal class ByteArrayConverter : JsonConverter<byte[]>
	{
		public List<byte[]> Bytes { get; }

		public ByteArrayConverter()
		{
			Bytes = new List<byte[]>();
		}

		public override byte[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			if (reader.TokenType != JsonTokenType.StartObject)
			{
				return null;
			}
			reader.Read();
			if (reader.TokenType != JsonTokenType.PropertyName || reader.GetString() != "_placeholder")
			{
				return null;
			}
			reader.Read();
			if (reader.TokenType != JsonTokenType.True || !reader.GetBoolean())
			{
				return null;
			}
			reader.Read();
			if (reader.TokenType != JsonTokenType.PropertyName || reader.GetString() != "num")
			{
				return null;
			}
			reader.Read();
			int @int = reader.GetInt32();
			byte[] result = Bytes[@int];
			reader.Read();
			return result;
		}

		public override void Write(Utf8JsonWriter writer, byte[] value, JsonSerializerOptions options)
		{
			Bytes.Add(value);
			writer.WriteStartObject();
			writer.WritePropertyName("_placeholder");
			writer.WriteBooleanValue(value: true);
			writer.WritePropertyName("num");
			writer.WriteNumberValue(Bytes.Count - 1);
			writer.WriteEndObject();
		}
	}
	public class JsonMessage : IMessage
	{
		private bool _parsed;

		private JsonArray _jsonArray;

		private string _event;

		public MessageType Type { get; }

		public string Sid { get; set; }

		public int PingInterval { get; set; }

		public int PingTimeout { get; set; }

		public List<string> Upgrades { get; set; }

		public int BinaryCount { get; set; }

		public string Namespace { get; set; }

		public TimeSpan Duration { get; set; }

		public int Id { get; set; }

		public string Error { get; set; }

		public string ReceivedText { get; set; }

		public List<byte[]> ReceivedBinary { get; set; }

		public JsonArray JsonArray
		{
			get
			{
				Parse();
				return _jsonArray;
			}
		}

		public string Event
		{
			get
			{
				Parse();
				return _event;
			}
			set
			{
				_event = value;
			}
		}

		public JsonMessage(MessageType type)
		{
			//IL_0007: 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)
			Type = type;
			Id = -1;
		}

		private void Parse()
		{
			if (!_parsed)
			{
				JsonArray jsonArray = (JsonNode.Parse(ReceivedText) ?? throw new ArgumentException("Cannot parse '" + ReceivedText + "' to JsonNode")).AsArray();
				SetEvent(jsonArray);
				_jsonArray = jsonArray;
				_parsed = true;
			}
		}

		private void SetEvent(JsonArray jsonArray)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			if ((int)Type == 42 || (int)Type == 45)
			{
				if (jsonArray.Count < 1)
				{
					throw new ArgumentException("Cannot get event name from an empty json array");
				}
				if (jsonArray[0] == null)
				{
					throw new ArgumentException("Event name is null");
				}
				Event = jsonArray[0].GetValue<string>();
				jsonArray.RemoveAt(0);
			}
		}
	}
	public class SystemTextJsonSerializer : ISerializer
	{
		private readonly JsonSerializerOptions _options;

		private readonly ConcurrentQueue<IMessage> _messageQueue;

		public SystemTextJsonSerializer()
			: this(new JsonSerializerOptions())
		{
		}

		public SystemTextJsonSerializer(JsonSerializerOptions options)
		{
			_options = options ?? new JsonSerializerOptions();
			_messageQueue = new ConcurrentQueue<IMessage>();
		}

		private JsonSerializerOptions NewOptions(JsonConverter converter)
		{
			return new JsonSerializerOptions(_options)
			{
				Converters = { converter }
			};
		}

		private string Serialize(object data)
		{
			return JsonSerializer.Serialize(data, _options);
		}

		private static List<SerializedItem> NewSerializedItems(StringBuilder builder, IEnumerable<byte[]> bytes)
		{
			//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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			List<SerializedItem> list = new List<SerializedItem>();
			list.Add(new SerializedItem
			{
				Type = (SerializedMessageType)0,
				Text = builder.ToString()
			});
			list.AddRange(bytes.Select((Func<byte[], SerializedItem>)((byte[] x) => new SerializedItem
			{
				Type = (SerializedMessageType)1,
				Binary = x
			})));
			return list;
		}

		private static object[] InsertEventToData(string eventName, object[] data)
		{
			object[] array = new object[data.Length + 1];
			array[0] = eventName;
			Array.Copy(data, 0, array, 1, data.Length);
			return array;
		}

		public List<SerializedItem> Serialize(EngineIO _, string eventName, int packetId, string ns, object[] data)
		{
			return InternalSerialize(eventName, packetId, ns, data);
		}

		public List<SerializedItem> Serialize(EngineIO _, int packetId, string nsp, object[] data)
		{
			ByteArrayConverter byteArrayConverter = new ByteArrayConverter();
			JsonSerializerOptions options = NewOptions(byteArrayConverter);
			string value = ((data != null && data.Length > 0) ? JsonSerializer.Serialize(data, options) : "[]");
			StringBuilder stringBuilder = new StringBuilder();
			if (byteArrayConverter.Bytes.Count == 0)
			{
				stringBuilder.Append("43");
			}
			else
			{
				stringBuilder.Append("46").Append(byteArrayConverter.Bytes.Count).Append('-');
			}
			if (!string.IsNullOrEmpty(nsp))
			{
				stringBuilder.Append(nsp).Append(',');
			}
			stringBuilder.Append(packetId).Append(value);
			return NewSerializedItems(stringBuilder, byteArrayConverter.Bytes);
		}

		public List<SerializedItem> Serialize(EngineIO _, string eventName, string nsp, object[] data)
		{
			return InternalSerialize(eventName, null, nsp, data);
		}

		private List<SerializedItem> InternalSerialize(string eventName, int? packetId, string ns, object[] data)
		{
			object[] value = InsertEventToData(eventName, data);
			ByteArrayConverter byteArrayConverter = new ByteArrayConverter();
			JsonSerializerOptions options = NewOptions(byteArrayConverter);
			string value2 = JsonSerializer.Serialize(value, options);
			StringBuilder stringBuilder = new StringBuilder();
			if (byteArrayConverter.Bytes.Count == 0)
			{
				stringBuilder.Append("42");
			}
			else
			{
				stringBuilder.Append("45").Append(byteArrayConverter.Bytes.Count).Append('-');
			}
			if (!string.IsNullOrEmpty(ns))
			{
				stringBuilder.Append(ns).Append(',');
			}
			if (packetId.HasValue)
			{
				stringBuilder.Append(packetId);
			}
			stringBuilder.Append(value2);
			return NewSerializedItems(stringBuilder, byteArrayConverter.Bytes);
		}

		private (JsonNode jsonNode, JsonSerializerOptions options) GetSerializationData(IMessage message, int index)
		{
			JsonMessage jsonMessage = (JsonMessage)(object)message;
			JsonNode? item = jsonMessage.JsonArray[index];
			ByteArrayConverter byteArrayConverter = new ByteArrayConverter();
			if (jsonMessage.ReceivedBinary != null)
			{
				byteArrayConverter.Bytes.AddRange(jsonMessage.ReceivedBinary);
			}
			JsonSerializerOptions item2 = NewOptions(byteArrayConverter);
			return (item, item2);
		}

		public T Deserialize<T>(IMessage message, int index)
		{
			var (node, options) = GetSerializationData(message, index);
			return node.Deserialize<T>(options);
		}

		public object Deserialize(IMessage message, int index, Type returnType)
		{
			var (node, options) = GetSerializationData(message, index);
			return node.Deserialize(returnType, options);
		}

		public IMessage Deserialize(EngineIO eio, string text)
		{
			//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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected I4, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			foreach (MessageType value in Enum.GetValues(typeof(MessageType)))
			{
				string text2 = ((int)value).ToString();
				if (text.StartsWith(text2))
				{
					IMessage val2 = NewMessage(value);
					ReadMessage(val2, eio, text.Substring(text2.Length));
					if (val2.BinaryCount > 0)
					{
						_messageQueue.Enqueue(val2);
						val2.ReceivedBinary = new List<byte[]>(val2.BinaryCount);
						return null;
					}
					return val2;
				}
			}
			return null;
		}

		public IMessage Deserialize(EngineIO _, byte[] bytes)
		{
			if (_messageQueue.Count <= 0)
			{
				return null;
			}
			if (!_messageQueue.TryPeek(out var result))
			{
				return null;
			}
			result.ReceivedBinary.Add(bytes);
			if (result.ReceivedBinary.Count < result.BinaryCount)
			{
				return null;
			}
			_messageQueue.TryDequeue(out var result2);
			return result2;
		}

		public string MessageToJson(IMessage message)
		{
			return ((JsonMessage)(object)message).JsonArray.ToJsonString(_options);
		}

		public IMessage NewMessage(MessageType type)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return (IMessage)(object)new JsonMessage(type);
		}

		public SerializedItem SerializePingMessage()
		{
			//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: Expected O, but got Unknown
			return new SerializedItem
			{
				Text = "2"
			};
		}

		public SerializedItem SerializeUpgradeMessage()
		{
			//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: Expected O, but got Unknown
			return new SerializedItem
			{
				Text = "5"
			};
		}

		public SerializedItem SerializePongMessage()
		{
			//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: Expected O, but got Unknown
			return new SerializedItem
			{
				Text = "3"
			};
		}

		public SerializedItem SerializeConnectedMessage(EngineIO eio, string ns, object auth, IEnumerable<KeyValuePair<string, string>> queries)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if ((int)eio != 3)
			{
				if ((int)eio == 4)
				{
					return SerializeEio4ConnectedMessage(ns, auth);
				}
				throw new ArgumentOutOfRangeException("EngineIO", eio, null);
			}
			return SerializeEio3ConnectedMessage(ns, queries);
		}

		private static SerializedItem SerializeEio3ConnectedMessage(string ns, IEnumerable<KeyValuePair<string, string>> queries)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			if (string.IsNullOrEmpty(ns))
			{
				return null;
			}
			SerializedItem val = new SerializedItem();
			StringBuilder stringBuilder = new StringBuilder("40");
			stringBuilder.Append(ns);
			if (queries != null)
			{
				int num = -1;
				foreach (KeyValuePair<string, string> query in queries)
				{
					num++;
					stringBuilder.Append((num == 0) ? '?' : '&');
					stringBuilder.Append(query.Key).Append('=').Append(query.Value);
				}
			}
			stringBuilder.Append(',');
			val.Text = stringBuilder.ToString();
			return val;
		}

		private SerializedItem SerializeEio4ConnectedMessage(string ns, object auth)
		{
			//IL_0033: 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_0045: Expected O, but got Unknown
			StringBuilder stringBuilder = new StringBuilder("40");
			if (!string.IsNullOrEmpty(ns))
			{
				stringBuilder.Append(ns).Append(',');
			}
			if (auth != null)
			{
				stringBuilder.Append(Serialize(auth));
			}
			return new SerializedItem
			{
				Text = stringBuilder.ToString()
			};
		}

		private static void ReadMessage(IMessage message, EngineIO eio, string text)
		{
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected I4, but got Unknown
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected I4, but got Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			MessageType type = message.Type;
			switch ((int)type)
			{
			default:
				switch (type - 40)
				{
				case 0:
					ReadConnectedMessage(message, text, eio);
					return;
				case 1:
					ReadDisconnectedMessage(message, text);
					return;
				case 2:
					ReadEventMessage(message, text);
					return;
				case 3:
					ReadAckMessage(message, text);
					return;
				case 4:
					ReadErrorMessage(message, text, eio);
					return;
				case 5:
					ReadBinaryMessage(message, text);
					return;
				case 6:
					ReadBinaryAckMessage(message, text);
					return;
				}
				break;
			case 0:
				ReadOpenedMessage(message, text);
				return;
			case 1:
				break;
			case 2:
			case 3:
				return;
			}
			throw new ArgumentOutOfRangeException("Type", message.Type, null);
		}

		private static void ReadOpenedMessage(IMessage message, string text)
		{
			JsonMessage jsonMessage = JsonSerializer.Deserialize<JsonMessage>(text, new JsonSerializerOptions
			{
				NumberHandling = JsonNumberHandling.AllowReadingFromString,
				PropertyNamingPolicy = JsonNamingPolicy.CamelCase
			});
			message.Sid = jsonMessage.Sid;
			message.PingInterval = jsonMessage.PingInterval;
			message.PingTimeout = jsonMessage.PingTimeout;
			message.Upgrades = jsonMessage.Upgrades;
		}

		private static void ReadConnectedMessage(IMessage message, string text, EngineIO eio)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if ((int)eio != 3)
			{
				if ((int)eio != 4)
				{
					throw new ArgumentOutOfRangeException("eio", eio, null);
				}
				ReadEio4ConnectedMessage(message, text);
			}
			else
			{
				ReadEio3ConnectedMessage(message, text);
			}
		}

		private static void ReadDisconnectedMessage(IMessage message, string text)
		{
			message.Namespace = text.TrimEnd(new char[1] { ',' });
		}

		private static void ReadEio4ConnectedMessage(IMessage message, string text)
		{
			int num = text.IndexOf('{');
			if (num > 0)
			{
				message.Namespace = text.Substring(0, num - 1);
				text = text.Substring(num);
			}
			else
			{
				message.Namespace = string.Empty;
			}
			message.Sid = JsonDocument.Parse(text).RootElement.GetProperty("sid").GetString();
		}

		private static void ReadEio3ConnectedMessage(IMessage message, string text)
		{
			if (text.Length < 2)
			{
				return;
			}
			int num = text.IndexOf('/');
			if (num != -1)
			{
				int num2 = text.IndexOf('?', num);
				if (num2 == -1)
				{
					num2 = text.IndexOf(',', num);
				}
				if (num2 == -1)
				{
					num2 = text.Length;
				}
				message.Namespace = text.Substring(num, num2);
			}
		}

		private static void ReadEventMessage(IMessage message, string text)
		{
			int num = text.IndexOf('[');
			int num2 = text.LastIndexOf(',', num);
			if (num2 > -1)
			{
				string text2 = text.Substring(0, num);
				message.Namespace = text2.Substring(0, num2);
				if (num - num2 > 1)
				{
					message.Id = int.Parse(text2.Substring(num2 + 1));
				}
			}
			else if (num > 0)
			{
				message.Id = int.Parse(text.Substring(0, num));
			}
			message.ReceivedText = text.Substring(num);
		}

		private static void ReadAckMessage(IMessage message, string text)
		{
			int num = text.IndexOf('[');
			int num2 = text.LastIndexOf(',', num);
			if (num2 > -1)
			{
				string text2 = text.Substring(0, num);
				message.Namespace = text2.Substring(0, num2);
				message.Id = int.Parse(text2.Substring(num2 + 1));
			}
			else
			{
				message.Id = int.Parse(text.Substring(0, num));
			}
			message.ReceivedText = text.Substring(num);
		}

		private static void ReadErrorMessage(IMessage message, string text, EngineIO eio)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			if ((int)eio == 3)
			{
				message.Error = text.Trim(new char[1] { '"' });
				return;
			}
			int num = text.IndexOf('{');
			if (num > 0)
			{
				message.Namespace = text.Substring(0, num - 1);
				text = text.Substring(num);
			}
			JsonObject jsonObject = (JsonNode.Parse(text) ?? throw new InvalidOperationException("Get a null while parse '" + text + "' to JsonNode")).AsObject();
			if (jsonObject == null)
			{
				throw new InvalidCastException("Cannot cast JsonNode to JsonObject");
			}
			message.Error = jsonObject["message"]?.GetValue<string>();
		}

		private static void ReadBinaryMessage(IMessage message, string text)
		{
			message.ReceivedBinary = new List<byte[]>();
			int num = text.IndexOf('-');
			message.BinaryCount = int.Parse(text.Substring(0, num));
			int num2 = text.IndexOf('[');
			int num3 = text.LastIndexOf(',', num2);
			if (num3 > -1)
			{
				message.Namespace = text.Substring(num + 1, num3 - num - 1);
				int num4 = num2 - num3 - 1;
				if (num4 > 0)
				{
					message.Id = int.Parse(text.Substring(num3 + 1, num4));
				}
			}
			else
			{
				int num5 = num2 - num - 1;
				if (num5 > 0)
				{
					message.Id = int.Parse(text.Substring(num + 1, num5));
				}
			}
			message.ReceivedText = text.Substring(num2);
		}

		private static void ReadBinaryAckMessage(IMessage message, string text)
		{
			int num = text.IndexOf('-');
			message.BinaryCount = int.Parse(text.Substring(0, num));
			int num2 = text.IndexOf('[');
			int num3 = text.LastIndexOf(',', num2);
			if (num3 > -1)
			{
				message.Namespace = text.Substring(num + 1, num3 - num - 1);
				message.Id = int.Parse(text.Substring(num3 + 1, num2 - num3 - 1));
			}
			else
			{
				message.Id = int.Parse(text.Substring(num + 1, num2 - num - 1));
			}
			message.ReceivedText = text.Substring(num2);
		}
	}
}

Mods/RealRadio/SocketIOClient.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Security;
using System.Net.WebSockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Runtime.Versioning;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using SocketIO.Core;
using SocketIO.Serializer.Core;
using SocketIO.Serializer.SystemTextJson;
using SocketIOClient.Extensions;
using SocketIOClient.Transport;
using SocketIOClient.Transport.Http;
using SocketIOClient.Transport.WebSockets;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("SocketIOClient.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b18b07d8d9f5f79927b53fb9601562a4986cd90fd64cbb7ccf0bd258dc3f2119a2c7db7bfea28eba76ae4346a125e56a6b6713e920656c598027182f19b54bcd9f9012228b5193d84c565e54caee24e4fcfa6f0cbe611b4bc631578fb4aa5f7dabf5beacbe8df27716a5a1849b5d124e5924161577424002142ba1ade29d089c")]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("doghappy")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("socket.io-client implemention for .NET")]
[assembly: AssemblyFileVersion("3.1.2.0")]
[assembly: AssemblyInformationalVersion("3.1.2+dc5e7d9d6c26d04d924351c8e242b6e8a8807f7a")]
[assembly: AssemblyProduct("SocketIOClient")]
[assembly: AssemblyTitle("SocketIOClient")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/doghappy/socket.io-client-csharp")]
[assembly: AssemblyVersion("3.1.2.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 SocketIOClient
{
	public class DisconnectReason
	{
		public static string IOServerDisconnect = "io server disconnect";

		public static string IOClientDisconnect = "io client disconnect";

		public static string PingTimeout = "ping timeout";

		public static string TransportClose = "transport close";

		public static string TransportError = "transport error";
	}
	public delegate void OnAnyHandler(string eventName, SocketIOResponse response);
	public delegate void OnOpenedHandler(string sid, int pingInterval, int pingTimeout);
	public delegate void OnAck(int packetId, List<JsonElement> array);
	public delegate void OnBinaryAck(int packetId, int totalCount, List<JsonElement> array);
	public delegate void OnBinaryReceived(int packetId, int totalCount, string eventName, List<JsonElement> array);
	public delegate void OnDisconnected();
	public delegate void OnError(string error);
	public delegate void OnEventReceived(int packetId, string eventName, List<JsonElement> array);
	public delegate void OnOpened(string sid, int pingInterval, int pingTimeout);
	public delegate void OnPing();
	public delegate void OnPong();
	public class ConnectionException : Exception
	{
		public ConnectionException(string message)
			: base(message)
		{
		}

		public ConnectionException(string message, Exception innerException)
			: base(message, innerException)
		{
		}
	}
	public class SocketIO : IDisposable
	{
		private Uri _serverUri;

		private int _attempts;

		private List<Type> _expectedExceptions;

		private int _packetId;

		private Exception _backgroundException;

		private Dictionary<int, Action<SocketIOResponse>> _ackActionHandlers;

		private Dictionary<int, Func<SocketIOResponse, Task>> _ackFuncHandlers;

		private List<OnAnyHandler> _onAnyHandlers;

		private Dictionary<string, Action<SocketIOResponse>> _eventActionHandlers;

		private Dictionary<string, Func<SocketIOResponse, Task>> _eventFuncHandlers;

		private double _reconnectionDelay;

		private readonly SemaphoreSlim _packetIdLock = new SemaphoreSlim(1, 1);

		private TaskCompletionSource<bool> _openedCompletionSource = new TaskCompletionSource<bool>();

		private TaskCompletionSource<bool> _transportCompletionSource = new TaskCompletionSource<bool>();

		private TaskCompletionSource<Exception> _connBackgroundSource = new TaskCompletionSource<Exception>();

		private readonly SemaphoreSlim _connectingLock = new SemaphoreSlim(1, 1);

		private CancellationTokenSource _connCts = new CancellationTokenSource();

		private readonly SemaphoreSlim _disconnectingLock = new SemaphoreSlim(1, 1);

		private Uri ServerUri
		{
			get
			{
				return _serverUri;
			}
			set
			{
				if (_serverUri != value)
				{
					_serverUri = value;
					if (value != null && value.AbsolutePath != "/")
					{
						Namespace = value.AbsolutePath;
					}
				}
			}
		}

		public string Id { get; private set; }

		public string Namespace { get; private set; }

		public bool Connected { get; private set; }

		public SocketIOOptions Options { get; }

		public ISerializer Serializer { get; set; }

		private ITransport Transport { get; set; }

		public IHttpClient HttpClient { get; set; }

		public Func<IClientWebSocket> ClientWebSocketProvider { get; set; }

		internal Dictionary<int, Action<SocketIOResponse>> AckActionHandlers => _ackActionHandlers;

		internal Dictionary<int, Func<SocketIOResponse, Task>> AckFuncHandlers => _ackFuncHandlers;

		public event EventHandler OnConnected;

		public event EventHandler<string> OnError;

		public event EventHandler<string> OnDisconnected;

		public event EventHandler<int> OnReconnected;

		public event EventHandler<int> OnReconnectAttempt;

		public event EventHandler<Exception> OnReconnectError;

		public event EventHandler OnReconnectFailed;

		public event EventHandler OnPing;

		public event EventHandler<TimeSpan> OnPong;

		public SocketIO(string uri)
			: this(new Uri(uri))
		{
		}

		public SocketIO(Uri uri)
			: this(uri, new SocketIOOptions())
		{
		}

		public SocketIO(string uri, SocketIOOptions options)
			: this(new Uri(uri), options)
		{
		}

		public SocketIO(Uri uri, SocketIOOptions options)
		{
			ServerUri = uri ?? throw new ArgumentNullException("uri");
			Options = options ?? throw new ArgumentNullException("options");
			Initialize();
		}

		private void InitializeStatus()
		{
			Id = null;
			Connected = false;
			_backgroundException = null;
			_reconnectionDelay = Options.ReconnectionDelay;
			Transport?.Dispose();
		}

		private void Initialize()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			_packetId = -1;
			_ackActionHandlers = new Dictionary<int, Action<SocketIOResponse>>();
			_ackFuncHandlers = new Dictionary<int, Func<SocketIOResponse, Task>>();
			_eventActionHandlers = new Dictionary<string, Action<SocketIOResponse>>();
			_eventFuncHandlers = new Dictionary<string, Func<SocketIOResponse, Task>>();
			_onAnyHandlers = new List<OnAnyHandler>();
			Serializer = (ISerializer)new SystemTextJsonSerializer();
			HttpClient = new DefaultHttpClient(Options.RemoteCertificateValidationCallback);
			ClientWebSocketProvider = () => new DefaultClientWebSocket(Options.RemoteCertificateValidationCallback);
			_expectedExceptions = new List<Type>
			{
				typeof(TimeoutException),
				typeof(WebSocketException),
				typeof(HttpRequestException),
				typeof(OperationCanceledException),
				typeof(TaskCanceledException),
				typeof(TransportException)
			};
		}

		private ITransport NewTransport(TransportProtocol protocol, TransportOptions options)
		{
			ITransport transport = protocol switch
			{
				TransportProtocol.Polling => NewHttpTransport(options), 
				TransportProtocol.WebSocket => NewWebSocketTransport(options), 
				_ => throw new ArgumentOutOfRangeException(), 
			};
			OnTransportCreated(transport);
			return transport;
		}

		private TransportOptions NewTransportOptions()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return new TransportOptions
			{
				EIO = Options.EIO,
				Query = (Options.Query ?? new List<KeyValuePair<string, string>>()),
				Auth = Options.Auth,
				ServerUri = ServerUri,
				Path = Options.Path,
				ConnectionTimeout = Options.ConnectionTimeout,
				AutoUpgrade = Options.AutoUpgrade,
				Namespace = Namespace
			};
		}

		private HttpTransport NewHttpTransport(TransportOptions options)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			IHttpPollingHandler pollingHandler = HttpPollingHandler.CreateHandler(options.EIO, HttpClient);
			HttpTransport result = new HttpTransport(options, pollingHandler, Serializer);
			SetHttpHeaders();
			return result;
		}

		private WebSocketTransport NewWebSocketTransport(TransportOptions options)
		{
			IClientWebSocket clientWebSocket = ClientWebSocketProvider();
			if (clientWebSocket == null)
			{
				throw new ArgumentNullException("ClientWebSocketProvider", $"{ClientWebSocketProvider} returns a null");
			}
			WebSocketTransport webSocketTransport = new WebSocketTransport(options, clientWebSocket, Serializer);
			SetWebSocketHeaders(webSocketTransport);
			return webSocketTransport;
		}

		private void OnTransportCreated(ITransport transport)
		{
			if (Options.Proxy != null)
			{
				transport.SetProxy(Options.Proxy);
			}
			transport.OnReceived = OnMessageReceived;
			transport.OnError = OnErrorReceived;
		}

		private void SetWebSocketHeaders(ITransport transport)
		{
			if (Options.ExtraHeaders == null)
			{
				return;
			}
			foreach (KeyValuePair<string, string> extraHeader in Options.ExtraHeaders)
			{
				transport.AddHeader(extraHeader.Key, extraHeader.Value);
			}
		}

		private void SetHttpHeaders()
		{
			if (Options.ExtraHeaders == null)
			{
				return;
			}
			foreach (KeyValuePair<string, string> extraHeader in Options.ExtraHeaders)
			{
				HttpClient.AddHeader(extraHeader.Key, extraHeader.Value);
			}
		}

		private void ConnectInBackground(CancellationToken cancellationToken)
		{
			Task.Factory.StartNew((Func<Task>)async delegate
			{
				InitializeStatus();
				while (!cancellationToken.IsCancellationRequested)
				{
					TransportOptions options = NewTransportOptions();
					ITransport transport = NewTransport(Options.Transport, options);
					if (_attempts > 0)
					{
						this.OnReconnectAttempt.TryInvoke(this, _attempts);
					}
					try
					{
						await transport.ConnectAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
						Transport = transport;
						_transportCompletionSource.SetResult(result: true);
						break;
					}
					catch (Exception ex)
					{
						Exception e = ex;
						transport.Dispose();
						this.OnReconnectError.TryInvoke(this, e);
						if (await AttemptAsync())
						{
							_connBackgroundSource.SetResult(new ConnectionException($"Cannot connect to server '{ServerUri}'."));
							break;
						}
						if (!CanHandleException(e))
						{
							_connBackgroundSource.SetResult(new ConnectionException($"Cannot connect to server '{ServerUri}'", e));
							ExceptionDispatchInfo.Capture((ex as Exception) ?? throw ex).Throw();
						}
					}
				}
			}, cancellationToken);
		}

		private async Task UpgradeToWebSocket(IMessage openedMessage)
		{
			TransportOptions options = NewTransportOptions();
			options.OpenedMessage = openedMessage;
			for (int i = 0; i < 3; i++)
			{
				WebSocketTransport transport = (WebSocketTransport)NewTransport(TransportProtocol.WebSocket, options);
				using (CancellationTokenSource cts = new CancellationTokenSource(Options.ConnectionTimeout))
				{
					_ = 1;
					try
					{
						await transport.ConnectAsync(cts.Token).ConfigureAwait(continueOnCapturedContext: false);
						SerializedItem item = Serializer.SerializeUpgradeMessage();
						await transport.SendAsync(new List<SerializedItem> { item }, cts.Token).ConfigureAwait(continueOnCapturedContext: false);
						Transport.Dispose();
						Transport = transport;
						Options.Transport = TransportProtocol.WebSocket;
						transport.OnUpgraded();
					}
					catch (Exception innerException)
					{
						transport.Dispose();
						ConnectionException args = new ConnectionException("Upgrade to websocket failed", innerException);
						this.OnReconnectError.TryInvoke(this, args);
						continue;
					}
				}
				break;
			}
			_openedCompletionSource.SetResult(result: true);
		}

		private async Task<bool> AttemptAsync()
		{
			_attempts++;
			if (_attempts <= Options.ReconnectionAttempts)
			{
				if (_reconnectionDelay < (double)Options.ReconnectionDelayMax)
				{
					_reconnectionDelay += 2.0 * Options.RandomizationFactor;
				}
				if (_reconnectionDelay > (double)Options.ReconnectionDelayMax)
				{
					_reconnectionDelay = Options.ReconnectionDelayMax;
				}
				await Task.Delay((int)_reconnectionDelay);
				return false;
			}
			this.OnReconnectFailed.TryInvoke(this, EventArgs.Empty);
			return true;
		}

		private bool CanHandleException(Exception e)
		{
			if (_expectedExceptions.Contains(e.GetType()))
			{
				if (Options.Reconnection)
				{
					if (_attempts > Options.ReconnectionAttempts)
					{
						return false;
					}
					return true;
				}
				_backgroundException = e;
				return false;
			}
			_backgroundException = e;
			return false;
		}

		private async Task ConnectCore(CancellationToken cancellationToken)
		{
			await _connectingLock.WaitAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			try
			{
				if (!Connected)
				{
					ConnectInBackground(cancellationToken);
					cancellationToken.Register(_connBackgroundSource.SetCanceled);
					Exception ex = await Task.Run(async () => await _connBackgroundSource.Task.ConfigureAwait(continueOnCapturedContext: false), cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
					_connBackgroundSource = new TaskCompletionSource<Exception>();
					if (ex != null)
					{
						throw ex;
					}
				}
			}
			finally
			{
				_connectingLock.Release();
			}
		}

		public async Task ConnectAsync()
		{
			await ConnectCore(_connCts.Token).ConfigureAwait(continueOnCapturedContext: false);
			_connCts.Dispose();
			_connCts = new CancellationTokenSource();
		}

		public async Task ConnectAsync(CancellationToken cancellationToken)
		{
			await ConnectCore(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
		}

		private void PingHandler()
		{
			this.OnPing.TryInvoke(this, EventArgs.Empty);
		}

		private void PongHandler(IMessage msg)
		{
			this.OnPong.TryInvoke(this, msg.Duration);
		}

		private async Task OpenedHandler(IMessage msg)
		{
			await _transportCompletionSource.Task;
			_transportCompletionSource = new TaskCompletionSource<bool>();
			if (Options.AutoUpgrade && Options.Transport == TransportProtocol.Polling && msg.Upgrades.Contains("websocket"))
			{
				UpgradeToWebSocket(msg);
			}
			else
			{
				_openedCompletionSource.SetResult(result: true);
			}
		}

		private async Task ConnectedHandler(IMessage msg)
		{
			await _openedCompletionSource.Task;
			_openedCompletionSource = new TaskCompletionSource<bool>();
			Id = msg.Sid;
			Connected = true;
			this.OnConnected.TryInvoke(this, EventArgs.Empty);
			if (_attempts > 0)
			{
				this.OnReconnected.TryInvoke(this, _attempts);
			}
			_attempts = 0;
			_connBackgroundSource.SetResult(null);
		}

		private void DisconnectedHandler()
		{
			InvokeDisconnect(DisconnectReason.IOServerDisconnect);
		}

		private void EventMessageHandler(IMessage message)
		{
			SocketIOResponse response = new SocketIOResponse(message, this)
			{
				PacketId = message.Id
			};
			foreach (OnAnyHandler onAnyHandler in _onAnyHandlers)
			{
				onAnyHandler.TryInvoke(message.Event, response);
			}
			Func<SocketIOResponse, Task> value2;
			if (_eventActionHandlers.TryGetValue(message.Event, out var value))
			{
				value.TryInvoke(response);
			}
			else if (_eventFuncHandlers.TryGetValue(message.Event, out value2))
			{
				value2.TryInvoke(response);
			}
		}

		private void AckMessageHandler(IMessage message)
		{
			SocketIOResponse response = new SocketIOResponse(message, this);
			if (_ackActionHandlers.ContainsKey(message.Id))
			{
				_ackActionHandlers[message.Id].TryInvoke(response);
				_ackActionHandlers.Remove(message.Id);
			}
			else if (_ackFuncHandlers.ContainsKey(message.Id))
			{
				_ackFuncHandlers[message.Id].TryInvoke(response);
				_ackFuncHandlers.Remove(message.Id);
			}
		}

		private void ErrorMessageHandler(IMessage msg)
		{
			this.OnError.TryInvoke(this, msg.Error);
		}

		private void BinaryMessageHandler(IMessage message)
		{
			SocketIOResponse response = new SocketIOResponse(message, this)
			{
				PacketId = message.Id
			};
			foreach (OnAnyHandler onAnyHandler in _onAnyHandlers)
			{
				onAnyHandler.TryInvoke(message.Event, response);
			}
			if (_eventActionHandlers.TryGetValue(message.Event, out var value))
			{
				value.TryInvoke(response);
			}
		}

		private void BinaryAckMessageHandler(IMessage msg)
		{
			if (_ackActionHandlers.TryGetValue(msg.Id, out var value))
			{
				SocketIOResponse response = new SocketIOResponse(msg, this)
				{
					PacketId = msg.Id
				};
				value.TryInvoke(response);
			}
		}

		private void OnErrorReceived(Exception ex)
		{
			InvokeDisconnect(DisconnectReason.TransportClose);
		}

		private void OnMessageReceived(IMessage msg)
		{
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected I4, but got Unknown
			//IL_001d: 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_0042: Expected I4, but got Unknown
			try
			{
				MessageType type = msg.Type;
				switch ((int)type)
				{
				case 2:
					PingHandler();
					return;
				case 3:
					PongHandler(msg);
					return;
				case 0:
					OpenedHandler(msg);
					return;
				case 1:
					return;
				}
				switch (type - 40)
				{
				case 0:
					ConnectedHandler(msg);
					break;
				case 1:
					DisconnectedHandler();
					break;
				case 2:
					EventMessageHandler(msg);
					break;
				case 3:
					AckMessageHandler(msg);
					break;
				case 4:
					ErrorMessageHandler(msg);
					break;
				case 5:
					BinaryMessageHandler(msg);
					break;
				case 6:
					BinaryAckMessageHandler(msg);
					break;
				}
			}
			catch (Exception)
			{
			}
		}

		public async Task DisconnectAsync()
		{
			await InvokeDisconnect(DisconnectReason.IOClientDisconnect);
		}

		public void On(string eventName, Action<SocketIOResponse> callback)
		{
			if (_eventActionHandlers.ContainsKey(eventName))
			{
				_eventActionHandlers.Remove(eventName);
			}
			_eventActionHandlers.Add(eventName, callback);
		}

		public void On(string eventName, Func<SocketIOResponse, Task> callback)
		{
			if (_eventFuncHandlers.ContainsKey(eventName))
			{
				_eventFuncHandlers.Remove(eventName);
			}
			_eventFuncHandlers.Add(eventName, callback);
		}

		public void Off(string eventName)
		{
			if (_eventActionHandlers.ContainsKey(eventName))
			{
				_eventActionHandlers.Remove(eventName);
			}
			if (_eventFuncHandlers.ContainsKey(eventName))
			{
				_eventFuncHandlers.Remove(eventName);
			}
		}

		public void OnAny(OnAnyHandler handler)
		{
			if (handler != null)
			{
				_onAnyHandlers.Add(handler);
			}
		}

		public void PrependAny(OnAnyHandler handler)
		{
			if (handler != null)
			{
				_onAnyHandlers.Insert(0, handler);
			}
		}

		public void OffAny(OnAnyHandler handler)
		{
			if (handler != null)
			{
				_onAnyHandlers.Remove(handler);
			}
		}

		public OnAnyHandler[] ListenersAny()
		{
			return _onAnyHandlers.ToArray();
		}

		internal async Task ClientAckAsync(int packetId, CancellationToken cancellationToken, params object[] data)
		{
			List<SerializedItem> items = Serializer.Serialize(Options.EIO, packetId, Namespace, data);
			await Transport.SendAsync(items, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
		}

		public async Task EmitAsync(string eventName, params object[] data)
		{
			await EmitAsync(eventName, CancellationToken.None, data).ConfigureAwait(continueOnCapturedContext: false);
		}

		private async Task EmitAsync(string eventName, CancellationToken cancellationToken, params object[] data)
		{
			List<SerializedItem> items = Serializer.Serialize(Options.EIO, eventName, Namespace, data);
			await Transport.SendAsync(items, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
		}

		public async Task EmitAsync(string eventName, Action<SocketIOResponse> ack, params object[] data)
		{
			await EmitAsync(eventName, CancellationToken.None, ack, data).ConfigureAwait(continueOnCapturedContext: false);
		}

		public async Task EmitAsync(string eventName, Func<SocketIOResponse, Task> ack, params object[] data)
		{
			await EmitAsync(eventName, CancellationToken.None, ack, data).ConfigureAwait(continueOnCapturedContext: false);
		}

		private async Task EmitForAck(string eventName, int packetId, CancellationToken cancellationToken, params object[] data)
		{
			List<SerializedItem> items = Serializer.Serialize(Options.EIO, eventName, packetId, Namespace, data);
			await Transport.SendAsync(items, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
		}

		private async Task EmitAsync(string eventName, CancellationToken cancellationToken, Action<SocketIOResponse> ack, params object[] data)
		{
			_ = 1;
			try
			{
				await _packetIdLock.WaitAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
				_ackActionHandlers.Add(++_packetId, ack);
				await EmitForAck(eventName, _packetId, cancellationToken, data).ConfigureAwait(continueOnCapturedContext: false);
			}
			finally
			{
				_packetIdLock.Release();
			}
		}

		private async Task EmitAsync(string eventName, CancellationToken cancellationToken, Func<SocketIOResponse, Task> ack, params object[] data)
		{
			_ = 1;
			try
			{
				await _packetIdLock.WaitAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
				_ackFuncHandlers.Add(++_packetId, ack);
				await EmitForAck(eventName, _packetId, cancellationToken, data).ConfigureAwait(continueOnCapturedContext: false);
			}
			finally
			{
				_packetIdLock.Release();
			}
		}

		private async Task InvokeDisconnect(string reason)
		{
			_ = 1;
			try
			{
				await _disconnectingLock.WaitAsync();
				if (Connected)
				{
					try
					{
						await Transport.DisconnectAsync(CancellationToken.None).ConfigureAwait(continueOnCapturedContext: false);
					}
					catch (Exception)
					{
					}
					Connected = false;
					Id = null;
					this.OnDisconnected.TryInvoke(this, reason);
					if (reason != DisconnectReason.IOServerDisconnect && reason != DisconnectReason.IOClientDisconnect && Options.Reconnection)
					{
						ConnectInBackground(_connCts.Token);
					}
				}
			}
			finally
			{
				_disconnectingLock.Release();
			}
		}

		public void AddExpectedException(Type type)
		{
			if (!_expectedExceptions.Contains(type))
			{
				_expectedExceptions.Add(type);
			}
		}

		public void Dispose()
		{
			_connCts.TryDispose();
			Transport.TryDispose();
			_ackActionHandlers.Clear();
			_onAnyHandlers.Clear();
			_eventActionHandlers.Clear();
		}
	}
	public sealed class SocketIOOptions
	{
		private double _randomizationFactor;

		public string Path { get; set; }

		public TimeSpan ConnectionTimeout { get; set; }

		public IEnumerable<KeyValuePair<string, string>> Query { get; set; }

		public bool Reconnection { get; set; }

		public double ReconnectionDelay { get; set; }

		public int ReconnectionDelayMax { get; set; }

		public int ReconnectionAttempts { get; set; }

		public double RandomizationFactor
		{
			get
			{
				return _randomizationFactor;
			}
			set
			{
				if (value >= 0.0 && value <= 1.0)
				{
					_randomizationFactor = value;
					return;
				}
				throw new ArgumentException("RandomizationFactor should be greater than or equal to 0.0, and less than 1.0.");
			}
		}

		public Dictionary<string, string> ExtraHeaders { get; set; }

		public TransportProtocol Transport { get; set; }

		public EngineIO EIO { get; set; }

		public bool AutoUpgrade { get; set; }

		public object Auth { get; set; }

		public IWebProxy Proxy { get; set; }

		public RemoteCertificateValidationCallback RemoteCertificateValidationCallback { get; set; }

		public SocketIOOptions()
		{
			RandomizationFactor = 0.5;
			ReconnectionDelay = 1000.0;
			ReconnectionDelayMax = 5000;
			ReconnectionAttempts = int.MaxValue;
			Path = "/socket.io";
			ConnectionTimeout = TimeSpan.FromSeconds(20.0);
			Reconnection = true;
			Transport = TransportProtocol.Polling;
			EIO = (EngineIO)4;
			AutoUpgrade = true;
		}
	}
	public class SocketIOResponse
	{
		private readonly IMessage _message;

		private readonly SocketIO _socketIO;

		public List<byte[]> InComingBytes => _message.ReceivedBinary;

		public int PacketId { get; set; }

		public SocketIOResponse(IMessage message, SocketIO socket)
		{
			_message = message;
			_socketIO = socket;
			PacketId = -1;
		}

		public T GetValue<T>(int index = 0)
		{
			return _socketIO.Serializer.Deserialize<T>(_message, index);
		}

		public override string ToString()
		{
			return _socketIO.Serializer.MessageToJson(_message);
		}

		public async Task CallbackAsync(params object[] data)
		{
			await _socketIO.ClientAckAsync(PacketId, CancellationToken.None, data).ConfigureAwait(continueOnCapturedContext: false);
		}

		public async Task CallbackAsync(CancellationToken cancellationToken, params object[] data)
		{
			await _socketIO.ClientAckAsync(PacketId, cancellationToken, data).ConfigureAwait(continueOnCapturedContext: false);
		}
	}
}
namespace SocketIOClient.UriConverters
{
	public static class UriConverter
	{
		public static Uri GetServerUri(bool ws, Uri serverUri, EngineIO eio, string path, IEnumerable<KeyValuePair<string, string>> queryParams)
		{
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected I4, but got Unknown
			StringBuilder stringBuilder = new StringBuilder();
			if (serverUri.Scheme == "https" || serverUri.Scheme == "wss")
			{
				stringBuilder.Append(ws ? "wss://" : "https://");
			}
			else
			{
				if (!(serverUri.Scheme == "http") && !(serverUri.Scheme == "ws"))
				{
					throw new ArgumentException("Only supports 'http, https, ws, wss' protocol");
				}
				stringBuilder.Append(ws ? "ws://" : "http://");
			}
			stringBuilder.Append(serverUri.Host);
			if (!serverUri.IsDefaultPort)
			{
				stringBuilder.Append(":").Append(serverUri.Port);
			}
			if (string.IsNullOrEmpty(path))
			{
				stringBuilder.Append("/socket.io");
			}
			else
			{
				stringBuilder.Append(path);
			}
			stringBuilder.Append("/?EIO=").Append((int)eio).Append("&transport=")
				.Append(ws ? "websocket" : "polling");
			if (queryParams != null)
			{
				foreach (KeyValuePair<string, string> queryParam in queryParams)
				{
					stringBuilder.Append('&').Append(queryParam.Key).Append('=')
						.Append(queryParam.Value);
				}
			}
			return new Uri(stringBuilder.ToString());
		}
	}
}
namespace SocketIOClient.Transport
{
	public abstract class BaseTransport : ITransport, IDisposable
	{
		private DateTime _pingTime;

		private static readonly HashSet<string> DefaultNamespaces = new HashSet<string>
		{
			null,
			string.Empty,
			"/"
		};

		protected TransportOptions Options { get; }

		private ISerializer Serializer { get; }

		public Action<IMessage> OnReceived { get; set; }

		protected abstract TransportProtocol Protocol { get; }

		protected CancellationTokenSource PingTokenSource { get; set; }

		public Action<Exception> OnError { get; set; }

		protected BaseTransport(TransportOptions options, ISerializer serializer)
		{
			Options = options;
			Serializer = serializer;
			base..ctor();
		}

		public abstract Task SendAsync(IList<SerializedItem> items, CancellationToken cancellationToken);

		protected virtual async Task OpenAsync(IMessage message)
		{
			Options.OpenedMessage = message;
			if ((int)Options.EIO != 3 || !string.IsNullOrEmpty(Options.Namespace))
			{
				SerializedItem item = Serializer.SerializeConnectedMessage(Options.EIO, Options.Namespace, Options.Auth, Options.Query);
				await SendAsync(new List<SerializedItem> { item }, CancellationToken.None).ConfigureAwait(continueOnCapturedContext: false);
			}
		}

		protected void StartPing(CancellationToken cancellationToken)
		{
			Task.Factory.StartNew((Func<Task>)async delegate
			{
				while (!cancellationToken.IsCancellationRequested)
				{
					await Task.Delay(Options.OpenedMessage.PingInterval, cancellationToken);
					try
					{
						using (CancellationTokenSource cts = new CancellationTokenSource(Options.OpenedMessage.PingTimeout))
						{
							await SendAsync(new List<SerializedItem> { Serializer.SerializePingMessage() }, cts.Token).ConfigureAwait(continueOnCapturedContext: false);
						}
						_pingTime = DateTime.Now;
						OnReceived.TryInvoke(Serializer.NewMessage((MessageType)2));
					}
					catch (Exception arg)
					{
						OnError.TryInvoke(arg);
						break;
					}
				}
			}, TaskCreationOptions.LongRunning);
		}

		protected abstract Task ConnectCoreAsync(Uri uri, CancellationToken cancellationToken);

		public async Task ConnectAsync(CancellationToken cancellationToken)
		{
			Uri uri = GetConnectionUri();
			try
			{
				await ConnectCoreAsync(uri, cancellationToken);
			}
			catch (Exception innerException)
			{
				throw new TransportException($"Could not connect to '{uri}'", innerException);
			}
		}

		public abstract Task DisconnectAsync(CancellationToken cancellationToken);

		public abstract void AddHeader(string key, string val);

		public abstract void SetProxy(IWebProxy proxy);

		public virtual void Dispose()
		{
			if (PingTokenSource != null && !PingTokenSource.IsCancellationRequested)
			{
				PingTokenSource.Cancel();
				PingTokenSource.Dispose();
			}
		}

		private async Task<bool> HandleEio3Messages(IMessage message)
		{
			if ((int)Options.EIO != 3)
			{
				return false;
			}
			if ((int)message.Type == 3)
			{
				message.Duration = DateTime.Now - _pingTime;
			}
			else if ((int)message.Type == 40)
			{
				int ms = 0;
				while (Options.OpenedMessage == null)
				{
					await Task.Delay(100);
					ms += 100;
					if (!((double)ms <= Options.ConnectionTimeout.TotalMilliseconds))
					{
						OnError.TryInvoke(new TimeoutException());
						return true;
					}
				}
				message.Sid = Options.OpenedMessage.Sid;
				if (!(message.Namespace == Options.Namespace) && (!DefaultNamespaces.Contains(Options.Namespace) || !DefaultNamespaces.Contains(message.Namespace)))
				{
					return true;
				}
				PingTokenSource?.Cancel();
				PingTokenSource = new CancellationTokenSource();
				StartPing(PingTokenSource.Token);
			}
			return false;
		}

		private async Task HandlePingMessage(IMessage message)
		{
			if ((int)Options.EIO == 3 || (int)message.Type != 2)
			{
				return;
			}
			_pingTime = DateTime.Now;
			try
			{
				await SendAsync(new List<SerializedItem> { Serializer.SerializePongMessage() }, CancellationToken.None).ConfigureAwait(continueOnCapturedContext: false);
				IMessage val = Serializer.NewMessage((MessageType)3);
				val.Duration = DateTime.Now - _pingTime;
				OnReceived.TryInvoke(val);
			}
			catch (Exception arg)
			{
				OnError.TryInvoke(arg);
			}
		}

		protected async Task OnTextReceived(string text)
		{
			IMessage message = Serializer.Deserialize(Options.EIO, text);
			await HandleMessage(message).ConfigureAwait(continueOnCapturedContext: false);
		}

		protected async Task OnBinaryReceived(byte[] bytes)
		{
			IMessage message = Serializer.Deserialize(Options.EIO, bytes);
			await HandleMessage(message).ConfigureAwait(continueOnCapturedContext: false);
		}

		private async Task HandleMessage(IMessage message)
		{
			if (message != null)
			{
				if ((int)message.Type == 0)
				{
					await OpenAsync(message).ConfigureAwait(continueOnCapturedContext: false);
				}
				if (!(await HandleEio3Messages(message)))
				{
					OnReceived.TryInvoke(message);
					await HandlePingMessage(message).ConfigureAwait(continueOnCapturedContext: false);
				}
			}
		}

		private Uri GetConnectionUri()
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected I4, but got Unknown
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(GetConnectionUriSchema()).Append("://").Append(Options.ServerUri.Host);
			if (!Options.ServerUri.IsDefaultPort)
			{
				stringBuilder.Append(':').Append(Options.ServerUri.Port);
			}
			stringBuilder.Append(string.IsNullOrEmpty(Options.Path) ? "/socket.io" : Options.Path);
			stringBuilder.Append("/?EIO=").Append((int)Options.EIO).Append("&transport=")
				.Append(Protocol.ToString().ToLower());
			if (Options.OpenedMessage != null)
			{
				stringBuilder.Append("&sid=").Append(Options.OpenedMessage.Sid);
			}
			foreach (KeyValuePair<string, string> item in Options.Query)
			{
				stringBuilder.Append('&').Append(item.Key).Append('=')
					.Append(item.Value);
			}
			return new Uri(stringBuilder.ToString());
		}

		private string GetConnectionUriSchema()
		{
			switch (Options.ServerUri.Scheme)
			{
			case "https":
			case "wss":
				return (Protocol == TransportProtocol.Polling) ? "https" : "wss";
			case "http":
			case "ws":
				return (Protocol == TransportProtocol.Polling) ? "http" : "ws";
			default:
				throw new ArgumentException("Only supports 'http, https, ws, wss' protocol");
			}
		}
	}
	public interface ITransport : IDisposable
	{
		Action<IMessage> OnReceived { get; set; }

		Action<Exception> OnError { get; set; }

		Task SendAsync(IList<SerializedItem> items, CancellationToken cancellationToken);

		Task ConnectAsync(CancellationToken cancellationToken);

		Task DisconnectAsync(CancellationToken cancellationToken);

		void AddHeader(string key, string val);

		void SetProxy(IWebProxy proxy);
	}
	public class TransportException : Exception
	{
		public TransportException()
		{
		}

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

		public TransportException(string message, Exception innerException)
			: base(message, innerException)
		{
		}
	}
	public enum TransportMessageType
	{
		Text,
		Binary,
		Close
	}
	public class TransportOptions
	{
		public EngineIO EIO { get; set; }

		public IEnumerable<KeyValuePair<string, string>> Query { get; set; }

		public object Auth { get; set; }

		public TimeSpan ConnectionTimeout { get; set; }

		public Uri ServerUri { get; set; }

		public string Path { get; set; }

		public bool AutoUpgrade { get; set; }

		public IMessage OpenedMessage { get; set; }

		public string Namespace { get; set; }
	}
	public enum TransportProtocol
	{
		Polling,
		WebSocket
	}
}
namespace SocketIOClient.Transport.WebSockets
{
	public static class ChunkSize
	{
		public const int Size1K = 1024;

		public const int Size8K = 8192;

		public const int Size16K = 16384;

		public const int Size32K = 32768;
	}
	public class DefaultClientWebSocket : IClientWebSocket, IDisposable
	{
		private readonly ClientWebSocket _ws;

		public WebSocketState State => (WebSocketState)_ws.State;

		public DefaultClientWebSocket(RemoteCertificateValidationCallback remoteCertificateValidationCallback)
		{
			_ws = new ClientWebSocket();
		}

		public async Task ConnectAsync(Uri uri, CancellationToken cancellationToken)
		{
			await _ws.ConnectAsync(uri, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
		}

		public async Task DisconnectAsync(CancellationToken cancellationToken)
		{
			await _ws.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
		}

		public async Task SendAsync(byte[] bytes, TransportMessageType type, bool endOfMessage, CancellationToken cancellationToken)
		{
			WebSocketMessageType messageType = WebSocketMessageType.Text;
			if (type == TransportMessageType.Binary)
			{
				messageType = WebSocketMessageType.Binary;
			}
			await _ws.SendAsync(new ArraySegment<byte>(bytes), messageType, endOfMessage, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
		}

		public async Task<WebSocketReceiveResult> ReceiveAsync(int bufferSize, CancellationToken cancellationToken)
		{
			byte[] buffer = new byte[bufferSize];
			System.Net.WebSockets.WebSocketReceiveResult webSocketReceiveResult = await _ws.ReceiveAsync(new ArraySegment<byte>(buffer), cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			return new WebSocketReceiveResult
			{
				Count = webSocketReceiveResult.Count,
				MessageType = (TransportMessageType)webSocketReceiveResult.MessageType,
				EndOfMessage = webSocketReceiveResult.EndOfMessage,
				Buffer = buffer
			};
		}

		public void AddHeader(string key, string val)
		{
			_ws.Options.SetRequestHeader(key, val);
		}

		public void SetProxy(IWebProxy proxy)
		{
			_ws.Options.Proxy = proxy;
		}

		public void Dispose()
		{
			_ws.Dispose();
		}
	}
	public interface IClientWebSocket : IDisposable
	{
		WebSocketState State { get; }

		Task ConnectAsync(Uri uri, CancellationToken cancellationToken);

		Task DisconnectAsync(CancellationToken cancellationToken);

		Task SendAsync(byte[] bytes, TransportMessageType type, bool endOfMessage, CancellationToken cancellationToken);

		Task<WebSocketReceiveResult> ReceiveAsync(int bufferSize, CancellationToken cancellationToken);

		void AddHeader(string key, string val);

		void SetProxy(IWebProxy proxy);
	}
	public class WebSocketReceiveResult
	{
		public int Count { get; set; }

		public bool EndOfMessage { get; set; }

		public TransportMessageType MessageType { get; set; }

		public byte[] Buffer { get; set; }
	}
	public enum WebSocketState
	{
		None,
		Connecting,
		Open,
		CloseSent,
		CloseReceived,
		Closed,
		Aborted
	}
	public class WebSocketTransport : BaseTransport
	{
		private readonly IClientWebSocket _ws;

		private readonly SemaphoreSlim _sendLock;

		private readonly CancellationTokenSource _listenCancellation;

		private int _sendChunkSize = 8192;

		private int _receiveChunkSize = 8192;

		private bool _dirty;

		protected override TransportProtocol Protocol => TransportProtocol.WebSocket;

		public WebSocketTransport(TransportOptions options, IClientWebSocket ws, ISerializer serializer)
			: base(options, serializer)
		{
			_ws = ws;
			_sendLock = new SemaphoreSlim(1, 1);
			_listenCancellation = new CancellationTokenSource();
		}

		private async Task SendAsync(TransportMessageType type, byte[] bytes, CancellationToken cancellationToken)
		{
			if (type == TransportMessageType.Binary && (int)base.Options.EIO == 3)
			{
				byte[] array = new byte[bytes.Length + 1];
				array[0] = 4;
				Buffer.BlockCopy(bytes, 0, array, 1, bytes.Length);
				bytes = array;
			}
			int pages = (int)Math.Ceiling((double)bytes.Length * 1.0 / (double)_sendChunkSize);
			for (int i = 0; i < pages; i++)
			{
				int num = i * _sendChunkSize;
				int num2 = _sendChunkSize;
				if (num + num2 > bytes.Length)
				{
					num2 = bytes.Length - num;
				}
				byte[] array2 = new byte[num2];
				Buffer.BlockCopy(bytes, num, array2, 0, array2.Length);
				bool endOfMessage = pages - 1 == i;
				await _ws.SendAsync(array2, type, endOfMessage, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			}
		}

		private void Listen(CancellationToken cancellationToken)
		{
			Task.Factory.StartNew((Func<Task>)async delegate
			{
				while (!cancellationToken.IsCancellationRequested)
				{
					byte[] binary = new byte[_receiveChunkSize];
					int count = 0;
					WebSocketReceiveResult webSocketReceiveResult = null;
					while (_ws.State == WebSocketState.Open)
					{
						try
						{
							webSocketReceiveResult = await _ws.ReceiveAsync(_receiveChunkSize, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
							if (binary.Length - count < webSocketReceiveResult.Count)
							{
								Array.Resize(ref binary, binary.Length + webSocketReceiveResult.Count);
							}
							Buffer.BlockCopy(webSocketReceiveResult.Buffer, 0, binary, count, webSocketReceiveResult.Count);
							count += webSocketReceiveResult.Count;
							if (webSocketReceiveResult.EndOfMessage)
							{
								break;
							}
						}
						catch (Exception arg)
						{
							base.OnError.TryInvoke(arg);
							return;
						}
					}
					if (webSocketReceiveResult == null)
					{
						break;
					}
					try
					{
						switch (webSocketReceiveResult.MessageType)
						{
						case TransportMessageType.Text:
						{
							string @string = Encoding.UTF8.GetString(binary, 0, count);
							await OnTextReceived(@string);
							break;
						}
						case TransportMessageType.Binary:
						{
							byte[] array;
							if ((int)base.Options.EIO == 3)
							{
								array = new byte[count - 1];
								Buffer.BlockCopy(binary, 1, array, 0, array.Length);
							}
							else
							{
								array = new byte[count];
								Buffer.BlockCopy(binary, 0, array, 0, array.Length);
							}
							await OnBinaryReceived(array);
							break;
						}
						case TransportMessageType.Close:
							base.OnError.TryInvoke(new TransportException("Received a Close message"));
							break;
						}
					}
					catch (Exception arg2)
					{
						base.OnError.TryInvoke(arg2);
						break;
					}
				}
			}, cancellationToken);
		}

		protected override async Task ConnectCoreAsync(Uri uri, CancellationToken cancellationToken)
		{
			await _ws.ConnectAsync(uri, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			Listen(_listenCancellation.Token);
		}

		public override async Task DisconnectAsync(CancellationToken cancellationToken)
		{
			await _ws.DisconnectAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
		}

		public override async Task SendAsync(IList<SerializedItem> items, CancellationToken cancellationToken)
		{
			_ = 2;
			try
			{
				await _sendLock.WaitAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
				if ((int)items[0].Type == 0)
				{
					byte[] bytes = Encoding.UTF8.GetBytes(items[0].Text);
					await SendAsync(TransportMessageType.Text, bytes, cancellationToken);
				}
				List<byte[]> list = EnumerableExtensions.AllBinary((IEnumerable<SerializedItem>)items);
				if (list.Count <= 0)
				{
					return;
				}
				foreach (byte[] item in list)
				{
					await SendAsync(TransportMessageType.Binary, item, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
				}
			}
			finally
			{
				_sendLock.Release();
			}
		}

		public void OnUpgraded()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			if ((int)base.Options.EIO == 3)
			{
				base.PingTokenSource?.Cancel();
				base.PingTokenSource = new CancellationTokenSource();
				StartPing(base.PingTokenSource.Token);
			}
		}

		public async Task ChangeSendChunkSizeAsync(int size)
		{
			try
			{
				await _sendLock.WaitAsync().ConfigureAwait(continueOnCapturedContext: false);
				_sendChunkSize = size;
			}
			finally
			{
				_sendLock.Release();
			}
		}

		public async Task ChangeReceiveChunkSizeAsync(int size)
		{
			try
			{
				await _sendLock.WaitAsync().ConfigureAwait(continueOnCapturedContext: false);
				_sendChunkSize = size;
			}
			finally
			{
				_sendLock.Release();
			}
		}

		public override void AddHeader(string key, string val)
		{
			if (_dirty)
			{
				throw new InvalidOperationException("Unable to add header after connecting");
			}
			_ws.AddHeader(key, val);
		}

		public override void SetProxy(IWebProxy proxy)
		{
			if (_dirty)
			{
				throw new InvalidOperationException("Unable to set proxy after connecting");
			}
			_ws.SetProxy(proxy);
		}

		public override void Dispose()
		{
			base.Dispose();
			_sendLock.Dispose();
		}
	}
}
namespace SocketIOClient.Transport.Http
{
	public class DefaultHttpClient : IHttpClient, IDisposable
	{
		private readonly HttpClientHandler _handler;

		private readonly HttpClient _httpClient;

		private static readonly HashSet<string> allowedHeaders = new HashSet<string> { "user-agent" };

		public DefaultHttpClient(RemoteCertificateValidationCallback remoteCertificateValidationCallback)
		{
			_handler = new HttpClientHandler();
			if (remoteCertificateValidationCallback != null)
			{
				_handler.ClientCertificateOptions = ClientCertificateOption.Manual;
				_handler.ServerCertificateCustomValidationCallback = (HttpRequestMessage req, X509Certificate2 cert, X509Chain chain, SslPolicyErrors policyErrors) => remoteCertificateValidationCallback(req, cert, chain, policyErrors);
			}
			_httpClient = new HttpClient(_handler);
		}

		public void AddHeader(string name, string value)
		{
			if (_httpClient.DefaultRequestHeaders.Contains(name))
			{
				_httpClient.DefaultRequestHeaders.Remove(name);
			}
			if (allowedHeaders.Contains(name.ToLower()))
			{
				_httpClient.DefaultRequestHeaders.TryAddWithoutValidation(name, value);
			}
			else
			{
				_httpClient.DefaultRequestHeaders.Add(name, value);
			}
		}

		public IEnumerable<string> GetHeaderValues(string name)
		{
			return _httpClient.DefaultRequestHeaders.GetValues(name);
		}

		public void SetProxy(IWebProxy proxy)
		{
			_handler.Proxy = proxy;
		}

		public Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
		{
			return _httpClient.SendAsync(request, cancellationToken);
		}

		public Task<HttpResponseMessage> PostAsync(string requestUri, HttpContent content, CancellationToken cancellationToken)
		{
			return _httpClient.PostAsync(requestUri, content, cancellationToken);
		}

		public Task<string> GetStringAsync(Uri requestUri)
		{
			return _httpClient.GetStringAsync(requestUri);
		}

		public void Dispose()
		{
			_httpClient.Dispose();
			_handler.Dispose();
		}
	}
	public class Eio3HttpPollingHandler : HttpPollingHandler
	{
		public Eio3HttpPollingHandler(IHttpClient adapter)
			: base(adapter)
		{
		}

		public override async Task PostAsync(string uri, IEnumerable<byte[]> bytes, CancellationToken cancellationToken)
		{
			List<byte> list = new List<byte>();
			foreach (byte[] @byte in bytes)
			{
				list.Add(1);
				IEnumerable<byte> collection = from x in SplitInt(@byte.Length + 1)
					select (byte)x;
				list.AddRange(collection);
				list.Add(byte.MaxValue);
				list.Add(4);
				list.AddRange(@byte);
			}
			ByteArrayContent byteArrayContent = new ByteArrayContent(list.ToArray());
			byteArrayContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
			await base.HttpClient.PostAsync(HttpPollingHandler.AppendRandom(uri), byteArrayContent, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
		}

		private static List<int> SplitInt(int number)
		{
			List<int> list = new List<int>();
			while (number > 0)
			{
				list.Add(number % 10);
				number /= 10;
			}
			list.Reverse();
			return list;
		}

		protected override async Task ProduceText(string text)
		{
			int num = 0;
			do
			{
				int index = text.IndexOf(':', num);
				if (index != -1 && int.TryParse(text.Substring(num, index - num), out var length))
				{
					string arg = text.Substring(index + 1, length);
					await base.OnTextReceived.TryInvokeAsync(arg);
					num = index + length + 1;
					continue;
				}
				break;
			}
			while (num < text.Length);
		}

		public override async Task PostAsync(string uri, string content, CancellationToken cancellationToken)
		{
			if (!string.IsNullOrEmpty(content))
			{
				content = content.Length + ":" + content;
				await base.PostAsync(uri, content, cancellationToken);
			}
		}
	}
	public class Eio4HttpPollingHandler : HttpPollingHandler
	{
		private const char Separator = '\u001e';

		public Eio4HttpPollingHandler(IHttpClient adapter)
			: base(adapter)
		{
		}

		public override async Task PostAsync(string uri, IEnumerable<byte[]> bytes, CancellationToken cancellationToken)
		{
			StringBuilder stringBuilder = new StringBuilder();
			foreach (byte[] @byte in bytes)
			{
				stringBuilder.Append('b').Append(Convert.ToBase64String(@byte)).Append('\u001e');
			}
			if (stringBuilder.Length != 0)
			{
				string content = stringBuilder.ToString().TrimEnd(new char[1] { '\u001e' });
				await PostAsync(uri, content, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			}
		}

		protected override async Task ProduceText(string text)
		{
			string[] array = text.Split(new char[1] { '\u001e' }, StringSplitOptions.RemoveEmptyEntries);
			string[] array2 = array;
			foreach (string text2 in array2)
			{
				if (text2[0] == 'b')
				{
					byte[] bytes = Convert.FromBase64String(text2.Substring(1));
					await OnBytes(bytes).ConfigureAwait(continueOnCapturedContext: false);
				}
				else
				{
					await base.OnTextReceived.TryInvokeAsync(text2).ConfigureAwait(continueOnCapturedContext: false);
				}
			}
		}
	}
	public abstract class HttpPollingHandler : IHttpPollingHandler
	{
		protected IHttpClient HttpClient { get; }

		public Func<string, Task> OnTextReceived { get; set; }

		public Func<byte[], Task> OnBytesReceived { get; set; }

		protected HttpPollingHandler(IHttpClient adapter)
		{
			HttpClient = adapter ?? throw new ArgumentNullException("adapter");
		}

		public void AddHeader(string key, string val)
		{
			HttpClient.AddHeader(key, val);
		}

		public void SetProxy(IWebProxy proxy)
		{
			HttpClient.SetProxy(proxy);
		}

		protected static string AppendRandom(string uri)
		{
			return uri + "&t=" + DateTimeOffset.Now.ToUnixTimeSeconds();
		}

		public async Task GetAsync(string uri, CancellationToken cancellationToken)
		{
			HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, AppendRandom(uri));
			HttpResponseMessage httpResponseMessage = await HttpClient.SendAsync(request, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			if (!httpResponseMessage.IsSuccessStatusCode)
			{
				throw new HttpRequestException($"Response status code does not indicate success: {httpResponseMessage.StatusCode}");
			}
			await ProduceMessageAsync(httpResponseMessage).ConfigureAwait(continueOnCapturedContext: false);
		}

		public async Task SendAsync(HttpRequestMessage req, CancellationToken cancellationToken)
		{
			HttpResponseMessage httpResponseMessage = await HttpClient.SendAsync(req, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			if (!httpResponseMessage.IsSuccessStatusCode)
			{
				throw new HttpRequestException($"Response status code does not indicate success: {httpResponseMessage.StatusCode}");
			}
			await ProduceMessageAsync(httpResponseMessage).ConfigureAwait(continueOnCapturedContext: false);
		}

		public virtual async Task PostAsync(string uri, string content, CancellationToken cancellationToken)
		{
			StringContent content2 = new StringContent(content);
			await ProduceMessageAsync(await HttpClient.PostAsync(AppendRandom(uri), content2, cancellationToken).ConfigureAwait(continueOnCapturedContext: false)).ConfigureAwait(continueOnCapturedContext: false);
		}

		public abstract Task PostAsync(string uri, IEnumerable<byte[]> bytes, CancellationToken cancellationToken);

		private async Task ProduceMessageAsync(HttpResponseMessage resMsg)
		{
			if (resMsg.Content.Headers.ContentType.MediaType == "application/octet-stream")
			{
				await ProduceBytes(await resMsg.Content.ReadAsByteArrayAsync().ConfigureAwait(continueOnCapturedContext: false)).ConfigureAwait(continueOnCapturedContext: false);
			}
			else
			{
				await ProduceText(await resMsg.Content.ReadAsStringAsync().ConfigureAwait(continueOnCapturedContext: false)).ConfigureAwait(continueOnCapturedContext: false);
			}
		}

		protected abstract Task ProduceText(string text);

		protected async Task OnBytes(byte[] bytes)
		{
			await OnBytesReceived.TryInvokeAsync(bytes);
		}

		private async Task ProduceBytes(byte[] bytes)
		{
			int k = 0;
			while (bytes.Length > k + 4)
			{
				byte b = bytes[k];
				StringBuilder stringBuilder = new StringBuilder();
				for (k++; bytes[k] != byte.MaxValue; k++)
				{
					stringBuilder.Append(bytes[k]);
				}
				k++;
				int length = int.Parse(stringBuilder.ToString());
				switch (b)
				{
				case 0:
				{
					byte[] array2 = new byte[length];
					Buffer.BlockCopy(bytes, k, array2, 0, array2.Length);
					await OnTextReceived.TryInvokeAsync<string>(Encoding.UTF8.GetString(array2));
					break;
				}
				case 1:
				{
					byte[] array = new byte[length - 1];
					Buffer.BlockCopy(bytes, k + 1, array, 0, array.Length);
					await OnBytes(array);
					break;
				}
				}
				k += length;
			}
		}

		public static IHttpPollingHandler CreateHandler(EngineIO eio, IHttpClient adapter)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			if ((int)eio == 3)
			{
				return new Eio3HttpPollingHandler(adapter);
			}
			return new Eio4HttpPollingHandler(adapter);
		}
	}
	public class HttpTransport : BaseTransport
	{
		private string _httpUri;

		private readonly SemaphoreSlim _sendLock;

		private CancellationTokenSource _pollingTokenSource;

		private readonly IHttpPollingHandler _pollingHandler;

		protected override TransportProtocol Protocol => TransportProtocol.Polling;

		public HttpTransport(TransportOptions options, IHttpPollingHandler pollingHandler, ISerializer serializer)
			: base(options, serializer)
		{
			_pollingHandler = pollingHandler ?? throw new ArgumentNullException("pollingHandler");
			_pollingHandler.OnTextReceived = base.OnTextReceived;
			_pollingHandler.OnBytesReceived = base.OnBinaryReceived;
			_sendLock = new SemaphoreSlim(1, 1);
		}

		private void StartPolling(CancellationToken cancellationToken)
		{
			Task.Factory.StartNew((Func<Task>)async delegate
			{
				while (!cancellationToken.IsCancellationRequested)
				{
					try
					{
						await _pollingHandler.GetAsync(_httpUri, CancellationToken.None).ConfigureAwait(continueOnCapturedContext: false);
					}
					catch (Exception obj)
					{
						base.OnError(obj);
						break;
					}
				}
			}, TaskCreationOptions.LongRunning);
		}

		protected override async Task ConnectCoreAsync(Uri uri, CancellationToken cancellationToken)
		{
			HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Get, uri);
			_httpUri = uri.ToString();
			await _pollingHandler.SendAsync(req, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
		}

		public override Task DisconnectAsync(CancellationToken cancellationToken)
		{
			_pollingTokenSource.Cancel();
			if (base.PingTokenSource != null)
			{
				base.PingTokenSource.Cancel();
			}
			return Task.CompletedTask;
		}

		public override void AddHeader(string key, string val)
		{
			_pollingHandler.AddHeader(key, val);
		}

		public override void SetProxy(IWebProxy proxy)
		{
			_pollingHandler.SetProxy(proxy);
		}

		public override void Dispose()
		{
			base.Dispose();
			_pollingTokenSource.TryCancel();
			_pollingTokenSource.TryDispose();
		}

		public override async Task SendAsync(IList<SerializedItem> items, CancellationToken cancellationToken)
		{
			if (items.Count == 0)
			{
				return;
			}
			try
			{
				await _sendLock.WaitAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
				if ((int)items[0].Type == 0)
				{
					await _pollingHandler.PostAsync(_httpUri, items[0].Text, cancellationToken);
				}
				List<byte[]> list = EnumerableExtensions.AllBinary((IEnumerable<SerializedItem>)items);
				if (list.Count > 0)
				{
					await _pollingHandler.PostAsync(_httpUri, list, cancellationToken);
				}
			}
			finally
			{
				_sendLock.Release();
			}
		}

		protected override async Task OpenAsync(IMessage message)
		{
			_httpUri = _httpUri + "&sid=" + message.Sid;
			_pollingTokenSource = new CancellationTokenSource();
			if (!base.Options.AutoUpgrade || !message.Upgrades.Contains("websocket"))
			{
				StartPolling(_pollingTokenSource.Token);
			}
			await base.OpenAsync(message);
		}
	}
	public interface IHttpClient : IDisposable
	{
		void AddHeader(string name, string value);

		void SetProxy(IWebProxy proxy);

		Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken);

		Task<HttpResponseMessage> PostAsync(string requestUri, HttpContent content, CancellationToken cancellationToken);

		Task<string> GetStringAsync(Uri requestUri);
	}
	public interface IHttpPollingHandler
	{
		Func<string, Task> OnTextReceived { get; set; }

		Func<byte[], Task> OnBytesReceived { get; set; }

		Task GetAsync(string uri, CancellationToken cancellationToken);

		Task SendAsync(HttpRequestMessage req, CancellationToken cancellationToken);

		Task PostAsync(string uri, string content, CancellationToken cancellationToken);

		Task PostAsync(string uri, IEnumerable<byte[]> bytes, CancellationToken cancellationToken);

		void AddHeader(string key, string val);

		void SetProxy(IWebProxy proxy);
	}
}
namespace SocketIOClient.Extensions
{
	internal static class CancellationTokenSourceExtensions
	{
		public static void TryDispose(this CancellationTokenSource cts)
		{
			cts?.Dispose();
		}

		public static void TryCancel(this CancellationTokenSource cts)
		{
			if (cts != null && !cts.IsCancellationRequested)
			{
				cts.Cancel();
			}
		}

		public static CancellationTokenSourceWrapper Renew(this CancellationTokenSourceWrapper cts)
		{
			cts?.Dispose();
			return new CancellationTokenSourceWrapper(new CancellationTokenSource());
		}
	}
	internal class CancellationTokenSourceWrapper : IDisposable
	{
		[CompilerGenerated]
		private CancellationTokenSource <cts>P;

		private bool _cancelled;

		private bool _disposed;

		public CancellationToken Token => <cts>P.Token;

		public bool IsCancellationRequested => <cts>P.IsCancellationRequested;

		public CancellationTokenSourceWrapper(CancellationTokenSource cts)
		{
			<cts>P = cts;
			base..ctor();
		}

		private void Cancel()
		{
			if (!_cancelled)
			{
				<cts>P.Cancel();
				_cancelled = true;
			}
		}

		private void DisposeInternal()
		{
			if (!_disposed)
			{
				<cts>P.Dispose();
				_disposed = true;
			}
		}

		public void Dispose()
		{
			Cancel();
			DisposeInternal();
		}
	}
	internal static class DisposableExtensions
	{
		public static void TryDispose(this IDisposable disposable)
		{
			disposable?.Dispose();
		}
	}
	internal static class EventHandlerExtensions
	{
		public static void TryInvoke<T>(this EventHandler<T> handler, object sender, T args)
		{
			handler?.Invoke(sender, args);
		}

		public static void TryInvoke(this EventHandler handler, object sender, EventArgs args)
		{
			handler?.Invoke(sender, args);
		}

		public static void TryInvoke<T>(this Action<T> action, T arg1)
		{
			action?.Invoke(arg1);
		}

		public static async Task TryInvokeAsync<T>(this Func<T, Task> func, T arg1)
		{
			if (func != null)
			{
				await func(arg1).ConfigureAwait(continueOnCapturedContext: false);
			}
		}
	}
	internal static class SocketIOEventExtensions
	{
		public static void TryInvoke(this OnAnyHandler handler, string eventName, SocketIOResponse response)
		{
			Task.Run(delegate
			{
				handler(eventName, response);
			});
		}

		public static void TryInvoke(this Action<SocketIOResponse> handler, SocketIOResponse response)
		{
			Task.Run(delegate
			{
				handler(response);
			});
		}

		public static void TryInvoke(this Func<SocketIOResponse, Task> handler, SocketIOResponse response)
		{
			handler(response);
		}
	}
}

Mods/RealRadio/SongInfoFetcher.GlobalPlayer.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Net.Http;
using System.Net.WebSockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using AngleSharp;
using AngleSharp.Dom;
using AngleSharp.Io;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using SongInfoFetcher.GlobalPlayer.Data;
using Websocket.Client;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SongInfoFetcher.GlobalPlayer")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+1cd90b6bdac1f314159cb7e67c99a8412d514dd2")]
[assembly: AssemblyProduct("SongInfoFetcher.GlobalPlayer")]
[assembly: AssemblyTitle("SongInfoFetcher.GlobalPlayer")]
[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 System.Runtime.Versioning
{
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiresPreviewFeaturesAttribute : Attribute
	{
		public string? Message { get; }

		public string? Url { get; set; }

		public RequiresPreviewFeaturesAttribute()
		{
		}

		public RequiresPreviewFeaturesAttribute(string? message)
		{
			Message = message;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CallerArgumentExpressionAttribute : Attribute
	{
		public string ParameterName { get; }

		public CallerArgumentExpressionAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CollectionBuilderAttribute : Attribute
	{
		public Type BuilderType { get; }

		public string MethodName { get; }

		public CollectionBuilderAttribute(Type builderType, string methodName)
		{
			BuilderType = builderType;
			MethodName = methodName;
		}
	}
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CompilerFeatureRequiredAttribute : Attribute
	{
		public const string RefStructs = "RefStructs";

		public const string RequiredMembers = "RequiredMembers";

		public string FeatureName { get; }

		public bool IsOptional { get; set; }

		public CompilerFeatureRequiredAttribute(string featureName)
		{
			FeatureName = featureName;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute
	{
		public string[] Arguments { get; }

		public InterpolatedStringHandlerArgumentAttribute(string argument)
		{
			Arguments = new string[1] { argument };
		}

		public InterpolatedStringHandlerArgumentAttribute(params string[] arguments)
		{
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class InterpolatedStringHandlerAttribute : Attribute
	{
	}
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	internal static class IsExternalInit
	{
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ModuleInitializerAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class OverloadResolutionPriorityAttribute : Attribute
	{
		public int Priority { get; }

		public OverloadResolutionPriorityAttribute(int priority)
		{
			Priority = priority;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ParamCollectionAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiredMemberAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiresLocationAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class SkipLocalsInitAttribute : Attribute
	{
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ConstantExpectedAttribute : Attribute
	{
		public object? Min { get; set; }

		public object? Max { get; set; }
	}
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ExperimentalAttribute : Attribute
	{
		public string DiagnosticId { get; }

		public string? UrlFormat { get; set; }

		public ExperimentalAttribute(string diagnosticId)
		{
			DiagnosticId = diagnosticId;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	internal sealed class MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	internal sealed class MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class SetsRequiredMembersAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class StringSyntaxAttribute : Attribute
	{
		public const string CompositeFormat = "CompositeFormat";

		public const string DateOnlyFormat = "DateOnlyFormat";

		public const string DateTimeFormat = "DateTimeFormat";

		public const string EnumFormat = "EnumFormat";

		public const string GuidFormat = "GuidFormat";

		public const string Json = "Json";

		public const string NumericFormat = "NumericFormat";

		public const string Regex = "Regex";

		public const string TimeOnlyFormat = "TimeOnlyFormat";

		public const string TimeSpanFormat = "TimeSpanFormat";

		public const string Uri = "Uri";

		public const string Xml = "Xml";

		public string Syntax { get; }

		public object?[] Arguments { get; }

		public StringSyntaxAttribute(string syntax)
		{
			Syntax = syntax;
			Arguments = new object[0];
		}

		public StringSyntaxAttribute(string syntax, params object?[] arguments)
		{
			Syntax = syntax;
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class UnscopedRefAttribute : Attribute
	{
	}
}
namespace SongInfoFetcher.GlobalPlayer
{
	public class GlobalPlayerSongFetcher : WSSongInfoFetcher
	{
		internal static Regex UriRegex = new Regex("https?://(media-ice\\.musicradio\\.com/(?<station>[^/?]+)MP3.*|(media-ssl\\.musicradio\\.com/(?<station>[^/?]+)).*)$", RegexOptions.IgnoreCase | RegexOptions.Compiled);

		internal static readonly JsonSerializerSettings JsonSerializerSettings = new JsonSerializerSettings
		{
			ContractResolver = (IContractResolver)new CamelCasePropertyNamesContractResolver()
		};

		private int heraldId;

		private string stationSlug;

		public override bool CanListenForSongInfo => true;

		public override bool CanRequestSongInfo => true;

		public GlobalPlayerSongFetcher(Uri uri)
			: base((Func<ClientWebSocket>)CreateClient, (Action<WebsocketClient>)null, (TimeSpan?)TimeSpan.FromSeconds(5.0))
		{
			((WSSongInfoFetcher)this).WSUri = new Uri("wss://metadata.musicradio.com/v2/now-playing");
			stationSlug = ParseStationSlug(uri);
		}

		private static ClientWebSocket CreateClient()
		{
			ClientWebSocket clientWebSocket = new ClientWebSocket();
			clientWebSocket.Options.SetRequestHeader("Origin", "https://www.globalplayer.com");
			return clientWebSocket;
		}

		private static string ParseStationSlug(Uri uri)
		{
			Match match = UriRegex.Match(uri.ToString());
			if (!match.Success)
			{
				throw new ArgumentException("Invalid uri", "uri");
			}
			return match.Groups["station"].Value;
		}

		public override async Task Start()
		{
			foreach (Brand item in (await MetaDataFetcher.FetchMetaData()).Props.PageProps.Feature.Blocks.FirstOrDefault((Block x) => x.Type == BlockType.LiveRadio && x.Brands != null).Brands ?? throw new InvalidOperationException("Could not find brands (required for resolving herald id from brand slug)"))
			{
				if (item.Slug.Equals(stationSlug, StringComparison.InvariantCultureIgnoreCase))
				{
					heraldId = item.NationalStation.HeraldId;
					break;
				}
			}
			if (heraldId == 0)
			{
				throw new InvalidOperationException("Could not find herald id for station slug " + stationSlug);
			}
			await <>n__0();
		}

		protected override async Task<SongInfo> InternalRequestSongInfo()
		{
			if (((WSSongInfoFetcher)this).CurrentSong != (SongInfo)null)
			{
				return ((WSSongInfoFetcher)this).CurrentSong;
			}
			while (((WSSongInfoFetcher)this).CurrentSong == (SongInfo)null)
			{
				await Task.Delay(100);
			}
			return ((WSSongInfoFetcher)this).CurrentSong;
		}

		protected override void OnDisconnected(DisconnectionInfo info)
		{
		}

		protected override void OnMessageReceived(ResponseMessage message)
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			if (message.MessageType != 0 || message.Text == null)
			{
				return;
			}
			try
			{
				NowPlayingResponse nowPlayingResponse = JsonConvert.DeserializeObject<NowPlayingResponse>(message.Text);
				if (!(nowPlayingResponse == null) && nowPlayingResponse.Type == ServiceMessageType.Station && !(nowPlayingResponse.NowPlaying == null) && nowPlayingResponse.NowPlaying.Title != null && nowPlayingResponse.NowPlaying.Artist != null)
				{
					((WSSongInfoFetcher)this).CurrentSong = new SongInfo(nowPlayingResponse.NowPlaying.Title, nowPlayingResponse.NowPlaying.Artist);
				}
			}
			catch
			{
			}
		}

		protected override void OnReconnected(ReconnectionInfo info)
		{
			SendAction(new SubscribeRequest(heraldId));
		}

		private void SendAction(RequestAction action)
		{
			SendActions(new <>z__ReadOnlySingleElementList<RequestAction>(action));
		}

		private void SendActions(IEnumerable<RequestAction> actions)
		{
			((WSSongInfoFetcher)this).Send(SerializeJson(new ActionsRequest(actions.ToList())));
		}

		private string SerializeJson(object obj)
		{
			return JsonConvert.SerializeObject(obj, JsonSerializerSettings);
		}

		[CompilerGenerated]
		[DebuggerHidden]
		private Task <>n__0()
		{
			return ((WSSongInfoFetcher)this).Start();
		}
	}
	public static class ManagerExtensions
	{
		public static void AddGlobalPlayerFetcher(this SongInfoFetchManager manager)
		{
			manager.AddFetcher(GlobalPlayerSongFetcher.UriRegex, (Func<Uri, ISongInfoFetcher>)((Uri uri) => (ISongInfoFetcher)(object)new GlobalPlayerSongFetcher(uri)));
		}
	}
	internal static class MetaDataFetcher
	{
		private static BrowsingContext context = new BrowsingContext(ConfigurationExtensions.WithDefaultLoader(Configuration.Default, (LoaderOptions)null));

		public static async Task<MetaData> FetchMetaData()
		{
			return JsonConvert.DeserializeObject<MetaData>(NodeExtensions.Text((INode)(object)(((INonElementParentNode)(await BrowsingContextExtensions.OpenAsync((IBrowsingContext)(object)context, "https://www.globalplayer.com", default(CancellationToken)))).GetElementById("__NEXT_DATA__") ?? throw new HttpRequestException("Could not find __NEXT_DATA__ element"))), GlobalPlayerSongFetcher.JsonSerializerSettings) ?? throw new HttpRequestException("Deserialized JSON is null");
		}
	}
	internal class SafeStringEnumConverter<T> : StringEnumConverter
	{
		static SafeStringEnumConverter()
		{
			if (!typeof(T).IsEnum)
			{
				throw new ArgumentException("T must be an enum");
			}
		}

		public override bool CanConvert(Type objectType)
		{
			return objectType == typeof(T);
		}

		public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
		{
			try
			{
				return ((StringEnumConverter)this).ReadJson(reader, objectType, existingValue, serializer);
			}
			catch
			{
				return null;
			}
		}
	}
}
namespace SongInfoFetcher.GlobalPlayer.Data
{
	internal record MetaData(Props Props);
	internal record Props(PageProps PageProps);
	internal record PageProps(Feature Feature);
	internal record Feature(List<Block> Blocks);
	internal record Block([property: JsonConverter(typeof(SafeStringEnumConverter<BlockType>))] BlockType Type, List<Brand>? Brands);
	internal enum BlockType
	{
		Unknown,
		[EnumMember(Value = "live_radio")]
		LiveRadio
	}
	internal record Brand(string Slug, NationalStation NationalStation);
	internal record NationalStation(string Name, int HeraldId);
	internal abstract record RequestAction(string Type);
	internal record SubscribeRequest(int Service) : RequestAction("subscribe");
	internal record ActionsRequest(List<RequestAction> Actions);
	internal abstract record ServiceResponse(int Service, ServiceMessageType Type);
	internal record NowPlayingResponse : ServiceResponse
	{
		public SongData NowPlaying { get; init; }

		public NowPlayingResponse(int Service, [JsonProperty("now_playing")] SongData NowPlaying)
		{
			this.NowPlaying = NowPlaying;
			base..ctor(Service, ServiceMessageType.Station);
		}

		[CompilerGenerated]
		public void Deconstruct(out int Service, out SongData NowPlaying)
		{
			Service = base.Service;
			NowPlaying = this.NowPlaying;
		}
	}
	internal enum ServiceMessageType
	{
		Unknown,
		Station
	}
	internal record SongData(string? Title, string? Artist);
}
[CompilerGenerated]
internal sealed class <>z__ReadOnlySingleElementList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	private sealed class Enumerator : IDisposable, IEnumerator, IEnumerator<T>
	{
		object IEnumerator.Current => _item;

		T IEnumerator<T>.Current => _item;

		public Enumerator(T item)
		{
			_item = item;
		}

		bool IEnumerator.MoveNext()
		{
			if (!_moveNextCalled)
			{
				return _moveNextCalled = true;
			}
			return false;
		}

		void IEnumerator.Reset()
		{
			_moveNextCalled = false;
		}

		void IDisposable.Dispose()
		{
		}
	}

	int ICollection.Count => 1;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => 1;

	T IReadOnlyList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
	}

	int ICollection<T>.Count => 1;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			if (index != 0)
			{
				throw new IndexOutOfRangeException();
			}
			return _item;
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlySingleElementList(T item)
	{
		_item = item;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection.CopyTo(Array array, int index)
	{
		array.SetValue(_item, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return EqualityComparer<T>.Default.Equals(_item, (T)value);
	}

	int IList.IndexOf(object value)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, (T)value))
		{
			return -1;
		}
		return 0;
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return new Enumerator(_item);
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return EqualityComparer<T>.Default.Equals(_item, item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		array[arrayIndex] = _item;
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		if (!EqualityComparer<T>.Default.Equals(_item, item))
		{
			return -1;
		}
		return 0;
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}

Mods/RealRadio/SongInfoFetcher.OneFM.dll

Decompiled a day 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 System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using SocketIO.Core;
using SocketIOClient;
using SocketIOClient.Transport;
using SongInfoFetcher.OneFM.Data;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SongInfoFetcher.OneFM")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+1cd90b6bdac1f314159cb7e67c99a8412d514dd2")]
[assembly: AssemblyProduct("SongInfoFetcher.OneFM")]
[assembly: AssemblyTitle("SongInfoFetcher.OneFM")]
[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 SongInfoFetcher.OneFM
{
	public static class ManagerExtensions
	{
		public static void AddOneFMFetcher(this SongInfoFetchManager manager)
		{
			manager.AddFetcher(OneFMSongInfoFetcher.UriRegex, (Func<Uri, ISongInfoFetcher>)((Uri uri) => (ISongInfoFetcher)(object)new OneFMSongInfoFetcher(uri)));
		}
	}
	public class OneFMSongInfoFetcher : SocketIOSongInfoFetcher
	{
		internal static readonly Regex UriRegex = new Regex("^https://strm\\d+\\.1\\.fm/(?<station>[^_/?]+)", RegexOptions.IgnoreCase | RegexOptions.Compiled);

		private readonly string radioStation;

		private readonly Uri playlistUri;

		public override bool CanListenForSongInfo => true;

		public override bool CanRequestSongInfo => true;

		public OneFMSongInfoFetcher(Uri uri)
			: base(new Uri("https://socket.1.fm"), GetSocketIOOptions())
		{
			radioStation = ParseRadioStation(uri);
			playlistUri = new Uri("https://www.1.fm/stplaylist/" + HttpUtility.UrlEncode(radioStation));
		}

		private string ParseRadioStation(Uri uri)
		{
			Match match = UriRegex.Match(uri.ToString());
			if (match.Success)
			{
				return match.Groups["station"].Value;
			}
			throw new ArgumentException("Invalid uri", "uri");
		}

		private static SocketIOOptions? GetSocketIOOptions()
		{
			//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_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_002e: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			return new SocketIOOptions
			{
				ExtraHeaders = new Dictionary<string, string> { { "Origin", "https://1.fm" } },
				AutoUpgrade = true,
				EIO = (EngineIO)3,
				Reconnection = true,
				ReconnectionDelay = 5000.0,
				Transport = (TransportProtocol)1
			};
		}

		public override Task Start()
		{
			((SocketIOSongInfoFetcher)this).Client.On("news", (Action<SocketIOResponse>)OnNewsReceived);
			((SocketIOSongInfoFetcher)this).Client.On("playernews", (Action<SocketIOResponse>)OnNewsReceived);
			return ((SocketIOSongInfoFetcher)this).Start();
		}

		public override async Task<SongInfo> InternalRequestSongInfo()
		{
			if (((SocketIOSongInfoFetcher)this).CurrentSong != (SongInfo)null)
			{
				return ((SocketIOSongInfoFetcher)this).CurrentSong;
			}
			SongData songData = (JsonConvert.DeserializeObject<NewsData>(await ((SocketIOSongInfoFetcher)this).Client.HttpClient.GetStringAsync(playlistUri)) ?? throw new ArgumentException("Deserialized JSON is null")).NowPlaying.FirstOrDefault();
			return ((SocketIOSongInfoFetcher)this).CurrentSong = new SongInfo(CapitalizeWords(songData.Title), CapitalizeWords(songData.Artist));
		}

		protected override void OnConnected()
		{
			((SocketIOSongInfoFetcher)this).Client.EmitAsync("room", new object[1] { radioStation });
		}

		private void OnNewsReceived(SocketIOResponse response)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			EventData<NewsData> value;
			try
			{
				value = response.GetValue<EventData<NewsData>>(0);
			}
			catch
			{
				return;
			}
			if (value?.Data?.NowPlaying != null)
			{
				SongData songData = value.Data.NowPlaying.FirstOrDefault();
				((SocketIOSongInfoFetcher)this).CurrentSong = new SongInfo(CapitalizeWords(songData.Title), CapitalizeWords(songData.Artist));
			}
		}

		private string? CapitalizeWords(string? input)
		{
			if (input == null)
			{
				return null;
			}
			StringBuilder stringBuilder = new StringBuilder(input);
			for (int i = 0; i < stringBuilder.Length; i++)
			{
				if (i == 0 || ShouldCapitalizeNextCharacter(stringBuilder[i - 1]))
				{
					stringBuilder[i] = char.ToUpper(stringBuilder[i]);
				}
			}
			return stringBuilder.ToString();
			static bool ShouldCapitalizeNextCharacter(char ch)
			{
				if (!char.IsLetter(ch) && ch != '\'')
				{
					return ch != '’';
				}
				return false;
			}
		}
	}
}
namespace SongInfoFetcher.OneFM.Data
{
	public record EventData<T>
	{
		[JsonProperty("__data")]
		public T? Data { get; set; }
	}
	public record NewsData
	{
		[JsonProperty("stid")]
		public string? StationId { get; set; }

		[JsonProperty("name")]
		public string? StationName { get; set; }

		public SongData[]? NowPlaying { get; set; } = Array.Empty<SongData>();

	}
	public record SongData
	{
		public string? Artist { get; set; }

		public string? Title { get; set; }
	}
}

Mods/RealRadio/SongInfoFetcher.SimulatorRadio.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.Net.WebSockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Websocket.Client;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SongInfoFetcher.SimulatorRadio")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+1cd90b6bdac1f314159cb7e67c99a8412d514dd2")]
[assembly: AssemblyProduct("SongInfoFetcher.SimulatorRadio")]
[assembly: AssemblyTitle("SongInfoFetcher.SimulatorRadio")]
[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;
		}
	}
}
internal record NowPlayingData
{
	public string? Artists { get; set; }

	public string? Title { get; set; }
}
internal record Message
{
	public MessageType Type { get; set; }

	[JsonProperty("now_playing")]
	public NowPlayingData? NowPlaying { get; set; }
}
internal enum MessageType
{
	NowPlaying,
	History,
	[EnumMember(Value = "24hours")]
	Last24Hours
}
namespace SongInfoFetcher.SimulatorRadio
{
	public static class ManagerExtensions
	{
		public static void AddSimulatorRadioFetcher(this SongInfoFetchManager manager)
		{
			manager.AddFetcher(SimulatorRadioSongInfoFetcher.UriRegex, (Func<Uri, ISongInfoFetcher>)((Uri uri) => (ISongInfoFetcher)(object)new SimulatorRadioSongInfoFetcher()));
		}
	}
	public class SimulatorRadioSongInfoFetcher : WSSongInfoFetcher
	{
		internal static Regex UriRegex { get; private set; } = new Regex("^(https?\\://stream.simulatorradio.com(.*))|(https?\\://simulatorradio.stream(.*))", RegexOptions.IgnoreCase | RegexOptions.Compiled);


		public override bool CanListenForSongInfo => true;

		public override bool CanRequestSongInfo => true;

		public SimulatorRadioSongInfoFetcher()
			: base((Func<ClientWebSocket>)CreateClient, (Action<WebsocketClient>)null, (TimeSpan?)TimeSpan.FromSeconds(15.0))
		{
			((WSSongInfoFetcher)this).WSUri = new Uri("wss://ws.simulatorradio.com");
		}

		private static ClientWebSocket CreateClient()
		{
			ClientWebSocket clientWebSocket = new ClientWebSocket();
			clientWebSocket.Options.SetRequestHeader("Origin", "https://simulatorradio.com");
			return clientWebSocket;
		}

		protected override async Task<SongInfo> InternalRequestSongInfo()
		{
			if (((WSSongInfoFetcher)this).CurrentSong != (SongInfo)null)
			{
				return ((WSSongInfoFetcher)this).CurrentSong;
			}
			return await Task.Run<SongInfo>(async delegate
			{
				while (((WSSongInfoFetcher)this).CurrentSong == (SongInfo)null)
				{
					await Task.Delay(100);
				}
				return ((WSSongInfoFetcher)this).CurrentSong;
			});
		}

		protected override void OnDisconnected(DisconnectionInfo info)
		{
		}

		protected override void OnMessageReceived(ResponseMessage message)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			if (message.MessageType == WebSocketMessageType.Text)
			{
				string text = message.Text;
				Message message2;
				try
				{
					message2 = JsonConvert.DeserializeObject<Message>(text);
				}
				catch
				{
					return;
				}
				if (message2.Type == MessageType.NowPlaying && !(message2.NowPlaying == null))
				{
					NowPlayingData nowPlaying = message2.NowPlaying;
					SongInfo currentSong = new SongInfo(nowPlaying.Title, nowPlaying.Artists);
					((WSSongInfoFetcher)this).CurrentSong = currentSong;
				}
			}
		}

		protected override void OnReconnected(ReconnectionInfo info)
		{
		}
	}
}

Mods/RealRadio/SongInfoFetcher.TruckersFM.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Http;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using SocketIO.Core;
using SocketIOClient;
using SocketIOClient.Transport;
using SongInfoFetcher.TruckersFM.Data;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SongInfoFetcher.TruckersFM")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+1cd90b6bdac1f314159cb7e67c99a8412d514dd2")]
[assembly: AssemblyProduct("SongInfoFetcher.TruckersFM")]
[assembly: AssemblyTitle("SongInfoFetcher.TruckersFM")]
[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 SongInfoFetcher.TruckersFM
{
	internal record SongEventData
	{
		[JsonProperty("current_song")]
		public CurrentSongData? CurrentSong { get; set; }
	}
	internal record CurrentSongData
	{
		public SongData? Song { get; set; }
	}
	public static class ManagerExtensions
	{
		public static void AddTruckersFMSongInfoFetcher(this SongInfoFetchManager manager)
		{
			manager.AddFetcher(TruckersFMSongFetcher.UriRegex, (Func<Uri, ISongInfoFetcher>)((Uri uri) => (ISongInfoFetcher)(object)new TruckersFMSongFetcher()));
		}
	}
	public class TruckersFMSongFetcher : SocketIOSongInfoFetcher
	{
		internal static readonly Regex UriRegex = new Regex("^https://live\\.truckers\\.fm(.*)$");

		private const string CurrentSongUrl = "https://radiocloud.pro/api/public/v1/song/current";

		public override bool CanListenForSongInfo => true;

		public override bool CanRequestSongInfo => true;

		public TruckersFMSongFetcher()
			: base(new Uri("https://public-socket.truckers.fm"), GetSocketIOOptions())
		{
		}

		public override Task Start()
		{
			((SocketIOSongInfoFetcher)this).Client.On("song", (Action<SocketIOResponse>)OnSongInfoReceived);
			return ((SocketIOSongInfoFetcher)this).Start();
		}

		private static SocketIOOptions GetSocketIOOptions()
		{
			//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_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_002e: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			return new SocketIOOptions
			{
				ExtraHeaders = new Dictionary<string, string> { { "Origin", "https://truckers.fm" } },
				AutoUpgrade = true,
				EIO = (EngineIO)3,
				Reconnection = true,
				ReconnectionDelay = 5000.0,
				Transport = (TransportProtocol)1
			};
		}

		private void OnSongInfoReceived(SocketIOResponse response)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			SongData songData = response.GetValue<SongEventData>(0)?.CurrentSong?.Song;
			if (!(songData == null))
			{
				((SocketIOSongInfoFetcher)this).CurrentSong = new SongInfo(songData.Title, songData.Artist);
			}
		}

		public override async Task<SongInfo> InternalRequestSongInfo()
		{
			if (((SocketIOSongInfoFetcher)this).CurrentSong != (SongInfo)null)
			{
				return ((SocketIOSongInfoFetcher)this).CurrentSong;
			}
			HttpResponseMessage obj = await ((SocketIOSongInfoFetcher)this).Client.HttpClient.SendAsync(new HttpRequestMessage(HttpMethod.Get, "https://radiocloud.pro/api/public/v1/song/current"), default(CancellationToken));
			obj.EnsureSuccessStatusCode();
			HttpCurrentSongResponse httpCurrentSongResponse = JsonConvert.DeserializeObject<HttpCurrentSongResponse>(await obj.Content.ReadAsStringAsync()) ?? throw new HttpRequestException("Deserialized JSON is null");
			if (httpCurrentSongResponse.Status != "success")
			{
				throw new HttpRequestException("Status is not 'success': " + httpCurrentSongResponse.Status);
			}
			if (httpCurrentSongResponse.Data == null)
			{
				throw new HttpRequestException("No data in response");
			}
			((SocketIOSongInfoFetcher)this).CurrentSong = new SongInfo(httpCurrentSongResponse.Data.Title, httpCurrentSongResponse.Data.Artist);
			return ((SocketIOSongInfoFetcher)this).CurrentSong;
		}
	}
}
namespace SongInfoFetcher.TruckersFM.Data
{
	internal record HttpCurrentSongResponse
	{
		public string? Status { get; set; }

		public SongData? Data { get; set; }
	}
	internal record SongData
	{
		public string? Artist { get; set; }

		public string? Title { get; set; }
	}
}

Mods/RealRadio/SongInfoFetcher.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Net.WebSockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using SocketIO.Serializer.Core;
using SocketIO.Serializer.NewtonsoftJson;
using SocketIOClient;
using Websocket.Client;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SongInfoFetcher")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+1cd90b6bdac1f314159cb7e67c99a8412d514dd2")]
[assembly: AssemblyProduct("SongInfoFetcher")]
[assembly: AssemblyTitle("SongInfoFetcher")]
[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 System.Runtime.Versioning
{
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiresPreviewFeaturesAttribute : Attribute
	{
		public string? Message { get; }

		public string? Url { get; set; }

		public RequiresPreviewFeaturesAttribute()
		{
		}

		public RequiresPreviewFeaturesAttribute(string? message)
		{
			Message = message;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CallerArgumentExpressionAttribute : Attribute
	{
		public string ParameterName { get; }

		public CallerArgumentExpressionAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CollectionBuilderAttribute : Attribute
	{
		public Type BuilderType { get; }

		public string MethodName { get; }

		public CollectionBuilderAttribute(Type builderType, string methodName)
		{
			BuilderType = builderType;
			MethodName = methodName;
		}
	}
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CompilerFeatureRequiredAttribute : Attribute
	{
		public const string RefStructs = "RefStructs";

		public const string RequiredMembers = "RequiredMembers";

		public string FeatureName { get; }

		public bool IsOptional { get; set; }

		public CompilerFeatureRequiredAttribute(string featureName)
		{
			FeatureName = featureName;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute
	{
		public string[] Arguments { get; }

		public InterpolatedStringHandlerArgumentAttribute(string argument)
		{
			Arguments = new string[1] { argument };
		}

		public InterpolatedStringHandlerArgumentAttribute(params string[] arguments)
		{
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class InterpolatedStringHandlerAttribute : Attribute
	{
	}
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	internal static class IsExternalInit
	{
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ModuleInitializerAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class OverloadResolutionPriorityAttribute : Attribute
	{
		public int Priority { get; }

		public OverloadResolutionPriorityAttribute(int priority)
		{
			Priority = priority;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ParamCollectionAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiredMemberAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiresLocationAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class SkipLocalsInitAttribute : Attribute
	{
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ConstantExpectedAttribute : Attribute
	{
		public object? Min { get; set; }

		public object? Max { get; set; }
	}
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ExperimentalAttribute : Attribute
	{
		public string DiagnosticId { get; }

		public string? UrlFormat { get; set; }

		public ExperimentalAttribute(string diagnosticId)
		{
			DiagnosticId = diagnosticId;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	internal sealed class MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	internal sealed class MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class SetsRequiredMembersAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class StringSyntaxAttribute : Attribute
	{
		public const string CompositeFormat = "CompositeFormat";

		public const string DateOnlyFormat = "DateOnlyFormat";

		public const string DateTimeFormat = "DateTimeFormat";

		public const string EnumFormat = "EnumFormat";

		public const string GuidFormat = "GuidFormat";

		public const string Json = "Json";

		public const string NumericFormat = "NumericFormat";

		public const string Regex = "Regex";

		public const string TimeOnlyFormat = "TimeOnlyFormat";

		public const string TimeSpanFormat = "TimeSpanFormat";

		public const string Uri = "Uri";

		public const string Xml = "Xml";

		public string Syntax { get; }

		public object?[] Arguments { get; }

		public StringSyntaxAttribute(string syntax)
		{
			Syntax = syntax;
			Arguments = new object[0];
		}

		public StringSyntaxAttribute(string syntax, params object?[] arguments)
		{
			Syntax = syntax;
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class UnscopedRefAttribute : Attribute
	{
	}
}
namespace SongInfoFetcher
{
	public interface ISongInfoFetcher : IDisposable
	{
		bool CanListenForSongInfo { get; }

		bool CanRequestSongInfo { get; }

		SongInfo? CurrentSong { get; }

		Task Start();

		Task Stop();

		Task<SongInfo> RequestSongInfo();

		void SubscribeToSongInfoChanges(Action<SongInfo> onSongInfoChanged);

		void UnsubscribeFromSongInfoChanges(Action<SongInfo> onSongInfoChanged);
	}
	public class ManualSongInfoFetcher : ISongInfoFetcher, IDisposable
	{
		private SongInfo? currentSong;

		private Action<SongInfo>? onSongInfoChanged;

		public bool CanListenForSongInfo => true;

		public bool CanRequestSongInfo => false;

		public SongInfo? CurrentSong
		{
			get
			{
				return currentSong;
			}
			set
			{
				if (!(currentSong == value))
				{
					currentSong = value;
					if (value != null)
					{
						onSongInfoChanged?.Invoke(value);
					}
				}
			}
		}

		public void Dispose()
		{
		}

		public Task<SongInfo> RequestSongInfo()
		{
			throw new NotSupportedException();
		}

		public Task Start()
		{
			return Task.CompletedTask;
		}

		public Task Stop()
		{
			return Task.CompletedTask;
		}

		public void SubscribeToSongInfoChanges(Action<SongInfo> onSongInfoChanged)
		{
			this.onSongInfoChanged = (Action<SongInfo>)Delegate.Combine(this.onSongInfoChanged, onSongInfoChanged);
		}

		public void UnsubscribeFromSongInfoChanges(Action<SongInfo> onSongInfoChanged)
		{
			this.onSongInfoChanged = (Action<SongInfo>)Delegate.Remove(this.onSongInfoChanged, onSongInfoChanged);
		}
	}
	public abstract class SocketIOSongInfoFetcher : ISongInfoFetcher, IDisposable
	{
		private SongInfo? currentSong;

		public abstract bool CanListenForSongInfo { get; }

		public abstract bool CanRequestSongInfo { get; }

		public SongInfo? CurrentSong
		{
			get
			{
				return currentSong;
			}
			protected set
			{
				if (!(value == currentSong))
				{
					currentSong = value;
					if (value != null)
					{
						SongInfoReceived?.Invoke(value);
					}
				}
			}
		}

		protected Action<SongInfo>? SongInfoReceived { get; private set; }

		protected SocketIO Client { get; private set; }

		public SocketIOSongInfoFetcher(Uri uri, SocketIOOptions? options = null)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0038: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			if (options == null)
			{
				options = new SocketIOOptions();
			}
			Client = new SocketIO(uri, options);
			Client.Serializer = (ISerializer)new NewtonsoftJsonSerializer(new JsonSerializerSettings
			{
				ContractResolver = (IContractResolver)new CamelCasePropertyNamesContractResolver()
			});
			Client.OnConnected += delegate
			{
				OnConnected();
			};
			Client.OnDisconnected += delegate
			{
				OnDisconnected();
			};
		}

		public Task<SongInfo> RequestSongInfo()
		{
			if (!CanRequestSongInfo)
			{
				throw new InvalidOperationException("Cannot request song info");
			}
			return InternalRequestSongInfo();
		}

		public abstract Task<SongInfo> InternalRequestSongInfo();

		public virtual Task Start()
		{
			return Client.ConnectAsync();
		}

		public Task Stop()
		{
			if (!Client.Connected)
			{
				return Task.CompletedTask;
			}
			return Client.DisconnectAsync();
		}

		public void SubscribeToSongInfoChanges(Action<SongInfo> onSongInfoChanged)
		{
			if (onSongInfoChanged == null)
			{
				throw new ArgumentNullException("onSongInfoChanged");
			}
			SongInfoReceived = (Action<SongInfo>)Delegate.Combine(SongInfoReceived, onSongInfoChanged);
		}

		public void UnsubscribeFromSongInfoChanges(Action<SongInfo> onSongInfoChanged)
		{
			if (onSongInfoChanged == null)
			{
				throw new ArgumentNullException("onSongInfoChanged");
			}
			SongInfoReceived = (Action<SongInfo>)Delegate.Remove(SongInfoReceived, onSongInfoChanged);
		}

		protected virtual void OnDisconnected()
		{
			CurrentSong = null;
		}

		protected virtual void OnConnected()
		{
		}

		public void Dispose()
		{
			Client.Dispose();
		}
	}
	public record SongInfo
	{
		public string Title { get; set; }

		public string? Artist { get; set; }

		public SongInfo(string? Title, string? Artist)
		{
			this.Title = Title ?? "Unknown Title";
			this.Artist = Artist;
		}

		public override string ToString()
		{
			if (Artist == null)
			{
				return Title;
			}
			return Artist + " - " + Title;
		}
	}
	public class SongInfoFetchManager
	{
		private Dictionary<Regex, Dictionary<Uri, ISongInfoFetcher>> fetchers = new Dictionary<Regex, Dictionary<Uri, ISongInfoFetcher>>();

		private Dictionary<Regex, Func<Uri, ISongInfoFetcher>> fetcherFactories = new Dictionary<Regex, Func<Uri, ISongInfoFetcher>>();

		private Dictionary<ISongInfoFetcher, Task> startTasks = new Dictionary<ISongInfoFetcher, Task>();

		public ReadOnlyDictionary<Regex, Dictionary<Uri, ISongInfoFetcher>> Fetchers => new ReadOnlyDictionary<Regex, Dictionary<Uri, ISongInfoFetcher>>(fetchers);

		public void AddFetcher(Regex uriRegex, Func<Uri, ISongInfoFetcher> fetcherFactory)
		{
			if (uriRegex == null)
			{
				throw new ArgumentNullException("uriRegex");
			}
			if (fetcherFactory == null)
			{
				throw new ArgumentNullException("fetcherFactory");
			}
			fetchers.Add(uriRegex, new Dictionary<Uri, ISongInfoFetcher>());
			fetcherFactories.Add(uriRegex, fetcherFactory);
		}

		public void AddFetcher(Uri uri, Func<Uri, ISongInfoFetcher> fetcherFactory)
		{
			AddFetcher(CreateBasicRegex(uri), fetcherFactory);
		}

		public static Regex CreateBasicRegex(Uri uri)
		{
			return new Regex("^" + Regex.Escape(uri.Scheme) + "://" + Regex.Escape(uri.Authority) + "(.*)$", RegexOptions.IgnoreCase | RegexOptions.Compiled);
		}

		public async Task<ISongInfoFetcher?> GetFetcher(Uri uri)
		{
			foreach (KeyValuePair<Regex, Dictionary<Uri, ISongInfoFetcher>> fetcher in fetchers)
			{
				if (fetcher.Key.Match(uri.ToString()).Success)
				{
					if (fetcher.Value.TryGetValue(uri, out var outFetcher2))
					{
						return outFetcher2;
					}
					outFetcher2 = fetcherFactories[fetcher.Key](uri);
					fetcher.Value.Add(uri, outFetcher2);
					Task task = outFetcher2.Start();
					startTasks.Add(outFetcher2, task);
					try
					{
						await task;
					}
					finally
					{
						startTasks.Remove(outFetcher2);
					}
					return outFetcher2;
				}
			}
			return null;
		}

		public async Task<bool> RemoveFetcher(Uri uri)
		{
			foreach (KeyValuePair<Regex, Dictionary<Uri, ISongInfoFetcher>> fetcher2 in fetchers)
			{
				if (fetcher2.Value.Remove(uri, out var fetcher))
				{
					if (startTasks.Remove(fetcher, out Task value))
					{
						try
						{
							await value;
						}
						catch
						{
						}
					}
					await fetcher.Stop();
					fetcher.Dispose();
					return true;
				}
				fetcher = null;
			}
			return false;
		}
	}
	public abstract class WSSongInfoFetcher : ISongInfoFetcher, IDisposable
	{
		private SongInfo? currentSong;

		public Uri? WSUri { get; set; }

		public abstract bool CanListenForSongInfo { get; }

		public abstract bool CanRequestSongInfo { get; }

		protected Action<SongInfo>? SongInfoReceived { get; private set; }

		protected WebsocketClient Client { get; private set; }

		public SongInfo? CurrentSong
		{
			get
			{
				return currentSong;
			}
			protected set
			{
				if (!(value == currentSong))
				{
					currentSong = value;
					if (value != null)
					{
						SongInfoReceived?.Invoke(value);
					}
				}
			}
		}

		public WSSongInfoFetcher(Func<ClientWebSocket>? clientFactory = null, Action<WebsocketClient>? configureClient = null, TimeSpan? reconnectTimeout = null)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			TimeSpan valueOrDefault = reconnectTimeout.GetValueOrDefault();
			if (!reconnectTimeout.HasValue)
			{
				valueOrDefault = TimeSpan.FromMinutes(1.0);
				reconnectTimeout = valueOrDefault;
			}
			Client = new WebsocketClient(new Uri("ws://localhost"), clientFactory);
			if (reconnectTimeout.HasValue)
			{
				Client.ReconnectTimeout = reconnectTimeout;
			}
			Client.ErrorReconnectTimeout = TimeSpan.FromSeconds(5.0);
			ObservableExtensions.Subscribe<ResponseMessage>(Client.MessageReceived, (Action<ResponseMessage>)OnMessageReceived);
			ObservableExtensions.Subscribe<ReconnectionInfo>(Client.ReconnectionHappened, (Action<ReconnectionInfo>)OnReconnected);
			ObservableExtensions.Subscribe<DisconnectionInfo>(Client.DisconnectionHappened, (Action<DisconnectionInfo>)OnDisconnected);
			configureClient?.Invoke(Client);
		}

		public virtual async Task Start()
		{
			if (WSUri == null)
			{
				throw new InvalidOperationException("WSUri is not set");
			}
			Client.Url = WSUri;
			await Client.Start();
		}

		public async Task Stop()
		{
			await Client.Stop(WebSocketCloseStatus.NormalClosure, "Stopped by user");
		}

		public Task<SongInfo> RequestSongInfo()
		{
			if (!CanRequestSongInfo)
			{
				throw new InvalidOperationException("Cannot request song info");
			}
			return InternalRequestSongInfo();
		}

		public void SubscribeToSongInfoChanges(Action<SongInfo> onSongInfoChanged)
		{
			if (onSongInfoChanged == null)
			{
				throw new ArgumentNullException("onSongInfoChanged");
			}
			SongInfoReceived = (Action<SongInfo>)Delegate.Combine(SongInfoReceived, onSongInfoChanged);
		}

		public void UnsubscribeFromSongInfoChanges(Action<SongInfo> onSongInfoChanged)
		{
			if (onSongInfoChanged == null)
			{
				throw new ArgumentNullException("onSongInfoChanged");
			}
			SongInfoReceived = (Action<SongInfo>)Delegate.Remove(SongInfoReceived, onSongInfoChanged);
		}

		protected void Send(string text)
		{
			Client.Send(text);
		}

		protected void Send(byte[] data)
		{
			Client.Send(data);
		}

		protected abstract void OnReconnected(ReconnectionInfo info);

		protected abstract void OnMessageReceived(ResponseMessage message);

		protected abstract Task<SongInfo> InternalRequestSongInfo();

		protected abstract void OnDisconnected(DisconnectionInfo info);

		public void Dispose()
		{
			Client.Dispose();
		}
	}
}

Mods/RealRadio/System.Buffers.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.Diagnostics.Tracing;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using FxResources.System.Buffers;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyDefaultAlias("System.Buffers")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyDescription("System.Buffers")]
[assembly: AssemblyFileVersion("4.600.125.16908")]
[assembly: AssemblyInformationalVersion("4.6.1+6b84308c9ad012f53240d72c1d716d7e42546483")]
[assembly: AssemblyProduct("Microsoft® .NET")]
[assembly: AssemblyTitle("System.Buffers")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/dotnet/maintenance-packages")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.0.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace FxResources.System.Buffers
{
	internal static class SR
	{
	}
}
namespace System
{
	internal static class SR
	{
		private static readonly bool s_usingResourceKeys = AppContext.TryGetSwitch("System.Resources.UseSystemResourceKeys", out var isEnabled) && isEnabled;

		private static ResourceManager s_resourceManager;

		internal static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(typeof(SR)));

		internal static string ArgumentException_BufferNotFromPool => GetResourceString("ArgumentException_BufferNotFromPool");

		private static bool UsingResourceKeys()
		{
			return s_usingResourceKeys;
		}

		internal static string GetResourceString(string resourceKey)
		{
			if (UsingResourceKeys())
			{
				return resourceKey;
			}
			string result = null;
			try
			{
				result = ResourceManager.GetString(resourceKey);
			}
			catch (MissingManifestResourceException)
			{
			}
			return result;
		}

		internal static string GetResourceString(string resourceKey, string defaultString)
		{
			string resourceString = GetResourceString(resourceKey);
			if (!(resourceKey == resourceString) && resourceString != null)
			{
				return resourceString;
			}
			return defaultString;
		}

		internal static string Format(string resourceFormat, object? p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(resourceFormat, p1);
		}

		internal static string Format(string resourceFormat, object? p1, object? p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(resourceFormat, p1, p2);
		}

		internal static string Format(string resourceFormat, object? p1, object? p2, object? p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(resourceFormat, p1, p2, p3);
		}

		internal static string Format(string resourceFormat, params object?[]? args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + ", " + string.Join(", ", args);
				}
				return string.Format(resourceFormat, args);
			}
			return resourceFormat;
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(provider, resourceFormat, p1);
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1, object? p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(provider, resourceFormat, p1, p2);
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1, object? p2, object? p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(provider, resourceFormat, p1, p2, p3);
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, params object?[]? args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + ", " + string.Join(", ", args);
				}
				return string.Format(provider, resourceFormat, args);
			}
			return resourceFormat;
		}
	}
}
namespace System.Buffers
{
	public abstract class ArrayPool<T>
	{
		private static ArrayPool<T> s_sharedInstance;

		public static ArrayPool<T> Shared
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return Volatile.Read(ref s_sharedInstance) ?? EnsureSharedCreated();
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static ArrayPool<T> EnsureSharedCreated()
		{
			Interlocked.CompareExchange(ref s_sharedInstance, Create(), null);
			return s_sharedInstance;
		}

		public static ArrayPool<T> Create()
		{
			return new DefaultArrayPool<T>();
		}

		public static ArrayPool<T> Create(int maxArrayLength, int maxArraysPerBucket)
		{
			return new DefaultArrayPool<T>(maxArrayLength, maxArraysPerBucket);
		}

		public abstract T[] Rent(int minimumLength);

		public abstract void Return(T[] array, bool clearArray = false);
	}
	[EventSource(Name = "System.Buffers.ArrayPoolEventSource")]
	internal sealed class ArrayPoolEventSource : EventSource
	{
		internal enum BufferAllocatedReason
		{
			Pooled,
			OverMaximumSize,
			PoolExhausted
		}

		internal static readonly System.Buffers.ArrayPoolEventSource Log = new System.Buffers.ArrayPoolEventSource();

		[Event(1, Level = EventLevel.Verbose)]
		internal unsafe void BufferRented(int bufferId, int bufferSize, int poolId, int bucketId)
		{
			EventData* ptr = stackalloc EventData[4];
			*ptr = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferId)
			};
			ptr[1] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferSize)
			};
			ptr[2] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&poolId)
			};
			ptr[3] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bucketId)
			};
			WriteEventCore(1, 4, ptr);
		}

		[Event(2, Level = EventLevel.Informational)]
		internal unsafe void BufferAllocated(int bufferId, int bufferSize, int poolId, int bucketId, BufferAllocatedReason reason)
		{
			EventData* ptr = stackalloc EventData[5];
			*ptr = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferId)
			};
			ptr[1] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferSize)
			};
			ptr[2] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&poolId)
			};
			ptr[3] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bucketId)
			};
			ptr[4] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&reason)
			};
			WriteEventCore(2, 5, ptr);
		}

		[Event(3, Level = EventLevel.Verbose)]
		internal void BufferReturned(int bufferId, int bufferSize, int poolId)
		{
			WriteEvent(3, bufferId, bufferSize, poolId);
		}
	}
	internal sealed class DefaultArrayPool<T> : ArrayPool<T>
	{
		private sealed class Bucket
		{
			internal readonly int _bufferLength;

			private readonly T[][] _buffers;

			private readonly int _poolId;

			private SpinLock _lock;

			private int _index;

			internal int Id => GetHashCode();

			internal Bucket(int bufferLength, int numberOfBuffers, int poolId)
			{
				_lock = new SpinLock(Debugger.IsAttached);
				_buffers = new T[numberOfBuffers][];
				_bufferLength = bufferLength;
				_poolId = poolId;
			}

			internal T[] Rent()
			{
				T[][] buffers = _buffers;
				T[] array = null;
				bool lockTaken = false;
				bool flag = false;
				try
				{
					_lock.Enter(ref lockTaken);
					if (_index < buffers.Length)
					{
						array = buffers[_index];
						buffers[_index++] = null;
						flag = array == null;
					}
				}
				finally
				{
					if (lockTaken)
					{
						_lock.Exit(useMemoryBarrier: false);
					}
				}
				if (flag)
				{
					array = new T[_bufferLength];
					System.Buffers.ArrayPoolEventSource log = System.Buffers.ArrayPoolEventSource.Log;
					if (log.IsEnabled())
					{
						log.BufferAllocated(array.GetHashCode(), _bufferLength, _poolId, Id, System.Buffers.ArrayPoolEventSource.BufferAllocatedReason.Pooled);
					}
				}
				return array;
			}

			internal void Return(T[] array)
			{
				if (array.Length != _bufferLength)
				{
					throw new ArgumentException(System.SR.ArgumentException_BufferNotFromPool, "array");
				}
				bool lockTaken = false;
				try
				{
					_lock.Enter(ref lockTaken);
					if (_index != 0)
					{
						_buffers[--_index] = array;
					}
				}
				finally
				{
					if (lockTaken)
					{
						_lock.Exit(useMemoryBarrier: false);
					}
				}
			}
		}

		private const int DefaultMaxArrayLength = 1048576;

		private const int DefaultMaxNumberOfArraysPerBucket = 50;

		private static T[] s_emptyArray;

		private readonly Bucket[] _buckets;

		private int Id => GetHashCode();

		internal DefaultArrayPool()
			: this(1048576, 50)
		{
		}

		internal DefaultArrayPool(int maxArrayLength, int maxArraysPerBucket)
		{
			if (maxArrayLength <= 0)
			{
				throw new ArgumentOutOfRangeException("maxArrayLength");
			}
			if (maxArraysPerBucket <= 0)
			{
				throw new ArgumentOutOfRangeException("maxArraysPerBucket");
			}
			if (maxArrayLength > 1073741824)
			{
				maxArrayLength = 1073741824;
			}
			else if (maxArrayLength < 16)
			{
				maxArrayLength = 16;
			}
			int id = Id;
			int num = System.Buffers.Utilities.SelectBucketIndex(maxArrayLength);
			Bucket[] array = new Bucket[num + 1];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = new Bucket(System.Buffers.Utilities.GetMaxSizeForBucket(i), maxArraysPerBucket, id);
			}
			_buckets = array;
		}

		public override T[] Rent(int minimumLength)
		{
			if (minimumLength < 0)
			{
				throw new ArgumentOutOfRangeException("minimumLength");
			}
			if (minimumLength == 0)
			{
				return s_emptyArray ?? (s_emptyArray = new T[0]);
			}
			System.Buffers.ArrayPoolEventSource log = System.Buffers.ArrayPoolEventSource.Log;
			T[] array = null;
			int num = System.Buffers.Utilities.SelectBucketIndex(minimumLength);
			if (num < _buckets.Length)
			{
				int num2 = num;
				do
				{
					array = _buckets[num2].Rent();
					if (array != null)
					{
						if (log.IsEnabled())
						{
							log.BufferRented(array.GetHashCode(), array.Length, Id, _buckets[num2].Id);
						}
						return array;
					}
				}
				while (++num2 < _buckets.Length && num2 != num + 2);
				array = new T[_buckets[num]._bufferLength];
			}
			else
			{
				array = new T[minimumLength];
			}
			if (log.IsEnabled())
			{
				int hashCode = array.GetHashCode();
				int bucketId = -1;
				log.BufferRented(hashCode, array.Length, Id, bucketId);
				log.BufferAllocated(hashCode, array.Length, Id, bucketId, (num >= _buckets.Length) ? System.Buffers.ArrayPoolEventSource.BufferAllocatedReason.OverMaximumSize : System.Buffers.ArrayPoolEventSource.BufferAllocatedReason.PoolExhausted);
			}
			return array;
		}

		public override void Return(T[] array, bool clearArray = false)
		{
			if (array == null)
			{
				throw new ArgumentNullException("array");
			}
			if (array.Length == 0)
			{
				return;
			}
			int num = System.Buffers.Utilities.SelectBucketIndex(array.Length);
			if (num < _buckets.Length)
			{
				if (clearArray)
				{
					Array.Clear(array, 0, array.Length);
				}
				_buckets[num].Return(array);
			}
			System.Buffers.ArrayPoolEventSource log = System.Buffers.ArrayPoolEventSource.Log;
			if (log.IsEnabled())
			{
				log.BufferReturned(array.GetHashCode(), array.Length, Id);
			}
		}
	}
	internal static class Utilities
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static int SelectBucketIndex(int bufferSize)
		{
			uint num = (uint)(bufferSize - 1) >> 4;
			int num2 = 0;
			if (num > 65535)
			{
				num >>= 16;
				num2 = 16;
			}
			if (num > 255)
			{
				num >>= 8;
				num2 += 8;
			}
			if (num > 15)
			{
				num >>= 4;
				num2 += 4;
			}
			if (num > 3)
			{
				num >>= 2;
				num2 += 2;
			}
			if (num > 1)
			{
				num >>= 1;
				num2++;
			}
			return num2 + (int)num;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static int GetMaxSizeForBucket(int binIndex)
		{
			return 16 << binIndex;
		}
	}
}

Mods/RealRadio/System.Memory.dll

Decompiled a day ago
using System;
using System.Buffers;
using System.Buffers.Binary;
using System.Buffers.Text;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Numerics;
using System.Numerics.Hashing;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using FxResources.System.Memory;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyDefaultAlias("System.Memory")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyDescription("System.Memory")]
[assembly: AssemblyFileVersion("4.600.325.20307")]
[assembly: AssemblyInformationalVersion("4.6.3+f62ca0009b038cab4725a720f386623a969d73ad")]
[assembly: AssemblyProduct("Microsoft® .NET")]
[assembly: AssemblyTitle("System.Memory")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/dotnet/maintenance-packages")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.0.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsByRefLikeAttribute : Attribute
	{
	}
	[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 FxResources.System.Memory
{
	internal static class SR
	{
	}
}
namespace System
{
	[DebuggerTypeProxy(typeof(System.MemoryDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	public readonly struct Memory<T>
	{
		private readonly object _object;

		private readonly int _index;

		private readonly int _length;

		private const int RemoveFlagsBitMask = int.MaxValue;

		public static Memory<T> Empty => default(Memory<T>);

		public int Length => _length & 0x7FFFFFFF;

		public bool IsEmpty => (_length & 0x7FFFFFFF) == 0;

		public Span<T> Span
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				Span<T> result;
				if (_index < 0)
				{
					result = ((MemoryManager<T>)_object).GetSpan();
					return result.Slice(_index & 0x7FFFFFFF, _length);
				}
				if (typeof(T) == typeof(char) && _object is string text)
				{
					result = new Span<T>(Unsafe.As<Pinnable<T>>(text), MemoryExtensions.StringAdjustment, text.Length);
					return result.Slice(_index, _length);
				}
				if (_object != null)
				{
					return new Span<T>((T[])_object, _index, _length & 0x7FFFFFFF);
				}
				result = default(Span<T>);
				return result;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory(T[] array)
		{
			if (array == null)
			{
				this = default(Memory<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			_object = array;
			_index = 0;
			_length = array.Length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Memory(T[] array, int start)
		{
			if (array == null)
			{
				if (start != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException();
				}
				this = default(Memory<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			if ((uint)start > (uint)array.Length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = array;
			_index = start;
			_length = array.Length - start;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory(T[] array, int start, int length)
		{
			if (array == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException();
				}
				this = default(Memory<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = array;
			_index = start;
			_length = length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Memory(MemoryManager<T> manager, int length)
		{
			if (length < 0)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = manager;
			_index = int.MinValue;
			_length = length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Memory(MemoryManager<T> manager, int start, int length)
		{
			if (length < 0 || start < 0)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = manager;
			_index = start | int.MinValue;
			_length = length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Memory(object obj, int start, int length)
		{
			_object = obj;
			_index = start;
			_length = length;
		}

		public static implicit operator Memory<T>(T[] array)
		{
			return new Memory<T>(array);
		}

		public static implicit operator Memory<T>(ArraySegment<T> segment)
		{
			return new Memory<T>(segment.Array, segment.Offset, segment.Count);
		}

		public static implicit operator ReadOnlyMemory<T>(Memory<T> memory)
		{
			return Unsafe.As<Memory<T>, ReadOnlyMemory<T>>(ref memory);
		}

		public override string ToString()
		{
			if (typeof(T) == typeof(char))
			{
				if (!(_object is string text))
				{
					return Span.ToString();
				}
				return text.Substring(_index, _length & 0x7FFFFFFF);
			}
			return $"System.Memory<{typeof(T).Name}>[{_length & 0x7FFFFFFF}]";
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory<T> Slice(int start)
		{
			int length = _length;
			int num = length & 0x7FFFFFFF;
			if ((uint)start > (uint)num)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new Memory<T>(_object, _index + start, length - start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory<T> Slice(int start, int length)
		{
			int length2 = _length;
			int num = length2 & 0x7FFFFFFF;
			if ((uint)start > (uint)num || (uint)length > (uint)(num - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			return new Memory<T>(_object, _index + start, length | (length2 & int.MinValue));
		}

		public void CopyTo(Memory<T> destination)
		{
			Span.CopyTo(destination.Span);
		}

		public bool TryCopyTo(Memory<T> destination)
		{
			return Span.TryCopyTo(destination.Span);
		}

		public unsafe MemoryHandle Pin()
		{
			if (_index < 0)
			{
				return ((MemoryManager<T>)_object).Pin(_index & 0x7FFFFFFF);
			}
			if (typeof(T) == typeof(char) && _object is string value)
			{
				GCHandle handle = GCHandle.Alloc(value, GCHandleType.Pinned);
				void* pointer = Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer, handle);
			}
			if (_object is T[] array)
			{
				if (_length < 0)
				{
					void* pointer2 = Unsafe.Add<T>(Unsafe.AsPointer(ref MemoryMarshal.GetReference<T>(array)), _index);
					return new MemoryHandle(pointer2);
				}
				GCHandle handle2 = GCHandle.Alloc(array, GCHandleType.Pinned);
				void* pointer3 = Unsafe.Add<T>((void*)handle2.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer3, handle2);
			}
			return default(MemoryHandle);
		}

		public T[] ToArray()
		{
			return Span.ToArray();
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			if (obj is ReadOnlyMemory<T> readOnlyMemory)
			{
				return readOnlyMemory.Equals(this);
			}
			if (obj is Memory<T> other)
			{
				return Equals(other);
			}
			return false;
		}

		public bool Equals(Memory<T> other)
		{
			if (_object == other._object && _index == other._index)
			{
				return _length == other._length;
			}
			return false;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			if (_object == null)
			{
				return 0;
			}
			int hashCode = _object.GetHashCode();
			int index = _index;
			int hashCode2 = index.GetHashCode();
			index = _length;
			return CombineHashCodes(hashCode, hashCode2, index.GetHashCode());
		}

		private static int CombineHashCodes(int left, int right)
		{
			return ((left << 5) + left) ^ right;
		}

		private static int CombineHashCodes(int h1, int h2, int h3)
		{
			return CombineHashCodes(CombineHashCodes(h1, h2), h3);
		}
	}
	internal sealed class MemoryDebugView<T>
	{
		private readonly ReadOnlyMemory<T> _memory;

		[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
		public T[] Items => _memory.ToArray();

		public MemoryDebugView(Memory<T> memory)
		{
			_memory = memory;
		}

		public MemoryDebugView(ReadOnlyMemory<T> memory)
		{
			_memory = memory;
		}
	}
	public static class MemoryExtensions
	{
		internal static readonly IntPtr StringAdjustment = MeasureStringAdjustment();

		public static ReadOnlySpan<char> Trim(this ReadOnlySpan<char> span)
		{
			return span.TrimStart().TrimEnd();
		}

		public static ReadOnlySpan<char> TrimStart(this ReadOnlySpan<char> span)
		{
			int i;
			for (i = 0; i < span.Length && char.IsWhiteSpace(span[i]); i++)
			{
			}
			return span.Slice(i);
		}

		public static ReadOnlySpan<char> TrimEnd(this ReadOnlySpan<char> span)
		{
			int num = span.Length - 1;
			while (num >= 0 && char.IsWhiteSpace(span[num]))
			{
				num--;
			}
			return span.Slice(0, num + 1);
		}

		public static ReadOnlySpan<char> Trim(this ReadOnlySpan<char> span, char trimChar)
		{
			return span.TrimStart(trimChar).TrimEnd(trimChar);
		}

		public static ReadOnlySpan<char> TrimStart(this ReadOnlySpan<char> span, char trimChar)
		{
			int i;
			for (i = 0; i < span.Length && span[i] == trimChar; i++)
			{
			}
			return span.Slice(i);
		}

		public static ReadOnlySpan<char> TrimEnd(this ReadOnlySpan<char> span, char trimChar)
		{
			int num = span.Length - 1;
			while (num >= 0 && span[num] == trimChar)
			{
				num--;
			}
			return span.Slice(0, num + 1);
		}

		public static ReadOnlySpan<char> Trim(this ReadOnlySpan<char> span, ReadOnlySpan<char> trimChars)
		{
			return span.TrimStart(trimChars).TrimEnd(trimChars);
		}

		public static ReadOnlySpan<char> TrimStart(this ReadOnlySpan<char> span, ReadOnlySpan<char> trimChars)
		{
			if (trimChars.IsEmpty)
			{
				return span.TrimStart();
			}
			int i;
			for (i = 0; i < span.Length; i++)
			{
				int num = 0;
				while (num < trimChars.Length)
				{
					if (span[i] != trimChars[num])
					{
						num++;
						continue;
					}
					goto IL_003c;
				}
				break;
				IL_003c:;
			}
			return span.Slice(i);
		}

		public static ReadOnlySpan<char> TrimEnd(this ReadOnlySpan<char> span, ReadOnlySpan<char> trimChars)
		{
			if (trimChars.IsEmpty)
			{
				return span.TrimEnd();
			}
			int num;
			for (num = span.Length - 1; num >= 0; num--)
			{
				int num2 = 0;
				while (num2 < trimChars.Length)
				{
					if (span[num] != trimChars[num2])
					{
						num2++;
						continue;
					}
					goto IL_0044;
				}
				break;
				IL_0044:;
			}
			return span.Slice(0, num + 1);
		}

		public static bool IsWhiteSpace(this ReadOnlySpan<char> span)
		{
			for (int i = 0; i < span.Length; i++)
			{
				if (!char.IsWhiteSpace(span[i]))
				{
					return false;
				}
			}
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOf<T>(this Span<T> span, T value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.IndexOf(ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, char>(ref value), span.Length);
			}
			return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), value, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOf<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length);
			}
			return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOf<T>(this Span<T> span, T value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.LastIndexOf(ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, char>(ref value), span.Length);
			}
			return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), value, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOf<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length);
			}
			return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool SequenceEqual<T>(this Span<T> span, ReadOnlySpan<T> other) where T : IEquatable<T>
		{
			int length = span.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length == other.Length)
				{
					return System.SpanHelpers.SequenceEqual(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), (NUInt)length * size);
				}
				return false;
			}
			if (length == other.Length)
			{
				return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other), length);
			}
			return false;
		}

		public static int SequenceCompareTo<T>(this Span<T> span, ReadOnlySpan<T> other) where T : IComparable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.SequenceCompareTo(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.SequenceCompareTo(ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			return System.SpanHelpers.SequenceCompareTo(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(other), other.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOf<T>(this ReadOnlySpan<T> span, T value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.IndexOf(ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, char>(ref value), span.Length);
			}
			return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), value, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOf<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length);
			}
			return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOf<T>(this ReadOnlySpan<T> span, T value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.LastIndexOf(ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, char>(ref value), span.Length);
			}
			return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), value, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOf<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length);
			}
			return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this Span<T> span, T value0, T value1) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), span.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this Span<T> span, T value0, T value1, T value2) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), Unsafe.As<T, byte>(ref value2), span.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this Span<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), span.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1, T value2) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), Unsafe.As<T, byte>(ref value2), span.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this Span<T> span, T value0, T value1) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), span.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this Span<T> span, T value0, T value1, T value2) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), Unsafe.As<T, byte>(ref value2), span.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this Span<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), span.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1, T value2) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), Unsafe.As<T, byte>(ref value2), span.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool SequenceEqual<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other) where T : IEquatable<T>
		{
			int length = span.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length == other.Length)
				{
					return System.SpanHelpers.SequenceEqual(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), (NUInt)length * size);
				}
				return false;
			}
			if (length == other.Length)
			{
				return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other), length);
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int SequenceCompareTo<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other) where T : IComparable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.SequenceCompareTo(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.SequenceCompareTo(ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			return System.SpanHelpers.SequenceCompareTo(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(other), other.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool StartsWith<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			int length = value.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length <= span.Length)
				{
					return System.SpanHelpers.SequenceEqual(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length * size);
				}
				return false;
			}
			if (length <= span.Length)
			{
				return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(value), length);
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool StartsWith<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			int length = value.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length <= span.Length)
				{
					return System.SpanHelpers.SequenceEqual(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length * size);
				}
				return false;
			}
			if (length <= span.Length)
			{
				return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(value), length);
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool EndsWith<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			int length = span.Length;
			int length2 = value.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length2 <= length)
				{
					return System.SpanHelpers.SequenceEqual(ref Unsafe.As<T, byte>(ref Unsafe.Add(ref MemoryMarshal.GetReference(span), length - length2)), ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length2 * size);
				}
				return false;
			}
			if (length2 <= length)
			{
				return System.SpanHelpers.SequenceEqual(ref Unsafe.Add(ref MemoryMarshal.GetReference(span), length - length2), ref MemoryMarshal.GetReference(value), length2);
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool EndsWith<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			int length = span.Length;
			int length2 = value.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length2 <= length)
				{
					return System.SpanHelpers.SequenceEqual(ref Unsafe.As<T, byte>(ref Unsafe.Add(ref MemoryMarshal.GetReference(span), length - length2)), ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length2 * size);
				}
				return false;
			}
			if (length2 <= length)
			{
				return System.SpanHelpers.SequenceEqual(ref Unsafe.Add(ref MemoryMarshal.GetReference(span), length - length2), ref MemoryMarshal.GetReference(value), length2);
			}
			return false;
		}

		public static void Reverse<T>(this Span<T> span)
		{
			ref T reference = ref MemoryMarshal.GetReference(span);
			int num = 0;
			int num2 = span.Length - 1;
			while (num < num2)
			{
				T val = Unsafe.Add(ref reference, num);
				Unsafe.Add(ref reference, num) = Unsafe.Add(ref reference, num2);
				Unsafe.Add(ref reference, num2) = val;
				num++;
				num2--;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this T[] array)
		{
			return new Span<T>(array);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this T[] array, int start, int length)
		{
			return new Span<T>(array, start, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this ArraySegment<T> segment)
		{
			return new Span<T>(segment.Array, segment.Offset, segment.Count);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this ArraySegment<T> segment, int start)
		{
			if ((uint)start > segment.Count)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new Span<T>(segment.Array, segment.Offset + start, segment.Count - start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this ArraySegment<T> segment, int start, int length)
		{
			if ((uint)start > segment.Count)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			if ((uint)length > segment.Count - start)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length);
			}
			return new Span<T>(segment.Array, segment.Offset + start, length);
		}

		public static Memory<T> AsMemory<T>(this T[] array)
		{
			return new Memory<T>(array);
		}

		public static Memory<T> AsMemory<T>(this T[] array, int start)
		{
			return new Memory<T>(array, start);
		}

		public static Memory<T> AsMemory<T>(this T[] array, int start, int length)
		{
			return new Memory<T>(array, start, length);
		}

		public static Memory<T> AsMemory<T>(this ArraySegment<T> segment)
		{
			return new Memory<T>(segment.Array, segment.Offset, segment.Count);
		}

		public static Memory<T> AsMemory<T>(this ArraySegment<T> segment, int start)
		{
			if ((uint)start > segment.Count)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new Memory<T>(segment.Array, segment.Offset + start, segment.Count - start);
		}

		public static Memory<T> AsMemory<T>(this ArraySegment<T> segment, int start, int length)
		{
			if ((uint)start > segment.Count)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			if ((uint)length > segment.Count - start)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length);
			}
			return new Memory<T>(segment.Array, segment.Offset + start, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void CopyTo<T>(this T[] source, Span<T> destination)
		{
			new ReadOnlySpan<T>(source).CopyTo(destination);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void CopyTo<T>(this T[] source, Memory<T> destination)
		{
			source.CopyTo(destination.Span);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool Overlaps<T>(this Span<T> span, ReadOnlySpan<T> other)
		{
			return ((ReadOnlySpan<T>)span).Overlaps(other);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool Overlaps<T>(this Span<T> span, ReadOnlySpan<T> other, out int elementOffset)
		{
			return ((ReadOnlySpan<T>)span).Overlaps(other, out elementOffset);
		}

		public static bool Overlaps<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other)
		{
			if (span.IsEmpty || other.IsEmpty)
			{
				return false;
			}
			IntPtr intPtr = Unsafe.ByteOffset(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other));
			if (Unsafe.SizeOf<IntPtr>() == 4)
			{
				if ((uint)(int)intPtr >= (uint)(span.Length * Unsafe.SizeOf<T>()))
				{
					return (uint)(int)intPtr > (uint)(-(other.Length * Unsafe.SizeOf<T>()));
				}
				return true;
			}
			if ((ulong)(long)intPtr >= (ulong)((long)span.Length * (long)Unsafe.SizeOf<T>()))
			{
				return (ulong)(long)intPtr > (ulong)(-((long)other.Length * (long)Unsafe.SizeOf<T>()));
			}
			return true;
		}

		public static bool Overlaps<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other, out int elementOffset)
		{
			if (span.IsEmpty || other.IsEmpty)
			{
				elementOffset = 0;
				return false;
			}
			IntPtr intPtr = Unsafe.ByteOffset(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other));
			if (Unsafe.SizeOf<IntPtr>() == 4)
			{
				if ((uint)(int)intPtr < (uint)(span.Length * Unsafe.SizeOf<T>()) || (uint)(int)intPtr > (uint)(-(other.Length * Unsafe.SizeOf<T>())))
				{
					if ((int)intPtr % Unsafe.SizeOf<T>() != 0)
					{
						System.ThrowHelper.ThrowArgumentException_OverlapAlignmentMismatch();
					}
					elementOffset = (int)intPtr / Unsafe.SizeOf<T>();
					return true;
				}
				elementOffset = 0;
				return false;
			}
			if ((ulong)(long)intPtr < (ulong)((long)span.Length * (long)Unsafe.SizeOf<T>()) || (ulong)(long)intPtr > (ulong)(-((long)other.Length * (long)Unsafe.SizeOf<T>())))
			{
				if ((long)intPtr % Unsafe.SizeOf<T>() != 0L)
				{
					System.ThrowHelper.ThrowArgumentException_OverlapAlignmentMismatch();
				}
				elementOffset = (int)((long)intPtr / Unsafe.SizeOf<T>());
				return true;
			}
			elementOffset = 0;
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T>(this Span<T> span, IComparable<T> comparable)
		{
			return span.BinarySearch<T, IComparable<T>>(comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparable>(this Span<T> span, TComparable comparable) where TComparable : IComparable<T>
		{
			return BinarySearch((ReadOnlySpan<T>)span, comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparer>(this Span<T> span, T value, TComparer comparer) where TComparer : IComparer<T>
		{
			return ((ReadOnlySpan<T>)span).BinarySearch(value, comparer);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T>(this ReadOnlySpan<T> span, IComparable<T> comparable)
		{
			return MemoryExtensions.BinarySearch<T, IComparable<T>>(span, comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparable>(this ReadOnlySpan<T> span, TComparable comparable) where TComparable : IComparable<T>
		{
			return System.SpanHelpers.BinarySearch(span, comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparer>(this ReadOnlySpan<T> span, T value, TComparer comparer) where TComparer : IComparer<T>
		{
			if (comparer == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.comparer);
			}
			System.SpanHelpers.ComparerComparable<T, TComparer> comparable = new System.SpanHelpers.ComparerComparable<T, TComparer>(value, comparer);
			return BinarySearch(span, comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static bool IsTypeComparableAsBytes<T>(out NUInt size)
		{
			if (typeof(T) == typeof(byte) || typeof(T) == typeof(sbyte))
			{
				size = (NUInt)1;
				return true;
			}
			if (typeof(T) == typeof(char) || typeof(T) == typeof(short) || typeof(T) == typeof(ushort))
			{
				size = (NUInt)2;
				return true;
			}
			if (typeof(T) == typeof(int) || typeof(T) == typeof(uint))
			{
				size = (NUInt)4;
				return true;
			}
			if (typeof(T) == typeof(long) || typeof(T) == typeof(ulong))
			{
				size = (NUInt)8;
				return true;
			}
			size = default(NUInt);
			return false;
		}

		public static Span<T> AsSpan<T>(this T[] array, int start)
		{
			return Span<T>.Create(array, start);
		}

		public static bool Contains(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
		{
			return span.IndexOf(value, comparisonType) >= 0;
		}

		public static bool Equals(this ReadOnlySpan<char> span, ReadOnlySpan<char> other, StringComparison comparisonType)
		{
			switch (comparisonType)
			{
			case StringComparison.Ordinal:
				return span.SequenceEqual(other);
			case StringComparison.OrdinalIgnoreCase:
				if (span.Length != other.Length)
				{
					return false;
				}
				return EqualsOrdinalIgnoreCase(span, other);
			default:
				return span.ToString().Equals(other.ToString(), comparisonType);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static bool EqualsOrdinalIgnoreCase(ReadOnlySpan<char> span, ReadOnlySpan<char> other)
		{
			if (other.Length == 0)
			{
				return true;
			}
			return CompareToOrdinalIgnoreCase(span, other) == 0;
		}

		public static int CompareTo(this ReadOnlySpan<char> span, ReadOnlySpan<char> other, StringComparison comparisonType)
		{
			return comparisonType switch
			{
				StringComparison.Ordinal => span.SequenceCompareTo(other), 
				StringComparison.OrdinalIgnoreCase => CompareToOrdinalIgnoreCase(span, other), 
				_ => string.Compare(span.ToString(), other.ToString(), comparisonType), 
			};
		}

		private unsafe static int CompareToOrdinalIgnoreCase(ReadOnlySpan<char> strA, ReadOnlySpan<char> strB)
		{
			int num = Math.Min(strA.Length, strB.Length);
			int num2 = num;
			fixed (char* ptr = &MemoryMarshal.GetReference(strA))
			{
				fixed (char* ptr3 = &MemoryMarshal.GetReference(strB))
				{
					char* ptr2 = ptr;
					char* ptr4 = ptr3;
					while (num != 0 && *ptr2 <= '\u007f' && *ptr4 <= '\u007f')
					{
						int num3 = *ptr2;
						int num4 = *ptr4;
						if (num3 == num4)
						{
							ptr2++;
							ptr4++;
							num--;
							continue;
						}
						if ((uint)(num3 - 97) <= 25u)
						{
							num3 -= 32;
						}
						if ((uint)(num4 - 97) <= 25u)
						{
							num4 -= 32;
						}
						if (num3 != num4)
						{
							return num3 - num4;
						}
						ptr2++;
						ptr4++;
						num--;
					}
					if (num == 0)
					{
						return strA.Length - strB.Length;
					}
					num2 -= num;
					return string.Compare(strA.Slice(num2).ToString(), strB.Slice(num2).ToString(), StringComparison.OrdinalIgnoreCase);
				}
			}
		}

		public static int IndexOf(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
		{
			if (comparisonType == StringComparison.Ordinal)
			{
				return span.IndexOf(value);
			}
			return span.ToString().IndexOf(value.ToString(), comparisonType);
		}

		public static int ToLower(this ReadOnlySpan<char> source, Span<char> destination, CultureInfo culture)
		{
			if (culture == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.culture);
			}
			if (destination.Length < source.Length)
			{
				return -1;
			}
			string text = source.ToString();
			string text2 = text.ToLower(culture);
			AsSpan(text2).CopyTo(destination);
			return source.Length;
		}

		public static int ToLowerInvariant(this ReadOnlySpan<char> source, Span<char> destination)
		{
			return source.ToLower(destination, CultureInfo.InvariantCulture);
		}

		public static int ToUpper(this ReadOnlySpan<char> source, Span<char> destination, CultureInfo culture)
		{
			if (culture == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.culture);
			}
			if (destination.Length < source.Length)
			{
				return -1;
			}
			string text = source.ToString();
			string text2 = text.ToUpper(culture);
			AsSpan(text2).CopyTo(destination);
			return source.Length;
		}

		public static int ToUpperInvariant(this ReadOnlySpan<char> source, Span<char> destination)
		{
			return source.ToUpper(destination, CultureInfo.InvariantCulture);
		}

		public static bool EndsWith(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
		{
			switch (comparisonType)
			{
			case StringComparison.Ordinal:
				return span.EndsWith(value);
			case StringComparison.OrdinalIgnoreCase:
				if (value.Length <= span.Length)
				{
					return EqualsOrdinalIgnoreCase(span.Slice(span.Length - value.Length), value);
				}
				return false;
			default:
			{
				string text = span.ToString();
				string value2 = value.ToString();
				return text.EndsWith(value2, comparisonType);
			}
			}
		}

		public static bool StartsWith(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
		{
			switch (comparisonType)
			{
			case StringComparison.Ordinal:
				return span.StartsWith(value);
			case StringComparison.OrdinalIgnoreCase:
				if (value.Length <= span.Length)
				{
					return EqualsOrdinalIgnoreCase(span.Slice(0, value.Length), value);
				}
				return false;
			default:
			{
				string text = span.ToString();
				string value2 = value.ToString();
				return text.StartsWith(value2, comparisonType);
			}
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ReadOnlySpan<char> AsSpan(this string text)
		{
			if (text == null)
			{
				return default(ReadOnlySpan<char>);
			}
			return new ReadOnlySpan<char>(Unsafe.As<Pinnable<char>>(text), StringAdjustment, text.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ReadOnlySpan<char> AsSpan(this string text, int start)
		{
			if (text == null)
			{
				if (start != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(ReadOnlySpan<char>);
			}
			if ((uint)start > (uint)text.Length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlySpan<char>(Unsafe.As<Pinnable<char>>(text), StringAdjustment + start * 2, text.Length - start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ReadOnlySpan<char> AsSpan(this string text, int start, int length)
		{
			if (text == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(ReadOnlySpan<char>);
			}
			if ((uint)start > (uint)text.Length || (uint)length > (uint)(text.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlySpan<char>(Unsafe.As<Pinnable<char>>(text), StringAdjustment + start * 2, length);
		}

		public static ReadOnlyMemory<char> AsMemory(this string text)
		{
			if (text == null)
			{
				return default(ReadOnlyMemory<char>);
			}
			return new ReadOnlyMemory<char>(text, 0, text.Length);
		}

		public static ReadOnlyMemory<char> AsMemory(this string text, int start)
		{
			if (text == null)
			{
				if (start != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(ReadOnlyMemory<char>);
			}
			if ((uint)start > (uint)text.Length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlyMemory<char>(text, start, text.Length - start);
		}

		public static ReadOnlyMemory<char> AsMemory(this string text, int start, int length)
		{
			if (text == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(ReadOnlyMemory<char>);
			}
			if ((uint)start > (uint)text.Length || (uint)length > (uint)(text.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlyMemory<char>(text, start, length);
		}

		private unsafe static IntPtr MeasureStringAdjustment()
		{
			string text = "a";
			fixed (char* source = text)
			{
				return Unsafe.ByteOffset(ref Unsafe.As<Pinnable<char>>(text).Data, ref Unsafe.AsRef<char>(source));
			}
		}
	}
	internal struct MutableDecimal
	{
		public uint Flags;

		public uint High;

		public uint Low;

		public uint Mid;

		private const uint SignMask = 2147483648u;

		private const uint ScaleMask = 16711680u;

		private const int ScaleShift = 16;

		public bool IsNegative
		{
			get
			{
				return (Flags & 0x80000000u) != 0;
			}
			set
			{
				Flags = (Flags & 0x7FFFFFFFu) | (value ? 2147483648u : 0u);
			}
		}

		public int Scale
		{
			get
			{
				return (byte)(Flags >> 16);
			}
			set
			{
				Flags = (Flags & 0xFF00FFFFu) | (uint)(value << 16);
			}
		}
	}
	internal struct NUInt
	{
		private unsafe readonly void* _value;

		private unsafe NUInt(uint value)
		{
			_value = (void*)value;
		}

		private unsafe NUInt(ulong value)
		{
			_value = (void*)value;
		}

		public static implicit operator NUInt(uint value)
		{
			return new NUInt(value);
		}

		public unsafe static implicit operator IntPtr(NUInt value)
		{
			return (IntPtr)value._value;
		}

		public static explicit operator NUInt(int value)
		{
			return new NUInt((uint)value);
		}

		public unsafe static explicit operator void*(NUInt value)
		{
			return value._value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static NUInt operator *(NUInt left, NUInt right)
		{
			if (sizeof(IntPtr) != 4)
			{
				return new NUInt((ulong)left._value * (ulong)right._value);
			}
			return new NUInt((uint)((int)left._value * (int)right._value));
		}
	}
	internal static class DecimalDecCalc
	{
		private static uint D32DivMod1E9(uint hi32, ref uint lo32)
		{
			ulong num = ((ulong)hi32 << 32) | lo32;
			lo32 = (uint)(num / 1000000000);
			return (uint)(num % 1000000000);
		}

		internal static uint DecDivMod1E9(ref MutableDecimal value)
		{
			return D32DivMod1E9(D32DivMod1E9(D32DivMod1E9(0u, ref value.High), ref value.Mid), ref value.Low);
		}

		internal static void DecAddInt32(ref MutableDecimal value, uint i)
		{
			if (D32AddCarry(ref value.Low, i) && D32AddCarry(ref value.Mid, 1u))
			{
				D32AddCarry(ref value.High, 1u);
			}
		}

		private static bool D32AddCarry(ref uint value, uint i)
		{
			uint num = value;
			uint num2 = (value = num + i);
			if (num2 >= num)
			{
				return num2 < i;
			}
			return true;
		}

		internal static void DecMul10(ref MutableDecimal value)
		{
			MutableDecimal d = value;
			DecShiftLeft(ref value);
			DecShiftLeft(ref value);
			DecAdd(ref value, d);
			DecShiftLeft(ref value);
		}

		private static void DecShiftLeft(ref MutableDecimal value)
		{
			uint num = (((value.Low & 0x80000000u) != 0) ? 1u : 0u);
			uint num2 = (((value.Mid & 0x80000000u) != 0) ? 1u : 0u);
			value.Low <<= 1;
			value.Mid = (value.Mid << 1) | num;
			value.High = (value.High << 1) | num2;
		}

		private static void DecAdd(ref MutableDecimal value, MutableDecimal d)
		{
			if (D32AddCarry(ref value.Low, d.Low) && D32AddCarry(ref value.Mid, 1u))
			{
				D32AddCarry(ref value.High, 1u);
			}
			if (D32AddCarry(ref value.Mid, d.Mid))
			{
				D32AddCarry(ref value.High, 1u);
			}
			D32AddCarry(ref value.High, d.High);
		}
	}
	internal static class Number
	{
		private static class DoubleHelper
		{
			public unsafe static uint Exponent(double d)
			{
				return (*(uint*)((byte*)(&d) + 4) >> 20) & 0x7FFu;
			}

			public unsafe static ulong Mantissa(double d)
			{
				return *(uint*)(&d) | ((ulong)(uint)(*(int*)((byte*)(&d) + 4) & 0xFFFFF) << 32);
			}

			public unsafe static bool Sign(double d)
			{
				return *(uint*)((byte*)(&d) + 4) >> 31 != 0;
			}
		}

		internal const int DECIMAL_PRECISION = 29;

		private static readonly ulong[] s_rgval64Power10 = new ulong[30]
		{
			11529215046068469760uL, 14411518807585587200uL, 18014398509481984000uL, 11258999068426240000uL, 14073748835532800000uL, 17592186044416000000uL, 10995116277760000000uL, 13743895347200000000uL, 17179869184000000000uL, 10737418240000000000uL,
			13421772800000000000uL, 16777216000000000000uL, 10485760000000000000uL, 13107200000000000000uL, 16384000000000000000uL, 14757395258967641293uL, 11805916207174113035uL, 9444732965739290428uL, 15111572745182864686uL, 12089258196146291749uL,
			9671406556917033399uL, 15474250491067253438uL, 12379400392853802751uL, 9903520314283042201uL, 15845632502852867522uL, 12676506002282294018uL, 10141204801825835215uL, 16225927682921336344uL, 12980742146337069075uL, 10384593717069655260uL
		};

		private static readonly sbyte[] s_rgexp64Power10 = new sbyte[15]
		{
			4, 7, 10, 14, 17, 20, 24, 27, 30, 34,
			37, 40, 44, 47, 50
		};

		private static readonly ulong[] s_rgval64Power10By16 = new ulong[42]
		{
			10240000000000000000uL, 11368683772161602974uL, 12621774483536188886uL, 14012984643248170708uL, 15557538194652854266uL, 17272337110188889248uL, 9588073174409622172uL, 10644899600020376798uL, 11818212630765741798uL, 13120851772591970216uL,
			14567071740625403792uL, 16172698447808779622uL, 17955302187076837696uL, 9967194951097567532uL, 11065809325636130658uL, 12285516299433008778uL, 13639663065038175358uL, 15143067982934716296uL, 16812182738118149112uL, 9332636185032188787uL,
			10361307573072618722uL, 16615349947311448416uL, 14965776766268445891uL, 13479973333575319909uL, 12141680576410806707uL, 10936253623915059637uL, 9850501549098619819uL, 17745086042373215136uL, 15983352577617880260uL, 14396524142538228461uL,
			12967236152753103031uL, 11679847981112819795uL, 10520271803096747049uL, 9475818434452569218uL, 17070116948172427008uL, 15375394465392026135uL, 13848924157002783096uL, 12474001934591998882uL, 11235582092889474480uL, 10120112665365530972uL,
			18230774251475056952uL, 16420821625123739930uL
		};

		private static readonly short[] s_rgexp64Power10By16 = new short[21]
		{
			54, 107, 160, 213, 266, 319, 373, 426, 479, 532,
			585, 638, 691, 745, 798, 851, 904, 957, 1010, 1064,
			1117
		};

		public static void RoundNumber(ref NumberBuffer number, int pos)
		{
			Span<byte> digits = number.Digits;
			int i;
			for (i = 0; i < pos && digits[i] != 0; i++)
			{
			}
			if (i == pos && digits[i] >= 53)
			{
				while (i > 0 && digits[i - 1] == 57)
				{
					i--;
				}
				if (i > 0)
				{
					digits[i - 1]++;
				}
				else
				{
					number.Scale++;
					digits[0] = 49;
					i = 1;
				}
			}
			else
			{
				while (i > 0 && digits[i - 1] == 48)
				{
					i--;
				}
			}
			if (i == 0)
			{
				number.Scale = 0;
				number.IsNegative = false;
			}
			digits[i] = 0;
		}

		internal static bool NumberBufferToDouble(ref NumberBuffer number, out double value)
		{
			double num = NumberToDouble(ref number);
			uint num2 = DoubleHelper.Exponent(num);
			ulong num3 = DoubleHelper.Mantissa(num);
			switch (num2)
			{
			case 2047u:
				value = 0.0;
				return false;
			case 0u:
				if (num3 == 0L)
				{
					num = 0.0;
				}
				break;
			}
			value = num;
			return true;
		}

		public unsafe static bool NumberBufferToDecimal(ref NumberBuffer number, ref decimal value)
		{
			MutableDecimal source = default(MutableDecimal);
			byte* ptr = number.UnsafeDigits;
			int num = number.Scale;
			if (*ptr == 0)
			{
				if (num > 0)
				{
					num = 0;
				}
			}
			else
			{
				if (num > 29)
				{
					return false;
				}
				while ((num > 0 || (*ptr != 0 && num > -28)) && (source.High < 429496729 || (source.High == 429496729 && (source.Mid < 2576980377u || (source.Mid == 2576980377u && (source.Low < 2576980377u || (source.Low == 2576980377u && *ptr <= 53)))))))
				{
					DecimalDecCalc.DecMul10(ref source);
					if (*ptr != 0)
					{
						DecimalDecCalc.DecAddInt32(ref source, (uint)(*(ptr++) - 48));
					}
					num--;
				}
				if (*(ptr++) >= 53)
				{
					bool flag = true;
					if (*(ptr - 1) == 53 && *(ptr - 2) % 2 == 0)
					{
						int num2 = 20;
						while (*ptr == 48 && num2 != 0)
						{
							ptr++;
							num2--;
						}
						if (*ptr == 0 || num2 == 0)
						{
							flag = false;
						}
					}
					if (flag)
					{
						DecimalDecCalc.DecAddInt32(ref source, 1u);
						if ((source.High | source.Mid | source.Low) == 0)
						{
							source.High = 429496729u;
							source.Mid = 2576980377u;
							source.Low = 2576980378u;
							num++;
						}
					}
				}
			}
			if (num > 0)
			{
				return false;
			}
			if (num <= -29)
			{
				source.High = 0u;
				source.Low = 0u;
				source.Mid = 0u;
				source.Scale = 28;
			}
			else
			{
				source.Scale = -num;
			}
			source.IsNegative = number.IsNegative;
			value = Unsafe.As<MutableDecimal, decimal>(ref source);
			return true;
		}

		public static void DecimalToNumber(decimal value, ref NumberBuffer number)
		{
			ref MutableDecimal reference = ref Unsafe.As<decimal, MutableDecimal>(ref value);
			Span<byte> digits = number.Digits;
			number.IsNegative = reference.IsNegative;
			int num = 29;
			while ((reference.Mid != 0) | (reference.High != 0))
			{
				uint num2 = DecimalDecCalc.DecDivMod1E9(ref reference);
				for (int i = 0; i < 9; i++)
				{
					digits[--num] = (byte)(num2 % 10 + 48);
					num2 /= 10;
				}
			}
			for (uint num3 = reference.Low; num3 != 0; num3 /= 10)
			{
				digits[--num] = (byte)(num3 % 10 + 48);
			}
			int num4 = 29 - num;
			number.Scale = num4 - reference.Scale;
			Span<byte> digits2 = number.Digits;
			int index = 0;
			while (--num4 >= 0)
			{
				digits2[index++] = digits[num++];
			}
			digits2[index] = 0;
		}

		private static uint DigitsToInt(ReadOnlySpan<byte> digits, int count)
		{
			uint value;
			int bytesConsumed;
			bool flag = Utf8Parser.TryParse(digits.Slice(0, count), out value, out bytesConsumed, 'D');
			return value;
		}

		private static ulong Mul32x32To64(uint a, uint b)
		{
			return (ulong)a * (ulong)b;
		}

		private static ulong Mul64Lossy(ulong a, ulong b, ref int pexp)
		{
			ulong num = Mul32x32To64((uint)(a >> 32), (uint)(b >> 32)) + (Mul32x32To64((uint)(a >> 32), (uint)b) >> 32) + (Mul32x32To64((uint)a, (uint)(b >> 32)) >> 32);
			if ((num & 0x8000000000000000uL) == 0L)
			{
				num <<= 1;
				pexp--;
			}
			return num;
		}

		private static int abs(int value)
		{
			if (value < 0)
			{
				return -value;
			}
			return value;
		}

		private unsafe static double NumberToDouble(ref NumberBuffer number)
		{
			ReadOnlySpan<byte> digits = number.Digits;
			int i = 0;
			int numDigits = number.NumDigits;
			int num = numDigits;
			for (; digits[i] == 48; i++)
			{
				num--;
			}
			if (num == 0)
			{
				return 0.0;
			}
			int num2 = Math.Min(num, 9);
			num -= num2;
			ulong num3 = DigitsToInt(digits, num2);
			if (num > 0)
			{
				num2 = Math.Min(num, 9);
				num -= num2;
				uint b = (uint)(s_rgval64Power10[num2 - 1] >> 64 - s_rgexp64Power10[num2 - 1]);
				num3 = Mul32x32To64((uint)num3, b) + DigitsToInt(digits.Slice(9), num2);
			}
			int num4 = number.Scale - (numDigits - num);
			int num5 = abs(num4);
			if (num5 >= 352)
			{
				ulong num6 = ((num4 > 0) ? 9218868437227405312uL : 0);
				if (number.IsNegative)
				{
					num6 |= 0x8000000000000000uL;
				}
				return *(double*)(&num6);
			}
			int pexp = 64;
			if ((num3 & 0xFFFFFFFF00000000uL) == 0L)
			{
				num3 <<= 32;
				pexp -= 32;
			}
			if ((num3 & 0xFFFF000000000000uL) == 0L)
			{
				num3 <<= 16;
				pexp -= 16;
			}
			if ((num3 & 0xFF00000000000000uL) == 0L)
			{
				num3 <<= 8;
				pexp -= 8;
			}
			if ((num3 & 0xF000000000000000uL) == 0L)
			{
				num3 <<= 4;
				pexp -= 4;
			}
			if ((num3 & 0xC000000000000000uL) == 0L)
			{
				num3 <<= 2;
				pexp -= 2;
			}
			if ((num3 & 0x8000000000000000uL) == 0L)
			{
				num3 <<= 1;
				pexp--;
			}
			int num7 = num5 & 0xF;
			if (num7 != 0)
			{
				int num8 = s_rgexp64Power10[num7 - 1];
				pexp += ((num4 < 0) ? (-num8 + 1) : num8);
				ulong b2 = s_rgval64Power10[num7 + ((num4 < 0) ? 15 : 0) - 1];
				num3 = Mul64Lossy(num3, b2, ref pexp);
			}
			num7 = num5 >> 4;
			if (num7 != 0)
			{
				int num9 = s_rgexp64Power10By16[num7 - 1];
				pexp += ((num4 < 0) ? (-num9 + 1) : num9);
				ulong b3 = s_rgval64Power10By16[num7 + ((num4 < 0) ? 21 : 0) - 1];
				num3 = Mul64Lossy(num3, b3, ref pexp);
			}
			if (((uint)(int)num3 & 0x400u) != 0)
			{
				ulong num10 = num3 + 1023 + (ulong)(((int)num3 >> 11) & 1);
				if (num10 < num3)
				{
					num10 = (num10 >> 1) | 0x8000000000000000uL;
					pexp++;
				}
				num3 = num10;
			}
			pexp += 1022;
			num3 = ((pexp <= 0) ? ((pexp == -52 && num3 >= 9223372036854775896uL) ? 1 : ((pexp > -52) ? (num3 >> -pexp + 11 + 1) : 0)) : ((pexp < 2047) ? ((ulong)((long)pexp << 52) + ((num3 >> 11) & 0xFFFFFFFFFFFFFL)) : 9218868437227405312uL));
			if (number.IsNegative)
			{
				num3 |= 0x8000000000000000uL;
			}
			return *(double*)(&num3);
		}
	}
	internal ref struct NumberBuffer
	{
		public int Scale;

		public bool IsNegative;

		public const int BufferSize = 51;

		private byte _b0;

		private byte _b1;

		private byte _b2;

		private byte _b3;

		private byte _b4;

		private byte _b5;

		private byte _b6;

		private byte _b7;

		private byte _b8;

		private byte _b9;

		private byte _b10;

		private byte _b11;

		private byte _b12;

		private byte _b13;

		private byte _b14;

		private byte _b15;

		private byte _b16;

		private byte _b17;

		private byte _b18;

		private byte _b19;

		private byte _b20;

		private byte _b21;

		private byte _b22;

		private byte _b23;

		private byte _b24;

		private byte _b25;

		private byte _b26;

		private byte _b27;

		private byte _b28;

		private byte _b29;

		private byte _b30;

		private byte _b31;

		private byte _b32;

		private byte _b33;

		private byte _b34;

		private byte _b35;

		private byte _b36;

		private byte _b37;

		private byte _b38;

		private byte _b39;

		private byte _b40;

		private byte _b41;

		private byte _b42;

		private byte _b43;

		private byte _b44;

		private byte _b45;

		private byte _b46;

		private byte _b47;

		private byte _b48;

		private byte _b49;

		private byte _b50;

		public unsafe Span<byte> Digits => new Span<byte>(Unsafe.AsPointer(ref _b0), 51);

		public unsafe byte* UnsafeDigits => (byte*)Unsafe.AsPointer(ref _b0);

		public int NumDigits => Digits.IndexOf<byte>(0);

		[Conditional("DEBUG")]
		public void CheckConsistency()
		{
		}

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append('[');
			stringBuilder.Append('"');
			Span<byte> digits = Digits;
			for (int i = 0; i < 51; i++)
			{
				byte b = digits[i];
				if (b == 0)
				{
					break;
				}
				stringBuilder.Append((char)b);
			}
			stringBuilder.Append('"');
			stringBuilder.Append(", Scale = " + Scale);
			stringBuilder.Append(", IsNegative   = " + IsNegative);
			stringBuilder.Append(']');
			return stringBuilder.ToString();
		}
	}
	[StructLayout(LayoutKind.Sequential)]
	internal sealed class Pinnable<T>
	{
		public T Data;
	}
	[DebuggerTypeProxy(typeof(System.MemoryDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	public readonly struct ReadOnlyMemory<T>
	{
		private readonly object _object;

		private readonly int _index;

		private readonly int _length;

		internal const int RemoveFlagsBitMask = int.MaxValue;

		public static ReadOnlyMemory<T> Empty => default(ReadOnlyMemory<T>);

		public int Length => _length & 0x7FFFFFFF;

		public bool IsEmpty => (_length & 0x7FFFFFFF) == 0;

		public ReadOnlySpan<T> Span
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				if (_index < 0)
				{
					return ((MemoryManager<T>)_object).GetSpan().Slice(_index & 0x7FFFFFFF, _length);
				}
				ReadOnlySpan<T> result;
				if (typeof(T) == typeof(char) && _object is string text)
				{
					result = new ReadOnlySpan<T>(Unsafe.As<Pinnable<T>>(text), MemoryExtensions.StringAdjustment, text.Length);
					return result.Slice(_index, _length);
				}
				if (_object != null)
				{
					return new ReadOnlySpan<T>((T[])_object, _index, _length & 0x7FFFFFFF);
				}
				result = default(ReadOnlySpan<T>);
				return result;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlyMemory(T[] array)
		{
			if (array == null)
			{
				this = default(ReadOnlyMemory<T>);
				return;
			}
			_object = array;
			_index = 0;
			_length = array.Length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlyMemory(T[] array, int start, int length)
		{
			if (array == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException();
				}
				this = default(ReadOnlyMemory<T>);
				return;
			}
			if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = array;
			_index = start;
			_length = length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal ReadOnlyMemory(object obj, int start, int length)
		{
			_object = obj;
			_index = start;
			_length = length;
		}

		public static implicit operator ReadOnlyMemory<T>(T[] array)
		{
			return new ReadOnlyMemory<T>(array);
		}

		public static implicit operator ReadOnlyMemory<T>(ArraySegment<T> segment)
		{
			return new ReadOnlyMemory<T>(segment.Array, segment.Offset, segment.Count);
		}

		public override string ToString()
		{
			if (typeof(T) == typeof(char))
			{
				if (!(_object is string text))
				{
					return Span.ToString();
				}
				return text.Substring(_index, _length & 0x7FFFFFFF);
			}
			return $"System.ReadOnlyMemory<{typeof(T).Name}>[{_length & 0x7FFFFFFF}]";
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlyMemory<T> Slice(int start)
		{
			int length = _length;
			int num = length & 0x7FFFFFFF;
			if ((uint)start > (uint)num)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlyMemory<T>(_object, _index + start, length - start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlyMemory<T> Slice(int start, int length)
		{
			int length2 = _length;
			int num = _length & 0x7FFFFFFF;
			if ((uint)start > (uint)num || (uint)length > (uint)(num - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlyMemory<T>(_object, _index + start, length | (length2 & int.MinValue));
		}

		public void CopyTo(Memory<T> destination)
		{
			Span.CopyTo(destination.Span);
		}

		public bool TryCopyTo(Memory<T> destination)
		{
			return Span.TryCopyTo(destination.Span);
		}

		public unsafe MemoryHandle Pin()
		{
			if (_index < 0)
			{
				return ((MemoryManager<T>)_object).Pin(_index & 0x7FFFFFFF);
			}
			if (typeof(T) == typeof(char) && _object is string value)
			{
				GCHandle handle = GCHandle.Alloc(value, GCHandleType.Pinned);
				void* pointer = Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer, handle);
			}
			if (_object is T[] array)
			{
				if (_length < 0)
				{
					void* pointer2 = Unsafe.Add<T>(Unsafe.AsPointer(ref MemoryMarshal.GetReference<T>(array)), _index);
					return new MemoryHandle(pointer2);
				}
				GCHandle handle2 = GCHandle.Alloc(array, GCHandleType.Pinned);
				void* pointer3 = Unsafe.Add<T>((void*)handle2.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer3, handle2);
			}
			return default(MemoryHandle);
		}

		public T[] ToArray()
		{
			return Span.ToArray();
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			if (obj is ReadOnlyMemory<T> other)
			{
				return Equals(other);
			}
			if (obj is Memory<T> memory)
			{
				return Equals(memory);
			}
			return false;
		}

		public bool Equals(ReadOnlyMemory<T> other)
		{
			if (_object == other._object && _index == other._index)
			{
				return _length == other._length;
			}
			return false;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			if (_object == null)
			{
				return 0;
			}
			int hashCode = _object.GetHashCode();
			int index = _index;
			int hashCode2 = index.GetHashCode();
			index = _length;
			return CombineHashCodes(hashCode, hashCode2, index.GetHashCode());
		}

		private static int CombineHashCodes(int left, int right)
		{
			return ((left << 5) + left) ^ right;
		}

		private static int CombineHashCodes(int h1, int h2, int h3)
		{
			return CombineHashCodes(CombineHashCodes(h1, h2), h3);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal object GetObjectStartLength(out int start, out int length)
		{
			start = _index;
			length = _length;
			return _object;
		}
	}
	[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	public readonly ref struct ReadOnlySpan<T>
	{
		public ref struct Enumerator
		{
			private readonly ReadOnlySpan<T> _span;

			private int _index;

			public ref readonly T Current
			{
				[MethodImpl(MethodImplOptions.AggressiveInlining)]
				get
				{
					return ref _span[_index];
				}
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			internal Enumerator(ReadOnlySpan<T> span)
			{
				_span = span;
				_index = -1;
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public bool MoveNext()
			{
				int num = _index + 1;
				if (num < _span.Length)
				{
					_index = num;
					return true;
				}
				return false;
			}
		}

		private readonly Pinnable<T> _pinnable;

		private readonly IntPtr _byteOffset;

		private readonly int _length;

		public int Length => _length;

		public bool IsEmpty => _length == 0;

		public static ReadOnlySpan<T> Empty => default(ReadOnlySpan<T>);

		public unsafe ref readonly T this[int index]
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				if ((uint)index >= (uint)_length)
				{
					System.ThrowHelper.ThrowIndexOutOfRangeException();
				}
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					return ref Unsafe.Add(ref Unsafe.AsRef<T>(byteOffset.ToPointer()), index);
				}
				return ref Unsafe.Add(ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset), index);
			}
		}

		internal Pinnable<T> Pinnable => _pinnable;

		internal IntPtr ByteOffset => _byteOffset;

		public static bool operator !=(ReadOnlySpan<T> left, ReadOnlySpan<T> right)
		{
			return !(left == right);
		}

		[Obsolete("Equals() on ReadOnlySpan will always throw an exception. Use == instead.")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			throw new NotSupportedException(System.SR.NotSupported_CannotCallEqualsOnSpan);
		}

		[Obsolete("GetHashCode() on ReadOnlySpan will always throw an exception.")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			throw new NotSupportedException(System.SR.NotSupported_CannotCallGetHashCodeOnSpan);
		}

		public static implicit operator ReadOnlySpan<T>(T[] array)
		{
			return new ReadOnlySpan<T>(array);
		}

		public static implicit operator ReadOnlySpan<T>(ArraySegment<T> segment)
		{
			return new ReadOnlySpan<T>(segment.Array, segment.Offset, segment.Count);
		}

		public Enumerator GetEnumerator()
		{
			return new Enumerator(this);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlySpan(T[] array)
		{
			if (array == null)
			{
				this = default(ReadOnlySpan<T>);
				return;
			}
			_length = array.Length;
			_pinnable = Unsafe.As<Pinnable<T>>(array);
			_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlySpan(T[] array, int start, int length)
		{
			if (array == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				this = default(ReadOnlySpan<T>);
				return;
			}
			if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			_length = length;
			_pinnable = Unsafe.As<Pinnable<T>>(array);
			_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment.Add<T>(start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[CLSCompliant(false)]
		public unsafe ReadOnlySpan(void* pointer, int length)
		{
			if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
			{
				System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
			}
			if (length < 0)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			_length = length;
			_pinnable = null;
			_byteOffset = new IntPtr(pointer);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal ReadOnlySpan(Pinnable<T> pinnable, IntPtr byteOffset, int length)
		{
			_length = length;
			_pinnable = pinnable;
			_byteOffset = byteOffset;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public unsafe ref readonly T GetPinnableReference()
		{
			if (_length != 0)
			{
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					return ref Unsafe.AsRef<T>(byteOffset.ToPointer());
				}
				return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset);
			}
			return ref Unsafe.AsRef<T>(null);
		}

		public void CopyTo(Span<T> destination)
		{
			if (!TryCopyTo(destination))
			{
				System.ThrowHelper.ThrowArgumentException_DestinationTooShort();
			}
		}

		public bool TryCopyTo(Span<T> destination)
		{
			int length = _length;
			int length2 = destination.Length;
			if (length == 0)
			{
				return true;
			}
			if ((uint)length > (uint)length2)
			{
				return false;
			}
			ref T src = ref DangerousGetPinnableReference();
			System.SpanHelpers.CopyTo(ref destination.DangerousGetPinnableReference(), length2, ref src, length);
			return true;
		}

		public static bool operator ==(ReadOnlySpan<T> left, ReadOnlySpan<T> right)
		{
			if (left._length == right._length)
			{
				return Unsafe.AreSame(ref left.DangerousGetPinnableReference(), ref right.DangerousGetPinnableReference());
			}
			return false;
		}

		public unsafe override string ToString()
		{
			if (typeof(T) == typeof(char))
			{
				if (_byteOffset == MemoryExtensions.StringAdjustment)
				{
					object obj = Unsafe.As<object>(_pinnable);
					if (obj is string text && _length == text.Length)
					{
						return text;
					}
				}
				fixed (char* value = &Unsafe.As<T, char>(ref DangerousGetPinnableReference()))
				{
					return new string(value, 0, _length);
				}
			}
			return $"System.ReadOnlySpan<{typeof(T).Name}>[{_length}]";
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlySpan<T> Slice(int start)
		{
			if ((uint)start > (uint)_length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = _byteOffset.Add<T>(start);
			int length = _length - start;
			return new ReadOnlySpan<T>(_pinnable, byteOffset, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlySpan<T> Slice(int start, int length)
		{
			if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = _byteOffset.Add<T>(start);
			return new ReadOnlySpan<T>(_pinnable, byteOffset, length);
		}

		public T[] ToArray()
		{
			if (_length == 0)
			{
				return System.SpanHelpers.PerTypeValues<T>.EmptyArray;
			}
			T[] array = new T[_length];
			CopyTo(array);
			return array;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[EditorBrowsable(EditorBrowsableState.Never)]
		internal unsafe ref T DangerousGetPinnableReference()
		{
			if (_pinnable == null)
			{
				IntPtr byteOffset = _byteOffset;
				return ref Unsafe.AsRef<T>(byteOffset.ToPointer());
			}
			return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset);
		}
	}
	public readonly struct SequencePosition : IEquatable<SequencePosition>
	{
		private readonly object _object;

		private readonly int _integer;

		public SequencePosition(object @object, int integer)
		{
			_object = @object;
			_integer = integer;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public object GetObject()
		{
			return _object;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public int GetInteger()
		{
			return _integer;
		}

		public bool Equals(SequencePosition other)
		{
			if (_integer == other._integer)
			{
				return object.Equals(_object, other._object);
			}
			return false;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			if (obj is SequencePosition other)
			{
				return Equals(other);
			}
			return false;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			return HashHelpers.Combine(_object?.GetHashCode() ?? 0, _integer);
		}
	}
	[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	public readonly ref struct Span<T>
	{
		public ref struct Enumerator
		{
			private readonly Span<T> _span;

			private int _index;

			public ref T Current
			{
				[MethodImpl(MethodImplOptions.AggressiveInlining)]
				get
				{
					return ref _span[_index];
				}
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			internal Enumerator(Span<T> span)
			{
				_span = span;
				_index = -1;
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public bool MoveNext()
			{
				int num = _index + 1;
				if (num < _span.Length)
				{
					_index = num;
					return true;
				}
				return false;
			}
		}

		private readonly Pinnable<T> _pinnable;

		private readonly IntPtr _byteOffset;

		private readonly int _length;

		public int Length => _length;

		public bool IsEmpty => _length == 0;

		public static Span<T> Empty => default(Span<T>);

		public unsafe ref T this[int index]
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				if ((uint)index >= (uint)_length)
				{
					System.ThrowHelper.ThrowIndexOutOfRangeException();
				}
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					return ref Unsafe.Add(ref Unsafe.AsRef<T>(byteOffset.ToPointer()), index);
				}
				return ref Unsafe.Add(ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset), index);
			}
		}

		internal Pinnable<T> Pinnable => _pinnable;

		internal IntPtr ByteOffset => _byteOffset;

		public static bool operator !=(Span<T> left, Span<T> right)
		{
			return !(left == right);
		}

		[Obsolete("Equals() on Span will always throw an exception. Use == instead.")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			throw new NotSupportedException(System.SR.NotSupported_CannotCallEqualsOnSpan);
		}

		[Obsolete("GetHashCode() on Span will always throw an exception.")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			throw new NotSupportedException(System.SR.NotSupported_CannotCallGetHashCodeOnSpan);
		}

		public static implicit operator Span<T>(T[] array)
		{
			return new Span<T>(array);
		}

		public static implicit operator Span<T>(ArraySegment<T> segment)
		{
			return new Span<T>(segment.Array, segment.Offset, segment.Count);
		}

		public Enumerator GetEnumerator()
		{
			return new Enumerator(this);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span(T[] array)
		{
			if (array == null)
			{
				this = default(Span<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			_length = array.Length;
			_pinnable = Unsafe.As<Pinnable<T>>(array);
			_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static Span<T> Create(T[] array, int start)
		{
			if (array == null)
			{
				if (start != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(Span<T>);
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			if ((uint)start > (uint)array.Length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment.Add<T>(start);
			int length = array.Length - start;
			return new Span<T>(Unsafe.As<Pinnable<T>>(array), byteOffset, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span(T[] array, int start, int length)
		{
			if (array == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				this = default(Span<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			_length = length;
			_pinnable = Unsafe.As<Pinnable<T>>(array);
			_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment.Add<T>(start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[CLSCompliant(false)]
		public unsafe Span(void* pointer, int length)
		{
			if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
			{
				System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
			}
			if (length < 0)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			_length = length;
			_pinnable = null;
			_byteOffset = new IntPtr(pointer);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Span(Pinnable<T> pinnable, IntPtr byteOffset, int length)
		{
			_length = length;
			_pinnable = pinnable;
			_byteOffset = byteOffset;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public unsafe ref T GetPinnableReference()
		{
			if (_length != 0)
			{
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					return ref Unsafe.AsRef<T>(byteOffset.ToPointer());
				}
				return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset);
			}
			return ref Unsafe.AsRef<T>(null);
		}

		public unsafe void Clear()
		{
			int length = _length;
			if (length == 0)
			{
				return;
			}
			UIntPtr byteLength = (UIntPtr)(ulong)((uint)length * Unsafe.SizeOf<T>());
			if ((Unsafe.SizeOf<T>() & (sizeof(IntPtr) - 1)) != 0)
			{
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					byte* ptr = (byte*)byteOffset.ToPointer();
					System.SpanHelpers.ClearLessThanPointerSized(ptr, byteLength);
				}
				else
				{
					System.SpanHelpers.ClearLessThanPointerSized(ref Unsafe.As<T, byte>(ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset)), byteLength);
				}
			}
			else if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
			{
				UIntPtr pointerSizeLength = (UIntPtr)(ulong)(length * Unsafe.SizeOf<T>() / sizeof(IntPtr));
				System.SpanHelpers.ClearPointerSizedWithReferences(ref Unsafe.As<T, IntPtr>(ref DangerousGetPinnableReference()), pointerSizeLength);
			}
			else
			{
				System.SpanHelpers.ClearPointerSizedWithoutReferences(ref Unsafe.As<T, byte>(ref DangerousGetPinnableReference()), byteLength);
			}
		}

		public unsafe void Fill(T value)
		{
			int length = _length;
			if (length == 0)
			{
				return;
			}
			if (Unsafe.SizeOf<T>() == 1)
			{
				byte value2 = Unsafe.As<T, byte>(ref value);
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					Unsafe.InitBlockUnaligned(byteOffset.ToPointer(), value2, (uint)length);
				}
				else
				{
					Unsafe.InitBlockUnaligned(ref Unsafe.As<T, byte>(ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset)), value2, (uint)length);
				}
				return;
			}
			ref T source = ref DangerousGetPinnableReference();
			int i;
			for (i = 0; i < (length & -8); i += 8)
			{
				Unsafe.Add(ref source, i) = value;
				Unsafe.Add(ref source, i + 1) = value;
				Unsafe.Add(ref source, i + 2) = value;
				Unsafe.Add(ref source, i + 3) = value;
				Unsafe.Add(ref source, i + 4) = value;
				Unsafe.Add(ref source, i + 5) = value;
				Unsafe.Add(ref source, i + 6) = value;
				Unsafe.Add(ref source, i + 7) = value;
			}
			if (i < (length & -4))
			{
				Unsafe.Add(ref source, i) = value;
				Unsafe.Add(ref source, i + 1) = value;
				Unsafe.Add(ref source, i + 2) = value;
				Unsafe.Add(ref source, i + 3) = value;
				i += 4;
			}
			for (; i < length; i++)
			{
				Unsafe.Add(ref source, i) = value;
			}
		}

		public void CopyTo(Span<T> destination)
		{
			if (!TryCopyTo(destination))
			{
				System.ThrowHelper.ThrowArgumentException_DestinationTooShort();
			}
		}

		public bool TryCopyTo(Span<T> destination)
		{
			int length = _length;
			int length2 = destination._length;
			if (length == 0)
			{
				return true;
			}
			if ((uint)length > (uint)length2)
			{
				return false;
			}
			ref T src = ref DangerousGetPinnableReference();
			System.SpanHelpers.CopyTo(ref destination.DangerousGetPinnableReference(), length2, ref src, length);
			return true;
		}

		public static bool operator ==(Span<T> left, Span<T> right)
		{
			if (left._length == right._length)
			{
				return Unsafe.AreSame(ref left.DangerousGetPinnableReference(), ref right.DangerousGetPinnableReference());
			}
			return false;
		}

		public static implicit operator ReadOnlySpan<T>(Span<T> span)
		{
			return new ReadOnlySpan<T>(span._pinnable, span._byteOffset, span._length);
		}

		public unsafe override string ToString()
		{
			if (typeof(T) == typeof(char))
			{
				fixed (char* value = &Unsafe.As<T, char>(ref DangerousGetPinnableReference()))
				{
					return new string(value, 0, _length);
				}
			}
			return $"System.Span<{typeof(T).Name}>[{_length}]";
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span<T> Slice(int start)
		{
			if ((uint)start > (uint)_length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = _byteOffset.Add<T>(start);
			int length = _length - start;
			return new Span<T>(_pinnable, byteOffset, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span<T> Slice(int start, int length)
		{
			if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = _byteOffset.Add<T>(start);
			return new Span<T>(_pinnable, byteOffset, length);
		}

		public T[] ToArray()
		{
			if (_length == 0)
			{
				return System.SpanHelpers.PerTypeValues<T>.EmptyArray;
			}
			T[] array = new T[_length];
			CopyTo(array);
			return array;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[EditorBrowsable(EditorBrowsableState.Never)]
		internal unsafe ref T DangerousGetPinnableReference()
		{
			if (_pinnable == null)
			{
				IntPtr byteOffset = _byteOffset;
				return ref Unsafe.AsRef<T>(byteOffset.ToPointer());
			}
			return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset);
		}
	}
	internal sealed class SpanDebugView<T>
	{
		private readonly T[] _array;

		[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
		public T[] Items => _array;

		public SpanDebugView(Span<T> span)
		{
			_array = span.ToArray();
		}

		public SpanDebugView(ReadOnlySpan<T> span)
		{
			_array = span.ToArray();
		}
	}
	internal static class SpanHelpers
	{
		internal struct ComparerComparable<T, TComparer> : IComparable<T> where TComparer : IComparer<T>
		{
			private readonly T _value;

			private readonly TComparer _comparer;

			public ComparerComparable(T value, TComparer comparer)
			{
				_value = value;
				_comparer = comparer;
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public int CompareTo(T other)
			{
				return _comparer.Compare(_value, other);
			}
		}

		[StructLayout(LayoutKind.Sequential, Size = 64)]
		private struct Reg64
		{
		}

		[StructLayout(LayoutKind.Sequential, Size = 32)]
		private struct Reg32
		{
		}

		[StructLayout(LayoutKind.Sequential, Size = 16)]
		private struct Reg16
		{
		}

		public static class PerTypeValues<T>
		{
			public static readonly bool IsReferenceOrContainsReferences = IsReferenceOrContainsReferencesCore(typeof(T));

			public static readonly T[] EmptyArray = new T[0];

			public static readonly IntPtr ArrayAdjustment = MeasureArrayAdjustment();

			private static IntPtr MeasureArrayAdjustment()
			{
				T[] array = new T[1];
				return Unsafe.ByteOffset(ref Unsafe.As<Pinnable<T>>(array).Data, ref array[0]);
			}
		}

		private const ulong XorPowerOfTwoToHighByte = 283686952306184uL;

		private const ulong XorPowerOfTwoToHighChar = 4295098372uL;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparable>(this ReadOnlySpan<T> span, TComparable comparable) where TComparable : IComparable<T>
		{
			if (comparable == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.comparable);
			}
			return BinarySearch(ref MemoryMarshal.GetReference(span), span.Length, comparable);
		}

		public static int BinarySearch<T, TComparable>(ref T spanStart, int length, TComparable comparable) where TComparable : IComparable<T>
		{
			int num = 0;
			int num2 = length - 1;
			while (num <= num2)
			{
				int num3 = num2 + num >>> 1;
				ref TComparable reference = ref comparable;
				TComparable val = default(TComparable);
				if (val == null)
				{
					val = reference;
					reference = ref val;
				}
				int num4 = reference.CompareTo(Unsafe.Add(ref spanStart, num3));
				if (num4 == 0)
				{
					return num3;
				}
				if (num4 > 0)
				{
					num = num3 + 1;
				}
				else
				{
					num2 = num3 - 1;
				}
			}
			return ~num;
		}

		public static int IndexOf(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength)
		{
			if (valueLength == 0)
			{
				return 0;
			}
			byte value2 = value;
			ref byte second = ref Unsafe.Add(ref value, 1);
			int num = valueLength - 1;
			int num2 = 0;
			while (true)
			{
				int num3 = searchSpaceLength - num2 - num;
				if (num3 <= 0)
				{
					break;
				}
				int num4 = IndexOf(ref Unsafe.Add(ref searchSpace, num2), value2, num3);
				if (num4 == -1)
				{
					break;
				}
				num2 += num4;
				if (SequenceEqual(ref Unsafe.Add(ref searchSpace, num2 + 1), ref second, num))
				{
					return num2;
				}
				num2++;
			}
			return -1;
		}

		public static int IndexOfAny(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength)
		{
			if (valueLength == 0)
			{
				return 0;
			}
			int num = -1;
			for (int i = 0; i < valueLength; i++)
			{
				int num2 = IndexOf(ref searchSpace, Unsafe.Add(ref value, i), searchSpaceLength);
				if ((uint)num2 < (uint)num)
				{
					num = num2;
					searchSpaceLength = num2;
					if (num == 0)
					{
						break;
					}
				}
			}
			return num;
		}

		public static int LastIndexOfAny(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength)
		{
			if (valueLength == 0)
			{
				return 0;
			}
			int num = -1;
			for (int i = 0; i < valueLength; i++)
			{
				int num2 = LastIndexOf(ref searchSpace, Unsafe.Add(ref value, i), searchSpaceLength);
				if (num2 > num)
				{
					num = num2;
				}
			}
			return num;
		}

		public unsafe static int IndexOf(ref byte searchSpace, byte value, int length)
		{
			IntPtr intPtr = (IntPtr)0;
			IntPtr intPtr2 = (IntPtr)length;
			if (Vector.IsHardwareAccelerated && length >= Vector<byte>.Count * 2)
			{
				int num = (int)Unsafe.AsPointer(ref searchSpace) & (Vector<byte>.Count - 1);
				intPtr2 = (IntPtr)((Vector<byte>.Count - num) & (Vector<byte>.Count - 1));
			}
			while (true)
			{
				if ((nuint)(void*)intPtr2 >= (nuint)8u)
				{
					intPtr2 -= 8;
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr))
					{
						goto IL_0242;
					}
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 1))
					{
						goto IL_024a;
					}
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 2))
					{
						goto IL_0258;
					}
					if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 3))
					{
						if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 4))
						{
							if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 5))
							{
								if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 6))
								{
									if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 7))
									{
										break;
									}
									intPtr += 8;
									continue;
								}
								return (int)(void*)(intPtr + 6);
							}
							return (int)(void*)(intPtr + 5);
						}
						return (int)(void*)(intPtr + 4);
					}
					goto IL_0266;
				}
				if ((nuint)(void*)intPtr2 >= (nuint)4u)
				{
					intPtr2 -= 4;
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr))
					{
						goto IL_0242;
					}
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 1))
					{
						goto IL_024a;
					}
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 2))
					{
						goto IL_0258;
					}
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 3))
					{
						goto IL_0266;
					}
					intPtr += 4;
				}
				while ((void*)intPtr2 != null)
				{
					intPtr2 -= 1;
					if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr))
					{
						intPtr += 1;
						continue;
					}
					goto IL_0242;
				}
				if (Vector.IsHardwareAccelerated && (int)(void*)intPtr < length)
				{
					intPtr2 = (IntPtr)((length - (int)(void*)intPtr) & ~(Vector<byte>.Count - 1));
					Vector<byte> vector = GetVector(value);
					for (; (void*)intPtr2 > (void*)intPtr; intPtr += Vector<byte>.Count)
					{
						Vector<byte> vector2 = Vector.Equals(vector, Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref searchSpace, intPtr)));
						if (!Vector<byte>.Zero.Equals(vector2))
						{
							return (int)(void*)intPtr + LocateFirstFoundByte(vector2);
						}
					}
					if ((int)(void*)intPtr < length)
					{
						intPtr2 = (IntPtr)(length - (int)(void*)intPtr);
						continue;
					}
				}
				return -1;
				IL_0266:
				return (int)(void*)(intPtr + 3);
				IL_0242:
				return (int)(void*)intPtr;
				IL_0258:
				return (int)(void*)(intPtr + 2);
				IL_024a:
				return (int)(void*)(intPtr + 1);
			}
			return (int)(void*)(intPtr + 7);
		}

		public static int LastIndexOf(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength)
		{
			if (valueLength == 0)
			{
				return 0;
			}
			byte value2 = value;
			ref byte second = ref Unsafe.Add(ref value, 1);
			int num = valueLength - 1;
			int num2 = 0;
			while (true)
			{
				int num3 = searchSpaceLength - num2 - num;
				if (num3 <= 0)
				{
					break;
				}
				int num4 = LastIndexOf(ref searchSpace, value2, num3);
				if (num4 == -1)
				{
					break;
				}
				if (SequenceEqual(ref Unsafe.Add(ref searchSpace, num4 + 1), ref second, num))
				{
					return num4;
				}
				num2 += num3 - num4;
			}
			return -1;
		}

		public unsafe static int LastIndexOf(ref byte searchSpace, byte value, int length)
		{
			IntPtr intPtr = (IntPtr)length;
			IntPtr intPtr2 = (IntPtr)length;
			if (Vector.IsHardwareAccelerated && length >= Vector<byte>.Count * 2)
			{
				int num = (int)Unsafe.AsPointer(ref searchSpace) & (Vector<byte>.Count - 1);
				intPtr2 = (IntPtr)(((length & (Vector<byte>.Count - 1)) + num) & (Vector<byte>.Count - 1));
			}
			while (true)
			{
				if ((nuint)(void*)intPtr2 >= (nuint)8u)
				{
					intPtr2 -= 8;
					intPtr -= 8;
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 7))
					{
						break;
					}
					if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 6))
					{
						if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 5))
						{
							if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 4))
							{
								if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 3))
								{
									if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 2))
									{
										if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 1))
										{
											if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr))
											{
												continue;
											}
											goto IL_0254;
										}
										goto IL_025c;
									}
									goto IL_026a;
								}
								goto IL_0278;
							}
							return (int)(void*)(intPtr + 4);
						}
						return (int)(void*)(intPtr + 5);
					}
					return (int)(void*)(intPtr + 6);
				}
				if ((nuint)(void*)intPtr2 >= (nuint)4u)
				{
					intPtr2 -= 4;
					intPtr -= 4;
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 3))
					{
						goto IL_0278;
					}
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 2))
					{
						goto IL_026a;
					}
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 1))
					{
						goto IL_025c;
					}
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr))
					{
						goto IL_0254;
					}
				}
				while ((void*)intPtr2 != null)
				{
					intPtr2 -= 1;
					intPtr -= 1;
					if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr))
					{
						continue;
					}
					goto IL_0254;
				}
				if (Vector.IsHardwareAccelerated && (void*)intPtr != null)
				{
					intPtr2 = (IntPtr)((int)(void*)intPtr & ~(Vector<byte>.Count - 1));
					Vector<byte> vector = GetVector(value);
					for (; (nuint)(void*)intPtr2 > (nuint)(Vector<byte>.Count - 1); intPtr2 -= Vector<byte>.Count)
					{
						Vector<byte> vector2 = Vector.Equals(vector, Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref searchSpace, intPtr - Vector<byte>.Count)));
						if (Vector<byte>.Zero.Equals(vector2))
						{
							intPtr -= Vector<byte>.Count;
							continue;
						}
						return (int)intPtr - Vector<byte>.Count + LocateLastFoundByte(vector2);
					}
					if ((void*)intPtr != null)
					{
						intPtr2 = intPtr;
						continue;
					}
				}
				return -1;
				IL_0254:
				return (int)(void*)intPtr;
				IL_026a:
				return (int)(void*)(intPtr + 2);
				IL_0278:
				return (int)(void*)(intPtr + 3);
				IL_025c:
				return (int)(void*)(intPtr + 1);
			}
			return (int)(void*)(intPtr + 7);
		}

		public unsafe static int IndexOfAny(ref byte searchSpace, byte value0, byte value1, int length)
		{
			IntPtr intPtr = (IntPtr)0;
			IntPtr intPtr2 = (IntPtr)length;
			if (Vector.IsHardwareAccelerated && length >= Vector<byte>.Count * 2)
			{
				int num = (int)Unsafe.AsPointer(ref searchSpace) & (Vector<byte>.Count - 1);
				intPtr2 = (IntPtr)((Vector<byte>.Count - num) & (Vector<byte>.Count - 1));
			}
			while (true)
			{
				if ((nuint)(void*)intPtr2 >= (nuint)8u)
				{
					intPtr2 -= 8;
					uint num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr);
					if (value0 == num2 || value1 == num2)
					{
						goto IL_02ff;
					}
					num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1);
					if (value0 == num2 || value1 == num2)
					{
						goto IL_0307;
					}
					num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2);
					if (value0 == num2 || value1 == num2)
					{
						goto IL_0315;
					}
					num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3);
					if (value0 != num2 && value1 != num2)
					{
						num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 4);
						if (value0 != num2 && value1 != num2)
						{
							num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 5);
							if (value0 != num2 && value1 != num2)
							{
								num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 6);
								if (value0 != num2 && value1 != num2)
								{
									num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 7);
									if (value0 == num2 || value1 == num2)
									{
										break;
									}
									intPtr += 8;
									continue;
								}
								return (int)(void*)(intPtr + 6);
							}
							return (int)(void*)(intPtr + 5);
						}
						return (int)(void*)(intPtr + 4);
					}
					goto IL_0323;
				}
				if ((nuint)(void*)intPtr2 >= (nuint)4u)
				{
					intPtr2 -= 4;
					uint num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr);
					if (value0 == num2 || value1 == num2)
					{
						goto IL_02ff;
					}
					num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1);
					if (value0 == num2 || value1 == num2)
					{
						goto IL_0307;
					}
					num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2);
					if (value0 == num2 || value1 == num2)
					{
						goto IL_0315;
					}
					num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3);
					if (value0 == num2 || value1 == num2)
					{
						goto IL_0323;
					}
					intPtr += 4;
				}
				while ((void*)intPtr2 != null)
				{
					intPtr2 -= 1;
					uint num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr);
					if (value0 != num2 && value1 != num2)
					{
						intPtr += 1;
						continue;
					}
					goto IL_02ff;
				}
				if (Vector.IsHardwareAccelerated && (int)(void*)intPtr < length)
				{
					intPtr2 = (IntPtr)((length - (int)(void*)intPtr) & ~(Vector<byte>.Count - 1));
					Vector<byte> vector = GetVector(value0);
					Vector<byte> vector2 = GetVector(value1);
					for (; (void*)intPtr2 > (void*)intPtr; intPtr += Vector<byte>.Count)
					{
						Vector<byte> left = Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref searchSpace, intPtr));
						Vector<byte> vector3 = Vector.BitwiseOr(Vector.Equals(left, vector), Vector.Equals(left, vector2));
						if (!Vector<byte>.Zero.Equals(vector3))
						{
							return (int)(void*)intPtr + LocateFirstFoundByte(vector3);
						}
					}
					if ((int)(void*)intPtr < length)
					{
						intPtr2 = (IntPtr)(length - (int)(void*)intPtr);
						continue;
					}
				}
				return -1;
				IL_02ff:
				return (int)(void*)intPtr;
				IL_0315:
				return (int)(void*)(intPtr + 2);
				IL_0307:
				return (int)(void*)(intPtr + 1);
				IL_0323:
				return (int)(void*)(intPtr + 3);
			}
			return (int)(void*)(intPtr + 7);
		}

		public unsafe static int IndexOfAny(ref byte searchSpace, byte value0, byte value1, byte value2, int length)
		{
			IntPtr intPtr = (IntPtr)0;
			IntPtr intPtr2 = (IntPtr)length;
			if (Vector.IsHardwareAccelerated && length >= Vector<byte>.Count * 2)
			{
				int num = (int)Unsafe.AsPointer(ref searchSpace) & (Vector<byte>.Count - 1);
				intPtr2 = (IntPtr)((Vector<byte>.Count - num) & (Vector<byte>.Count - 1));
			}
			while (true)
			{
				if ((nuint)(void*)intPtr2 >= (nuint)8u)
				{
					intPtr2 -= 8;
					uint num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr);
					if (value0 == num2 || value1 == num2 || value2 == num2)
					{
						goto IL_0393;
					}
					num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1);
					if (value0 == num2 || value1 == num2 || value2 == num2)
					{
						goto IL_039b;
					}
					num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2);
					if (value0 == num2 || value1 == num2 || value2 == num2)
					{
						goto IL_03a9;
					}
					num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3);
					if (value0 != num2 && value1 != num2 && value2 != num2)
					{
						num2 = Unsafe.A

Mods/RealRadio/System.Numerics.Vectors.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.Globalization;
using System.Numerics.Hashing;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using FxResources.System.Numerics.Vectors;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyDefaultAlias("System.Numerics.Vectors")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyDescription("System.Numerics.Vectors")]
[assembly: AssemblyFileVersion("4.600.125.16908")]
[assembly: AssemblyInformationalVersion("4.6.1+6b84308c9ad012f53240d72c1d716d7e42546483")]
[assembly: AssemblyProduct("Microsoft® .NET")]
[assembly: AssemblyTitle("System.Numerics.Vectors")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/dotnet/maintenance-packages")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.1.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace FxResources.System.Numerics.Vectors
{
	internal static class SR
	{
	}
}
namespace System
{
	internal static class MathF
	{
		public const float PI = 3.1415927f;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Abs(float x)
		{
			return Math.Abs(x);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Acos(float x)
		{
			return (float)Math.Acos(x);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Cos(float x)
		{
			return (float)Math.Cos(x);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float IEEERemainder(float x, float y)
		{
			return (float)Math.IEEERemainder(x, y);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Pow(float x, float y)
		{
			return (float)Math.Pow(x, y);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Sin(float x)
		{
			return (float)Math.Sin(x);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Sqrt(float x)
		{
			return (float)Math.Sqrt(x);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Tan(float x)
		{
			return (float)Math.Tan(x);
		}
	}
	internal static class SR
	{
		private static readonly bool s_usingResourceKeys = AppContext.TryGetSwitch("System.Resources.UseSystemResourceKeys", out var isEnabled) && isEnabled;

		private static ResourceManager s_resourceManager;

		internal static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(typeof(SR)));

		internal static string Arg_ArgumentOutOfRangeException => GetResourceString("Arg_ArgumentOutOfRangeException");

		internal static string Arg_ElementsInSourceIsGreaterThanDestination => GetResourceString("Arg_ElementsInSourceIsGreaterThanDestination");

		internal static string Arg_NullArgumentNullRef => GetResourceString("Arg_NullArgumentNullRef");

		internal static string Arg_TypeNotSupported => GetResourceString("Arg_TypeNotSupported");

		internal static string Arg_InsufficientNumberOfElements => GetResourceString("Arg_InsufficientNumberOfElements");

		private static bool UsingResourceKeys()
		{
			return s_usingResourceKeys;
		}

		internal static string GetResourceString(string resourceKey)
		{
			if (UsingResourceKeys())
			{
				return resourceKey;
			}
			string result = null;
			try
			{
				result = ResourceManager.GetString(resourceKey);
			}
			catch (MissingManifestResourceException)
			{
			}
			return result;
		}

		internal static string GetResourceString(string resourceKey, string defaultString)
		{
			string resourceString = GetResourceString(resourceKey);
			if (!(resourceKey == resourceString) && resourceString != null)
			{
				return resourceString;
			}
			return defaultString;
		}

		internal static string Format(string resourceFormat, object? p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(resourceFormat, p1);
		}

		internal static string Format(string resourceFormat, object? p1, object? p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(resourceFormat, p1, p2);
		}

		internal static string Format(string resourceFormat, object? p1, object? p2, object? p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(resourceFormat, p1, p2, p3);
		}

		internal static string Format(string resourceFormat, params object?[]? args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + ", " + string.Join(", ", args);
				}
				return string.Format(resourceFormat, args);
			}
			return resourceFormat;
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(provider, resourceFormat, p1);
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1, object? p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(provider, resourceFormat, p1, p2);
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1, object? p2, object? p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(provider, resourceFormat, p1, p2, p3);
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, params object?[]? args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + ", " + string.Join(", ", args);
				}
				return string.Format(provider, resourceFormat, args);
			}
			return resourceFormat;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Field, Inherited = false)]
	internal sealed class IntrinsicAttribute : Attribute
	{
	}
}
namespace System.Numerics
{
	internal class ConstantHelper
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static byte GetByteWithAllBitsSet()
		{
			byte result = 0;
			result = byte.MaxValue;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static sbyte GetSByteWithAllBitsSet()
		{
			sbyte result = 0;
			result = -1;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ushort GetUInt16WithAllBitsSet()
		{
			ushort result = 0;
			result = ushort.MaxValue;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static short GetInt16WithAllBitsSet()
		{
			short result = 0;
			result = -1;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static uint GetUInt32WithAllBitsSet()
		{
			uint result = 0u;
			result = uint.MaxValue;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int GetInt32WithAllBitsSet()
		{
			int result = 0;
			result = -1;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ulong GetUInt64WithAllBitsSet()
		{
			ulong result = 0uL;
			result = ulong.MaxValue;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static long GetInt64WithAllBitsSet()
		{
			long result = 0L;
			result = -1L;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static float GetSingleWithAllBitsSet()
		{
			float result = 0f;
			*(int*)(&result) = -1;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static double GetDoubleWithAllBitsSet()
		{
			double result = 0.0;
			*(long*)(&result) = -1L;
			return result;
		}
	}
	public struct Matrix3x2 : IEquatable<Matrix3x2>
	{
		public float M11;

		public float M12;

		public float M21;

		public float M22;

		public float M31;

		public float M32;

		private static readonly Matrix3x2 _identity = new Matrix3x2(1f, 0f, 0f, 1f, 0f, 0f);

		public static Matrix3x2 Identity => _identity;

		public bool IsIdentity
		{
			get
			{
				if (M11 == 1f && M22 == 1f && M12 == 0f && M21 == 0f && M31 == 0f)
				{
					return M32 == 0f;
				}
				return false;
			}
		}

		public Vector2 Translation
		{
			get
			{
				return new Vector2(M31, M32);
			}
			set
			{
				M31 = value.X;
				M32 = value.Y;
			}
		}

		public Matrix3x2(float m11, float m12, float m21, float m22, float m31, float m32)
		{
			M11 = m11;
			M12 = m12;
			M21 = m21;
			M22 = m22;
			M31 = m31;
			M32 = m32;
		}

		public static Matrix3x2 CreateTranslation(Vector2 position)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = 1f;
			result.M12 = 0f;
			result.M21 = 0f;
			result.M22 = 1f;
			result.M31 = position.X;
			result.M32 = position.Y;
			return result;
		}

		public static Matrix3x2 CreateTranslation(float xPosition, float yPosition)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = 1f;
			result.M12 = 0f;
			result.M21 = 0f;
			result.M22 = 1f;
			result.M31 = xPosition;
			result.M32 = yPosition;
			return result;
		}

		public static Matrix3x2 CreateScale(float xScale, float yScale)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = xScale;
			result.M12 = 0f;
			result.M21 = 0f;
			result.M22 = yScale;
			result.M31 = 0f;
			result.M32 = 0f;
			return result;
		}

		public static Matrix3x2 CreateScale(float xScale, float yScale, Vector2 centerPoint)
		{
			float m = centerPoint.X * (1f - xScale);
			float m2 = centerPoint.Y * (1f - yScale);
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = xScale;
			result.M12 = 0f;
			result.M21 = 0f;
			result.M22 = yScale;
			result.M31 = m;
			result.M32 = m2;
			return result;
		}

		public static Matrix3x2 CreateScale(Vector2 scales)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = scales.X;
			result.M12 = 0f;
			result.M21 = 0f;
			result.M22 = scales.Y;
			result.M31 = 0f;
			result.M32 = 0f;
			return result;
		}

		public static Matrix3x2 CreateScale(Vector2 scales, Vector2 centerPoint)
		{
			float m = centerPoint.X * (1f - scales.X);
			float m2 = centerPoint.Y * (1f - scales.Y);
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = scales.X;
			result.M12 = 0f;
			result.M21 = 0f;
			result.M22 = scales.Y;
			result.M31 = m;
			result.M32 = m2;
			return result;
		}

		public static Matrix3x2 CreateScale(float scale)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = scale;
			result.M12 = 0f;
			result.M21 = 0f;
			result.M22 = scale;
			result.M31 = 0f;
			result.M32 = 0f;
			return result;
		}

		public static Matrix3x2 CreateScale(float scale, Vector2 centerPoint)
		{
			float m = centerPoint.X * (1f - scale);
			float m2 = centerPoint.Y * (1f - scale);
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = scale;
			result.M12 = 0f;
			result.M21 = 0f;
			result.M22 = scale;
			result.M31 = m;
			result.M32 = m2;
			return result;
		}

		public static Matrix3x2 CreateSkew(float radiansX, float radiansY)
		{
			float m = MathF.Tan(radiansX);
			float m2 = MathF.Tan(radiansY);
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = 1f;
			result.M12 = m2;
			result.M21 = m;
			result.M22 = 1f;
			result.M31 = 0f;
			result.M32 = 0f;
			return result;
		}

		public static Matrix3x2 CreateSkew(float radiansX, float radiansY, Vector2 centerPoint)
		{
			float num = MathF.Tan(radiansX);
			float num2 = MathF.Tan(radiansY);
			float m = (0f - centerPoint.Y) * num;
			float m2 = (0f - centerPoint.X) * num2;
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = 1f;
			result.M12 = num2;
			result.M21 = num;
			result.M22 = 1f;
			result.M31 = m;
			result.M32 = m2;
			return result;
		}

		public static Matrix3x2 CreateRotation(float radians)
		{
			radians = MathF.IEEERemainder(radians, (float)Math.PI * 2f);
			float num;
			float num2;
			if (radians > -1.7453294E-05f && radians < 1.7453294E-05f)
			{
				num = 1f;
				num2 = 0f;
			}
			else if (radians > 1.570779f && radians < 1.5708138f)
			{
				num = 0f;
				num2 = 1f;
			}
			else if (radians < -3.1415753f || radians > 3.1415753f)
			{
				num = -1f;
				num2 = 0f;
			}
			else if (radians > -1.5708138f && radians < -1.570779f)
			{
				num = 0f;
				num2 = -1f;
			}
			else
			{
				num = MathF.Cos(radians);
				num2 = MathF.Sin(radians);
			}
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = num;
			result.M12 = num2;
			result.M21 = 0f - num2;
			result.M22 = num;
			result.M31 = 0f;
			result.M32 = 0f;
			return result;
		}

		public static Matrix3x2 CreateRotation(float radians, Vector2 centerPoint)
		{
			radians = MathF.IEEERemainder(radians, (float)Math.PI * 2f);
			float num;
			float num2;
			if (radians > -1.7453294E-05f && radians < 1.7453294E-05f)
			{
				num = 1f;
				num2 = 0f;
			}
			else if (radians > 1.570779f && radians < 1.5708138f)
			{
				num = 0f;
				num2 = 1f;
			}
			else if (radians < -3.1415753f || radians > 3.1415753f)
			{
				num = -1f;
				num2 = 0f;
			}
			else if (radians > -1.5708138f && radians < -1.570779f)
			{
				num = 0f;
				num2 = -1f;
			}
			else
			{
				num = MathF.Cos(radians);
				num2 = MathF.Sin(radians);
			}
			float m = centerPoint.X * (1f - num) + centerPoint.Y * num2;
			float m2 = centerPoint.Y * (1f - num) - centerPoint.X * num2;
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = num;
			result.M12 = num2;
			result.M21 = 0f - num2;
			result.M22 = num;
			result.M31 = m;
			result.M32 = m2;
			return result;
		}

		public float GetDeterminant()
		{
			return M11 * M22 - M21 * M12;
		}

		public static bool Invert(Matrix3x2 matrix, out Matrix3x2 result)
		{
			float num = matrix.M11 * matrix.M22 - matrix.M21 * matrix.M12;
			if (MathF.Abs(num) < float.Epsilon)
			{
				result = new Matrix3x2(float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN);
				return false;
			}
			float num2 = 1f / num;
			result.M11 = matrix.M22 * num2;
			result.M12 = (0f - matrix.M12) * num2;
			result.M21 = (0f - matrix.M21) * num2;
			result.M22 = matrix.M11 * num2;
			result.M31 = (matrix.M21 * matrix.M32 - matrix.M31 * matrix.M22) * num2;
			result.M32 = (matrix.M31 * matrix.M12 - matrix.M11 * matrix.M32) * num2;
			return true;
		}

		public static Matrix3x2 Lerp(Matrix3x2 matrix1, Matrix3x2 matrix2, float amount)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = matrix1.M11 + (matrix2.M11 - matrix1.M11) * amount;
			result.M12 = matrix1.M12 + (matrix2.M12 - matrix1.M12) * amount;
			result.M21 = matrix1.M21 + (matrix2.M21 - matrix1.M21) * amount;
			result.M22 = matrix1.M22 + (matrix2.M22 - matrix1.M22) * amount;
			result.M31 = matrix1.M31 + (matrix2.M31 - matrix1.M31) * amount;
			result.M32 = matrix1.M32 + (matrix2.M32 - matrix1.M32) * amount;
			return result;
		}

		public static Matrix3x2 Negate(Matrix3x2 value)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = 0f - value.M11;
			result.M12 = 0f - value.M12;
			result.M21 = 0f - value.M21;
			result.M22 = 0f - value.M22;
			result.M31 = 0f - value.M31;
			result.M32 = 0f - value.M32;
			return result;
		}

		public static Matrix3x2 Add(Matrix3x2 value1, Matrix3x2 value2)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = value1.M11 + value2.M11;
			result.M12 = value1.M12 + value2.M12;
			result.M21 = value1.M21 + value2.M21;
			result.M22 = value1.M22 + value2.M22;
			result.M31 = value1.M31 + value2.M31;
			result.M32 = value1.M32 + value2.M32;
			return result;
		}

		public static Matrix3x2 Subtract(Matrix3x2 value1, Matrix3x2 value2)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = value1.M11 - value2.M11;
			result.M12 = value1.M12 - value2.M12;
			result.M21 = value1.M21 - value2.M21;
			result.M22 = value1.M22 - value2.M22;
			result.M31 = value1.M31 - value2.M31;
			result.M32 = value1.M32 - value2.M32;
			return result;
		}

		public static Matrix3x2 Multiply(Matrix3x2 value1, Matrix3x2 value2)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = value1.M11 * value2.M11 + value1.M12 * value2.M21;
			result.M12 = value1.M11 * value2.M12 + value1.M12 * value2.M22;
			result.M21 = value1.M21 * value2.M11 + value1.M22 * value2.M21;
			result.M22 = value1.M21 * value2.M12 + value1.M22 * value2.M22;
			result.M31 = value1.M31 * value2.M11 + value1.M32 * value2.M21 + value2.M31;
			result.M32 = value1.M31 * value2.M12 + value1.M32 * value2.M22 + value2.M32;
			return result;
		}

		public static Matrix3x2 Multiply(Matrix3x2 value1, float value2)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = value1.M11 * value2;
			result.M12 = value1.M12 * value2;
			result.M21 = value1.M21 * value2;
			result.M22 = value1.M22 * value2;
			result.M31 = value1.M31 * value2;
			result.M32 = value1.M32 * value2;
			return result;
		}

		public static Matrix3x2 operator -(Matrix3x2 value)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = 0f - value.M11;
			result.M12 = 0f - value.M12;
			result.M21 = 0f - value.M21;
			result.M22 = 0f - value.M22;
			result.M31 = 0f - value.M31;
			result.M32 = 0f - value.M32;
			return result;
		}

		public static Matrix3x2 operator +(Matrix3x2 value1, Matrix3x2 value2)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = value1.M11 + value2.M11;
			result.M12 = value1.M12 + value2.M12;
			result.M21 = value1.M21 + value2.M21;
			result.M22 = value1.M22 + value2.M22;
			result.M31 = value1.M31 + value2.M31;
			result.M32 = value1.M32 + value2.M32;
			return result;
		}

		public static Matrix3x2 operator -(Matrix3x2 value1, Matrix3x2 value2)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = value1.M11 - value2.M11;
			result.M12 = value1.M12 - value2.M12;
			result.M21 = value1.M21 - value2.M21;
			result.M22 = value1.M22 - value2.M22;
			result.M31 = value1.M31 - value2.M31;
			result.M32 = value1.M32 - value2.M32;
			return result;
		}

		public static Matrix3x2 operator *(Matrix3x2 value1, Matrix3x2 value2)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = value1.M11 * value2.M11 + value1.M12 * value2.M21;
			result.M12 = value1.M11 * value2.M12 + value1.M12 * value2.M22;
			result.M21 = value1.M21 * value2.M11 + value1.M22 * value2.M21;
			result.M22 = value1.M21 * value2.M12 + value1.M22 * value2.M22;
			result.M31 = value1.M31 * value2.M11 + value1.M32 * value2.M21 + value2.M31;
			result.M32 = value1.M31 * value2.M12 + value1.M32 * value2.M22 + value2.M32;
			return result;
		}

		public static Matrix3x2 operator *(Matrix3x2 value1, float value2)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = value1.M11 * value2;
			result.M12 = value1.M12 * value2;
			result.M21 = value1.M21 * value2;
			result.M22 = value1.M22 * value2;
			result.M31 = value1.M31 * value2;
			result.M32 = value1.M32 * value2;
			return result;
		}

		public static bool operator ==(Matrix3x2 value1, Matrix3x2 value2)
		{
			if (value1.M11 == value2.M11 && value1.M22 == value2.M22 && value1.M12 == value2.M12 && value1.M21 == value2.M21 && value1.M31 == value2.M31)
			{
				return value1.M32 == value2.M32;
			}
			return false;
		}

		public static bool operator !=(Matrix3x2 value1, Matrix3x2 value2)
		{
			if (value1.M11 == value2.M11 && value1.M12 == value2.M12 && value1.M21 == value2.M21 && value1.M22 == value2.M22 && value1.M31 == value2.M31)
			{
				return value1.M32 != value2.M32;
			}
			return true;
		}

		public bool Equals(Matrix3x2 other)
		{
			if (M11 == other.M11 && M22 == other.M22 && M12 == other.M12 && M21 == other.M21 && M31 == other.M31)
			{
				return M32 == other.M32;
			}
			return false;
		}

		public override bool Equals(object obj)
		{
			if (obj is Matrix3x2)
			{
				return Equals((Matrix3x2)obj);
			}
			return false;
		}

		public override string ToString()
		{
			CultureInfo currentCulture = CultureInfo.CurrentCulture;
			return string.Format(currentCulture, "{{ {{M11:{0} M12:{1}}} {{M21:{2} M22:{3}}} {{M31:{4} M32:{5}}} }}", M11.ToString(currentCulture), M12.ToString(currentCulture), M21.ToString(currentCulture), M22.ToString(currentCulture), M31.ToString(currentCulture), M32.ToString(currentCulture));
		}

		public override int GetHashCode()
		{
			return M11.GetHashCode() + M12.GetHashCode() + M21.GetHashCode() + M22.GetHashCode() + M31.GetHashCode() + M32.GetHashCode();
		}
	}
	public struct Matrix4x4 : IEquatable<Matrix4x4>
	{
		private struct CanonicalBasis
		{
			public Vector3 Row0;

			public Vector3 Row1;

			public Vector3 Row2;
		}

		private struct VectorBasis
		{
			public unsafe Vector3* Element0;

			public unsafe Vector3* Element1;

			public unsafe Vector3* Element2;
		}

		public float M11;

		public float M12;

		public float M13;

		public float M14;

		public float M21;

		public float M22;

		public float M23;

		public float M24;

		public float M31;

		public float M32;

		public float M33;

		public float M34;

		public float M41;

		public float M42;

		public float M43;

		public float M44;

		private static readonly Matrix4x4 _identity = new Matrix4x4(1f, 0f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 0f, 1f);

		public static Matrix4x4 Identity => _identity;

		public bool IsIdentity
		{
			get
			{
				if (M11 == 1f && M22 == 1f && M33 == 1f && M44 == 1f && M12 == 0f && M13 == 0f && M14 == 0f && M21 == 0f && M23 == 0f && M24 == 0f && M31 == 0f && M32 == 0f && M34 == 0f && M41 == 0f && M42 == 0f)
				{
					return M43 == 0f;
				}
				return false;
			}
		}

		public Vector3 Translation
		{
			get
			{
				return new Vector3(M41, M42, M43);
			}
			set
			{
				M41 = value.X;
				M42 = value.Y;
				M43 = value.Z;
			}
		}

		public Matrix4x4(float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24, float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44)
		{
			M11 = m11;
			M12 = m12;
			M13 = m13;
			M14 = m14;
			M21 = m21;
			M22 = m22;
			M23 = m23;
			M24 = m24;
			M31 = m31;
			M32 = m32;
			M33 = m33;
			M34 = m34;
			M41 = m41;
			M42 = m42;
			M43 = m43;
			M44 = m44;
		}

		public Matrix4x4(Matrix3x2 value)
		{
			M11 = value.M11;
			M12 = value.M12;
			M13 = 0f;
			M14 = 0f;
			M21 = value.M21;
			M22 = value.M22;
			M23 = 0f;
			M24 = 0f;
			M31 = 0f;
			M32 = 0f;
			M33 = 1f;
			M34 = 0f;
			M41 = value.M31;
			M42 = value.M32;
			M43 = 0f;
			M44 = 1f;
		}

		public static Matrix4x4 CreateBillboard(Vector3 objectPosition, Vector3 cameraPosition, Vector3 cameraUpVector, Vector3 cameraForwardVector)
		{
			Vector3 left = new Vector3(objectPosition.X - cameraPosition.X, objectPosition.Y - cameraPosition.Y, objectPosition.Z - cameraPosition.Z);
			float num = left.LengthSquared();
			left = ((!(num < 0.0001f)) ? Vector3.Multiply(left, 1f / MathF.Sqrt(num)) : (-cameraForwardVector));
			Vector3 vector = Vector3.Normalize(Vector3.Cross(cameraUpVector, left));
			Vector3 vector2 = Vector3.Cross(left, vector);
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = vector.X;
			result.M12 = vector.Y;
			result.M13 = vector.Z;
			result.M14 = 0f;
			result.M21 = vector2.X;
			result.M22 = vector2.Y;
			result.M23 = vector2.Z;
			result.M24 = 0f;
			result.M31 = left.X;
			result.M32 = left.Y;
			result.M33 = left.Z;
			result.M34 = 0f;
			result.M41 = objectPosition.X;
			result.M42 = objectPosition.Y;
			result.M43 = objectPosition.Z;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateConstrainedBillboard(Vector3 objectPosition, Vector3 cameraPosition, Vector3 rotateAxis, Vector3 cameraForwardVector, Vector3 objectForwardVector)
		{
			Vector3 left = new Vector3(objectPosition.X - cameraPosition.X, objectPosition.Y - cameraPosition.Y, objectPosition.Z - cameraPosition.Z);
			float num = left.LengthSquared();
			left = ((!(num < 0.0001f)) ? Vector3.Multiply(left, 1f / MathF.Sqrt(num)) : (-cameraForwardVector));
			Vector3 vector = rotateAxis;
			float x = Vector3.Dot(rotateAxis, left);
			Vector3 vector3;
			Vector3 vector2;
			if (MathF.Abs(x) > 0.99825466f)
			{
				vector2 = objectForwardVector;
				x = Vector3.Dot(rotateAxis, vector2);
				if (MathF.Abs(x) > 0.99825466f)
				{
					vector2 = ((MathF.Abs(rotateAxis.Z) > 0.99825466f) ? new Vector3(1f, 0f, 0f) : new Vector3(0f, 0f, -1f));
				}
				vector3 = Vector3.Normalize(Vector3.Cross(rotateAxis, vector2));
				vector2 = Vector3.Normalize(Vector3.Cross(vector3, rotateAxis));
			}
			else
			{
				vector3 = Vector3.Normalize(Vector3.Cross(rotateAxis, left));
				vector2 = Vector3.Normalize(Vector3.Cross(vector3, vector));
			}
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = vector3.X;
			result.M12 = vector3.Y;
			result.M13 = vector3.Z;
			result.M14 = 0f;
			result.M21 = vector.X;
			result.M22 = vector.Y;
			result.M23 = vector.Z;
			result.M24 = 0f;
			result.M31 = vector2.X;
			result.M32 = vector2.Y;
			result.M33 = vector2.Z;
			result.M34 = 0f;
			result.M41 = objectPosition.X;
			result.M42 = objectPosition.Y;
			result.M43 = objectPosition.Z;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateTranslation(Vector3 position)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = 1f;
			result.M12 = 0f;
			result.M13 = 0f;
			result.M14 = 0f;
			result.M21 = 0f;
			result.M22 = 1f;
			result.M23 = 0f;
			result.M24 = 0f;
			result.M31 = 0f;
			result.M32 = 0f;
			result.M33 = 1f;
			result.M34 = 0f;
			result.M41 = position.X;
			result.M42 = position.Y;
			result.M43 = position.Z;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateTranslation(float xPosition, float yPosition, float zPosition)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = 1f;
			result.M12 = 0f;
			result.M13 = 0f;
			result.M14 = 0f;
			result.M21 = 0f;
			result.M22 = 1f;
			result.M23 = 0f;
			result.M24 = 0f;
			result.M31 = 0f;
			result.M32 = 0f;
			result.M33 = 1f;
			result.M34 = 0f;
			result.M41 = xPosition;
			result.M42 = yPosition;
			result.M43 = zPosition;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateScale(float xScale, float yScale, float zScale)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = xScale;
			result.M12 = 0f;
			result.M13 = 0f;
			result.M14 = 0f;
			result.M21 = 0f;
			result.M22 = yScale;
			result.M23 = 0f;
			result.M24 = 0f;
			result.M31 = 0f;
			result.M32 = 0f;
			result.M33 = zScale;
			result.M34 = 0f;
			result.M41 = 0f;
			result.M42 = 0f;
			result.M43 = 0f;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateScale(float xScale, float yScale, float zScale, Vector3 centerPoint)
		{
			float m = centerPoint.X * (1f - xScale);
			float m2 = centerPoint.Y * (1f - yScale);
			float m3 = centerPoint.Z * (1f - zScale);
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = xScale;
			result.M12 = 0f;
			result.M13 = 0f;
			result.M14 = 0f;
			result.M21 = 0f;
			result.M22 = yScale;
			result.M23 = 0f;
			result.M24 = 0f;
			result.M31 = 0f;
			result.M32 = 0f;
			result.M33 = zScale;
			result.M34 = 0f;
			result.M41 = m;
			result.M42 = m2;
			result.M43 = m3;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateScale(Vector3 scales)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = scales.X;
			result.M12 = 0f;
			result.M13 = 0f;
			result.M14 = 0f;
			result.M21 = 0f;
			result.M22 = scales.Y;
			result.M23 = 0f;
			result.M24 = 0f;
			result.M31 = 0f;
			result.M32 = 0f;
			result.M33 = scales.Z;
			result.M34 = 0f;
			result.M41 = 0f;
			result.M42 = 0f;
			result.M43 = 0f;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateScale(Vector3 scales, Vector3 centerPoint)
		{
			float m = centerPoint.X * (1f - scales.X);
			float m2 = centerPoint.Y * (1f - scales.Y);
			float m3 = centerPoint.Z * (1f - scales.Z);
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = scales.X;
			result.M12 = 0f;
			result.M13 = 0f;
			result.M14 = 0f;
			result.M21 = 0f;
			result.M22 = scales.Y;
			result.M23 = 0f;
			result.M24 = 0f;
			result.M31 = 0f;
			result.M32 = 0f;
			result.M33 = scales.Z;
			result.M34 = 0f;
			result.M41 = m;
			result.M42 = m2;
			result.M43 = m3;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateScale(float scale)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = scale;
			result.M12 = 0f;
			result.M13 = 0f;
			result.M14 = 0f;
			result.M21 = 0f;
			result.M22 = scale;
			result.M23 = 0f;
			result.M24 = 0f;
			result.M31 = 0f;
			result.M32 = 0f;
			result.M33 = scale;
			result.M34 = 0f;
			result.M41 = 0f;
			result.M42 = 0f;
			result.M43 = 0f;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateScale(float scale, Vector3 centerPoint)
		{
			float m = centerPoint.X * (1f - scale);
			float m2 = centerPoint.Y * (1f - scale);
			float m3 = centerPoint.Z * (1f - scale);
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = scale;
			result.M12 = 0f;
			result.M13 = 0f;
			result.M14 = 0f;
			result.M21 = 0f;
			result.M22 = scale;
			result.M23 = 0f;
			result.M24 = 0f;
			result.M31 = 0f;
			result.M32 = 0f;
			result.M33 = scale;
			result.M34 = 0f;
			result.M41 = m;
			result.M42 = m2;
			result.M43 = m3;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateRotationX(float radians)
		{
			float num = MathF.Cos(radians);
			float num2 = MathF.Sin(radians);
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = 1f;
			result.M12 = 0f;
			result.M13 = 0f;
			result.M14 = 0f;
			result.M21 = 0f;
			result.M22 = num;
			result.M23 = num2;
			result.M24 = 0f;
			result.M31 = 0f;
			result.M32 = 0f - num2;
			result.M33 = num;
			result.M34 = 0f;
			result.M41 = 0f;
			result.M42 = 0f;
			result.M43 = 0f;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateRotationX(float radians, Vector3 centerPoint)
		{
			float num = MathF.Cos(radians);
			float num2 = MathF.Sin(radians);
			float m = centerPoint.Y * (1f - num) + centerPoint.Z * num2;
			float m2 = centerPoint.Z * (1f - num) - centerPoint.Y * num2;
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = 1f;
			result.M12 = 0f;
			result.M13 = 0f;
			result.M14 = 0f;
			result.M21 = 0f;
			result.M22 = num;
			result.M23 = num2;
			result.M24 = 0f;
			result.M31 = 0f;
			result.M32 = 0f - num2;
			result.M33 = num;
			result.M34 = 0f;
			result.M41 = 0f;
			result.M42 = m;
			result.M43 = m2;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateRotationY(float radians)
		{
			float num = MathF.Cos(radians);
			float num2 = MathF.Sin(radians);
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = num;
			result.M12 = 0f;
			result.M13 = 0f - num2;
			result.M14 = 0f;
			result.M21 = 0f;
			result.M22 = 1f;
			result.M23 = 0f;
			result.M24 = 0f;
			result.M31 = num2;
			result.M32 = 0f;
			result.M33 = num;
			result.M34 = 0f;
			result.M41 = 0f;
			result.M42 = 0f;
			result.M43 = 0f;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateRotationY(float radians, Vector3 centerPoint)
		{
			float num = MathF.Cos(radians);
			float num2 = MathF.Sin(radians);
			float m = centerPoint.X * (1f - num) - centerPoint.Z * num2;
			float m2 = centerPoint.Z * (1f - num) + centerPoint.X * num2;
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = num;
			result.M12 = 0f;
			result.M13 = 0f - num2;
			result.M14 = 0f;
			result.M21 = 0f;
			result.M22 = 1f;
			result.M23 = 0f;
			result.M24 = 0f;
			result.M31 = num2;
			result.M32 = 0f;
			result.M33 = num;
			result.M34 = 0f;
			result.M41 = m;
			result.M42 = 0f;
			result.M43 = m2;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateRotationZ(float radians)
		{
			float num = MathF.Cos(radians);
			float num2 = MathF.Sin(radians);
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = num;
			result.M12 = num2;
			result.M13 = 0f;
			result.M14 = 0f;
			result.M21 = 0f - num2;
			result.M22 = num;
			result.M23 = 0f;
			result.M24 = 0f;
			result.M31 = 0f;
			result.M32 = 0f;
			result.M33 = 1f;
			result.M34 = 0f;
			result.M41 = 0f;
			result.M42 = 0f;
			result.M43 = 0f;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateRotationZ(float radians, Vector3 centerPoint)
		{
			float num = MathF.Cos(radians);
			float num2 = MathF.Sin(radians);
			float m = centerPoint.X * (1f - num) + centerPoint.Y * num2;
			float m2 = centerPoint.Y * (1f - num) - centerPoint.X * num2;
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = num;
			result.M12 = num2;
			result.M13 = 0f;
			result.M14 = 0f;
			result.M21 = 0f - num2;
			result.M22 = num;
			result.M23 = 0f;
			result.M24 = 0f;
			result.M31 = 0f;
			result.M32 = 0f;
			result.M33 = 1f;
			result.M34 = 0f;
			result.M41 = m;
			result.M42 = m2;
			result.M43 = 0f;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateFromAxisAngle(Vector3 axis, float angle)
		{
			float x = axis.X;
			float y = axis.Y;
			float z = axis.Z;
			float num = MathF.Sin(angle);
			float num2 = MathF.Cos(angle);
			float num3 = x * x;
			float num4 = y * y;
			float num5 = z * z;
			float num6 = x * y;
			float num7 = x * z;
			float num8 = y * z;
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = num3 + num2 * (1f - num3);
			result.M12 = num6 - num2 * num6 + num * z;
			result.M13 = num7 - num2 * num7 - num * y;
			result.M14 = 0f;
			result.M21 = num6 - num2 * num6 - num * z;
			result.M22 = num4 + num2 * (1f - num4);
			result.M23 = num8 - num2 * num8 + num * x;
			result.M24 = 0f;
			result.M31 = num7 - num2 * num7 + num * y;
			result.M32 = num8 - num2 * num8 - num * x;
			result.M33 = num5 + num2 * (1f - num5);
			result.M34 = 0f;
			result.M41 = 0f;
			result.M42 = 0f;
			result.M43 = 0f;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreatePerspectiveFieldOfView(float fieldOfView, float aspectRatio, float nearPlaneDistance, float farPlaneDistance)
		{
			if (fieldOfView <= 0f || fieldOfView >= (float)Math.PI)
			{
				throw new ArgumentOutOfRangeException("fieldOfView");
			}
			if (nearPlaneDistance <= 0f)
			{
				throw new ArgumentOutOfRangeException("nearPlaneDistance");
			}
			if (farPlaneDistance <= 0f)
			{
				throw new ArgumentOutOfRangeException("farPlaneDistance");
			}
			if (nearPlaneDistance >= farPlaneDistance)
			{
				throw new ArgumentOutOfRangeException("nearPlaneDistance");
			}
			float num = 1f / MathF.Tan(fieldOfView * 0.5f);
			float m = num / aspectRatio;
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = m;
			result.M12 = (result.M13 = (result.M14 = 0f));
			result.M22 = num;
			result.M21 = (result.M23 = (result.M24 = 0f));
			result.M31 = (result.M32 = 0f);
			float num2 = (result.M33 = (float.IsPositiveInfinity(farPlaneDistance) ? (-1f) : (farPlaneDistance / (nearPlaneDistance - farPlaneDistance))));
			result.M34 = -1f;
			result.M41 = (result.M42 = (result.M44 = 0f));
			result.M43 = nearPlaneDistance * num2;
			return result;
		}

		public static Matrix4x4 CreatePerspective(float width, float height, float nearPlaneDistance, float farPlaneDistance)
		{
			if (nearPlaneDistance <= 0f)
			{
				throw new ArgumentOutOfRangeException("nearPlaneDistance");
			}
			if (farPlaneDistance <= 0f)
			{
				throw new ArgumentOutOfRangeException("farPlaneDistance");
			}
			if (nearPlaneDistance >= farPlaneDistance)
			{
				throw new ArgumentOutOfRangeException("nearPlaneDistance");
			}
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = 2f * nearPlaneDistance / width;
			result.M12 = (result.M13 = (result.M14 = 0f));
			result.M22 = 2f * nearPlaneDistance / height;
			result.M21 = (result.M23 = (result.M24 = 0f));
			float num = (result.M33 = (float.IsPositiveInfinity(farPlaneDistance) ? (-1f) : (farPlaneDistance / (nearPlaneDistance - farPlaneDistance))));
			result.M31 = (result.M32 = 0f);
			result.M34 = -1f;
			result.M41 = (result.M42 = (result.M44 = 0f));
			result.M43 = nearPlaneDistance * num;
			return result;
		}

		public static Matrix4x4 CreatePerspectiveOffCenter(float left, float right, float bottom, float top, float nearPlaneDistance, float farPlaneDistance)
		{
			if (nearPlaneDistance <= 0f)
			{
				throw new ArgumentOutOfRangeException("nearPlaneDistance");
			}
			if (farPlaneDistance <= 0f)
			{
				throw new ArgumentOutOfRangeException("farPlaneDistance");
			}
			if (nearPlaneDistance >= farPlaneDistance)
			{
				throw new ArgumentOutOfRangeException("nearPlaneDistance");
			}
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = 2f * nearPlaneDistance / (right - left);
			result.M12 = (result.M13 = (result.M14 = 0f));
			result.M22 = 2f * nearPlaneDistance / (top - bottom);
			result.M21 = (result.M23 = (result.M24 = 0f));
			result.M31 = (left + right) / (right - left);
			result.M32 = (top + bottom) / (top - bottom);
			float num = (result.M33 = (float.IsPositiveInfinity(farPlaneDistance) ? (-1f) : (farPlaneDistance / (nearPlaneDistance - farPlaneDistance))));
			result.M34 = -1f;
			result.M43 = nearPlaneDistance * num;
			result.M41 = (result.M42 = (result.M44 = 0f));
			return result;
		}

		public static Matrix4x4 CreateOrthographic(float width, float height, float zNearPlane, float zFarPlane)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = 2f / width;
			result.M12 = (result.M13 = (result.M14 = 0f));
			result.M22 = 2f / height;
			result.M21 = (result.M23 = (result.M24 = 0f));
			result.M33 = 1f / (zNearPlane - zFarPlane);
			result.M31 = (result.M32 = (result.M34 = 0f));
			result.M41 = (result.M42 = 0f);
			result.M43 = zNearPlane / (zNearPlane - zFarPlane);
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateOrthographicOffCenter(float left, float right, float bottom, float top, float zNearPlane, float zFarPlane)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = 2f / (right - left);
			result.M12 = (result.M13 = (result.M14 = 0f));
			result.M22 = 2f / (top - bottom);
			result.M21 = (result.M23 = (result.M24 = 0f));
			result.M33 = 1f / (zNearPlane - zFarPlane);
			result.M31 = (result.M32 = (result.M34 = 0f));
			result.M41 = (left + right) / (left - right);
			result.M42 = (top + bottom) / (bottom - top);
			result.M43 = zNearPlane / (zNearPlane - zFarPlane);
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateLookAt(Vector3 cameraPosition, Vector3 cameraTarget, Vector3 cameraUpVector)
		{
			Vector3 vector = Vector3.Normalize(cameraPosition - cameraTarget);
			Vector3 vector2 = Vector3.Normalize(Vector3.Cross(cameraUpVector, vector));
			Vector3 vector3 = Vector3.Cross(vector, vector2);
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = vector2.X;
			result.M12 = vector3.X;
			result.M13 = vector.X;
			result.M14 = 0f;
			result.M21 = vector2.Y;
			result.M22 = vector3.Y;
			result.M23 = vector.Y;
			result.M24 = 0f;
			result.M31 = vector2.Z;
			result.M32 = vector3.Z;
			result.M33 = vector.Z;
			result.M34 = 0f;
			result.M41 = 0f - Vector3.Dot(vector2, cameraPosition);
			result.M42 = 0f - Vector3.Dot(vector3, cameraPosition);
			result.M43 = 0f - Vector3.Dot(vector, cameraPosition);
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateWorld(Vector3 position, Vector3 forward, Vector3 up)
		{
			Vector3 vector = Vector3.Normalize(-forward);
			Vector3 vector2 = Vector3.Normalize(Vector3.Cross(up, vector));
			Vector3 vector3 = Vector3.Cross(vector, vector2);
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = vector2.X;
			result.M12 = vector2.Y;
			result.M13 = vector2.Z;
			result.M14 = 0f;
			result.M21 = vector3.X;
			result.M22 = vector3.Y;
			result.M23 = vector3.Z;
			result.M24 = 0f;
			result.M31 = vector.X;
			result.M32 = vector.Y;
			result.M33 = vector.Z;
			result.M34 = 0f;
			result.M41 = position.X;
			result.M42 = position.Y;
			result.M43 = position.Z;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateFromQuaternion(Quaternion quaternion)
		{
			float num = quaternion.X * quaternion.X;
			float num2 = quaternion.Y * quaternion.Y;
			float num3 = quaternion.Z * quaternion.Z;
			float num4 = quaternion.X * quaternion.Y;
			float num5 = quaternion.Z * quaternion.W;
			float num6 = quaternion.Z * quaternion.X;
			float num7 = quaternion.Y * quaternion.W;
			float num8 = quaternion.Y * quaternion.Z;
			float num9 = quaternion.X * quaternion.W;
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = 1f - 2f * (num2 + num3);
			result.M12 = 2f * (num4 + num5);
			result.M13 = 2f * (num6 - num7);
			result.M14 = 0f;
			result.M21 = 2f * (num4 - num5);
			result.M22 = 1f - 2f * (num3 + num);
			result.M23 = 2f * (num8 + num9);
			result.M24 = 0f;
			result.M31 = 2f * (num6 + num7);
			result.M32 = 2f * (num8 - num9);
			result.M33 = 1f - 2f * (num2 + num);
			result.M34 = 0f;
			result.M41 = 0f;
			result.M42 = 0f;
			result.M43 = 0f;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateFromYawPitchRoll(float yaw, float pitch, float roll)
		{
			Quaternion quaternion = Quaternion.CreateFromYawPitchRoll(yaw, pitch, roll);
			return CreateFromQuaternion(quaternion);
		}

		public static Matrix4x4 CreateShadow(Vector3 lightDirection, Plane plane)
		{
			Plane plane2 = Plane.Normalize(plane);
			float num = plane2.Normal.X * lightDirection.X + plane2.Normal.Y * lightDirection.Y + plane2.Normal.Z * lightDirection.Z;
			float num2 = 0f - plane2.Normal.X;
			float num3 = 0f - plane2.Normal.Y;
			float num4 = 0f - plane2.Normal.Z;
			float num5 = 0f - plane2.D;
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = num2 * lightDirection.X + num;
			result.M21 = num3 * lightDirection.X;
			result.M31 = num4 * lightDirection.X;
			result.M41 = num5 * lightDirection.X;
			result.M12 = num2 * lightDirection.Y;
			result.M22 = num3 * lightDirection.Y + num;
			result.M32 = num4 * lightDirection.Y;
			result.M42 = num5 * lightDirection.Y;
			result.M13 = num2 * lightDirection.Z;
			result.M23 = num3 * lightDirection.Z;
			result.M33 = num4 * lightDirection.Z + num;
			result.M43 = num5 * lightDirection.Z;
			result.M14 = 0f;
			result.M24 = 0f;
			result.M34 = 0f;
			result.M44 = num;
			return result;
		}

		public static Matrix4x4 CreateReflection(Plane value)
		{
			value = Plane.Normalize(value);
			float x = value.Normal.X;
			float y = value.Normal.Y;
			float z = value.Normal.Z;
			float num = -2f * x;
			float num2 = -2f * y;
			float num3 = -2f * z;
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = num * x + 1f;
			result.M12 = num2 * x;
			result.M13 = num3 * x;
			result.M14 = 0f;
			result.M21 = num * y;
			result.M22 = num2 * y + 1f;
			result.M23 = num3 * y;
			result.M24 = 0f;
			result.M31 = num * z;
			result.M32 = num2 * z;
			result.M33 = num3 * z + 1f;
			result.M34 = 0f;
			result.M41 = num * value.D;
			result.M42 = num2 * value.D;
			result.M43 = num3 * value.D;
			result.M44 = 1f;
			return result;
		}

		public float GetDeterminant()
		{
			float m = M11;
			float m2 = M12;
			float m3 = M13;
			float m4 = M14;
			float m5 = M21;
			float m6 = M22;
			float m7 = M23;
			float m8 = M24;
			float m9 = M31;
			float m10 = M32;
			float m11 = M33;
			float m12 = M34;
			float m13 = M41;
			float m14 = M42;
			float m15 = M43;
			float m16 = M44;
			float num = m11 * m16 - m12 * m15;
			float num2 = m10 * m16 - m12 * m14;
			float num3 = m10 * m15 - m11 * m14;
			float num4 = m9 * m16 - m12 * m13;
			float num5 = m9 * m15 - m11 * m13;
			float num6 = m9 * m14 - m10 * m13;
			return m * (m6 * num - m7 * num2 + m8 * num3) - m2 * (m5 * num - m7 * num4 + m8 * num5) + m3 * (m5 * num2 - m6 * num4 + m8 * num6) - m4 * (m5 * num3 - m6 * num5 + m7 * num6);
		}

		public static bool Invert(Matrix4x4 matrix, out Matrix4x4 result)
		{
			float m = matrix.M11;
			float m2 = matrix.M12;
			float m3 = matrix.M13;
			float m4 = matrix.M14;
			float m5 = matrix.M21;
			float m6 = matrix.M22;
			float m7 = matrix.M23;
			float m8 = matrix.M24;
			float m9 = matrix.M31;
			float m10 = matrix.M32;
			float m11 = matrix.M33;
			float m12 = matrix.M34;
			float m13 = matrix.M41;
			float m14 = matrix.M42;
			float m15 = matrix.M43;
			float m16 = matrix.M44;
			float num = m11 * m16 - m12 * m15;
			float num2 = m10 * m16 - m12 * m14;
			float num3 = m10 * m15 - m11 * m14;
			float num4 = m9 * m16 - m12 * m13;
			float num5 = m9 * m15 - m11 * m13;
			float num6 = m9 * m14 - m10 * m13;
			float num7 = m6 * num - m7 * num2 + m8 * num3;
			float num8 = 0f - (m5 * num - m7 * num4 + m8 * num5);
			float num9 = m5 * num2 - m6 * num4 + m8 * num6;
			float num10 = 0f - (m5 * num3 - m6 * num5 + m7 * num6);
			float num11 = m * num7 + m2 * num8 + m3 * num9 + m4 * num10;
			if (MathF.Abs(num11) < float.Epsilon)
			{
				result = new Matrix4x4(float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN);
				return false;
			}
			float num12 = 1f / num11;
			result.M11 = num7 * num12;
			result.M21 = num8 * num12;
			result.M31 = num9 * num12;
			result.M41 = num10 * num12;
			result.M12 = (0f - (m2 * num - m3 * num2 + m4 * num3)) * num12;
			result.M22 = (m * num - m3 * num4 + m4 * num5) * num12;
			result.M32 = (0f - (m * num2 - m2 * num4 + m4 * num6)) * num12;
			result.M42 = (m * num3 - m2 * num5 + m3 * num6) * num12;
			float num13 = m7 * m16 - m8 * m15;
			float num14 = m6 * m16 - m8 * m14;
			float num15 = m6 * m15 - m7 * m14;
			float num16 = m5 * m16 - m8 * m13;
			float num17 = m5 * m15 - m7 * m13;
			float num18 = m5 * m14 - m6 * m13;
			result.M13 = (m2 * num13 - m3 * num14 + m4 * num15) * num12;
			result.M23 = (0f - (m * num13 - m3 * num16 + m4 * num17)) * num12;
			result.M33 = (m * num14 - m2 * num16 + m4 * num18) * num12;
			result.M43 = (0f - (m * num15 - m2 * num17 + m3 * num18)) * num12;
			float num19 = m7 * m12 - m8 * m11;
			float num20 = m6 * m12 - m8 * m10;
			float num21 = m6 * m11 - m7 * m10;
			float num22 = m5 * m12 - m8 * m9;
			float num23 = m5 * m11 - m7 * m9;
			float num24 = m5 * m10 - m6 * m9;
			result.M14 = (0f - (m2 * num19 - m3 * num20 + m4 * num21)) * num12;
			result.M24 = (m * num19 - m3 * num22 + m4 * num23) * num12;
			result.M34 = (0f - (m * num20 - m2 * num22 + m4 * num24)) * num12;
			result.M44 = (m * num21 - m2 * num23 + m3 * num24) * num12;
			return true;
		}

		public unsafe static bool Decompose(Matrix4x4 matrix, out Vector3 scale, out Quaternion rotation, out Vector3 translation)
		{
			bool result = true;
			fixed (Vector3* ptr = &scale)
			{
				float* ptr2 = (float*)ptr;
				VectorBasis vectorBasis = default(VectorBasis);
				Vector3** ptr3 = (Vector3**)(&vectorBasis);
				Matrix4x4 identity = Identity;
				CanonicalBasis canonicalBasis = default(CanonicalBasis);
				Vector3* ptr4 = &canonicalBasis.Row0;
				canonicalBasis.Row0 = new Vector3(1f, 0f, 0f);
				canonicalBasis.Row1 = new Vector3(0f, 1f, 0f);
				canonicalBasis.Row2 = new Vector3(0f, 0f, 1f);
				translation = new Vector3(matrix.M41, matrix.M42, matrix.M43);
				*ptr3 = (Vector3*)(&identity.M11);
				ptr3[1] = (Vector3*)(&identity.M21);
				ptr3[2] = (Vector3*)(&identity.M31);
				*(*ptr3) = new Vector3(matrix.M11, matrix.M12, matrix.M13);
				*ptr3[1] = new Vector3(matrix.M21, matrix.M22, matrix.M23);
				*ptr3[2] = new Vector3(matrix.M31, matrix.M32, matrix.M33);
				scale.X = (*ptr3)->Length();
				scale.Y = ptr3[1]->Length();
				scale.Z = ptr3[2]->Length();
				float num = *ptr2;
				float num2 = ptr2[1];
				float num3 = ptr2[2];
				uint num4;
				uint num5;
				uint num6;
				if (num < num2)
				{
					if (num2 < num3)
					{
						num4 = 2u;
						num5 = 1u;
						num6 = 0u;
					}
					else
					{
						num4 = 1u;
						if (num < num3)
						{
							num5 = 2u;
							num6 = 0u;
						}
						else
						{
							num5 = 0u;
							num6 = 2u;
						}
					}
				}
				else if (num < num3)
				{
					num4 = 2u;
					num5 = 0u;
					num6 = 1u;
				}
				else
				{
					num4 = 0u;
					if (num2 < num3)
					{
						num5 = 2u;
						num6 = 1u;
					}
					else
					{
						num5 = 1u;
						num6 = 2u;
					}
				}
				if (ptr2[num4] < 0.0001f)
				{
					*ptr3[num4] = ptr4[num4];
				}
				*ptr3[num4] = Vector3.Normalize(*ptr3[num4]);
				if (ptr2[num5] < 0.0001f)
				{
					float num7 = MathF.Abs(ptr3[num4]->X);
					float num8 = MathF.Abs(ptr3[num4]->Y);
					float num9 = MathF.Abs(ptr3[num4]->Z);
					uint num10 = ((num7 < num8) ? ((!(num8 < num9)) ? ((!(num7 < num9)) ? 2u : 0u) : 0u) : ((num7 < num9) ? 1u : ((num8 < num9) ? 1u : 2u)));
					*ptr3[num5] = Vector3.Cross(*ptr3[num4], ptr4[num10]);
				}
				*ptr3[num5] = Vector3.Normalize(*ptr3[num5]);
				if (ptr2[num6] < 0.0001f)
				{
					*ptr3[num6] = Vector3.Cross(*ptr3[num4], *ptr3[num5]);
				}
				*ptr3[num6] = Vector3.Normalize(*ptr3[num6]);
				float num11 = identity.GetDeterminant();
				if (num11 < 0f)
				{
					ptr2[num4] = 0f - ptr2[num4];
					*ptr3[num4] = -(*ptr3[num4]);
					num11 = 0f - num11;
				}
				num11 -= 1f;
				num11 *= num11;
				if (0.0001f < num11)
				{
					rotation = Quaternion.Identity;
					result = false;
				}
				else
				{
					rotation = Quaternion.CreateFromRotationMatrix(identity);
				}
			}
			return result;
		}

		public static Matrix4x4 Transform(Matrix4x4 value, Quaternion rotation)
		{
			float num = rotation.X + rotation.X;
			float num2 = rotation.Y + rotation.Y;
			float num3 = rotation.Z + rotation.Z;
			float num4 = rotation.W * num;
			float num5 = rotation.W * num2;
			float num6 = rotation.W * num3;
			float num7 = rotation.X * num;
			float num8 = rotation.X * num2;
			float num9 = rotation.X * num3;
			float num10 = rotation.Y * num2;
			float num11 = rotation.Y * num3;
			float num12 = rotation.Z * num3;
			float num13 = 1f - num10 - num12;
			float num14 = num8 - num6;
			float num15 = num9 + num5;
			float num16 = num8 + num6;
			float num17 = 1f - num7 - num12;
			float num18 = num11 - num4;
			float num19 = num9 - num5;
			float num20 = num11 + num4;
			float num21 = 1f - num7 - num10;
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = value.M11 * num13 + value.M12 * num14 + value.M13 * num15;
			result.M12 = value.M11 * num16 + value.M12 * num17 + value.M13 * num18;
			result.M13 = value.M11 * num19 + value.M12 * num20 + value.M13 * num21;
			result.M14 = value.M14;
			result.M21 = value.M21 * num13 + value.M22 * num14 + value.M23 * num15;
			result.M22 = value.M21 * num16 + value.M22 * num17 + value.M23 * num18;
			result.M23 = value.M21 * num19 + value.M22 * num20 + value.M23 * num21;
			result.M24 = value.M24;
			result.M31 = value.M31 * num13 + value.M32 * num14 + value.M33 * num15;
			result.M32 = value.M31 * num16 + value.M32 * num17 + value.M33 * num18;
			result.M33 = value.M31 * num19 + value.M32 * num20 + value.M33 * num21;
			result.M34 = value.M34;
			result.M41 = value.M41 * num13 + value.M42 * num14 + value.M43 * num15;
			result.M42 = value.M41 * num16 + value.M42 * num17 + value.M43 * num18;
			result.M43 = value.M41 * num19 + value.M42 * num20 + value.M43 * num21;
			result.M44 = value.M44;
			return result;
		}

		public static Matrix4x4 Transpose(Matrix4x4 matrix)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = matrix.M11;
			result.M12 = matrix.M21;
			result.M13 = matrix.M31;
			result.M14 = matrix.M41;
			result.M21 = matrix.M12;
			result.M22 = matrix.M22;
			result.M23 = matrix.M32;
			result.M24 = matrix.M42;
			result.M31 = matrix.M13;
			result.M32 = matrix.M23;
			result.M33 = matrix.M33;
			result.M34 = matrix.M43;
			result.M41 = matrix.M14;
			result.M42 = matrix.M24;
			result.M43 = matrix.M34;
			result.M44 = matrix.M44;
			return result;
		}

		public static Matrix4x4 Lerp(Matrix4x4 matrix1, Matrix4x4 matrix2, float amount)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = matrix1.M11 + (matrix2.M11 - matrix1.M11) * amount;
			result.M12 = matrix1.M12 + (matrix2.M12 - matrix1.M12) * amount;
			result.M13 = matrix1.M13 + (matrix2.M13 - matrix1.M13) * amount;
			result.M14 = matrix1.M14 + (matrix2.M14 - matrix1.M14) * amount;
			result.M21 = matrix1.M21 + (matrix2.M21 - matrix1.M21) * amount;
			result.M22 = matrix1.M22 + (matrix2.M22 - matrix1.M22) * amount;
			result.M23 = matrix1.M23 + (matrix2.M23 - matrix1.M23) * amount;
			result.M24 = matrix1.M24 + (matrix2.M24 - matrix1.M24) * amount;
			result.M31 = matrix1.M31 + (matrix2.M31 - matrix1.M31) * amount;
			result.M32 = matrix1.M32 + (matrix2.M32 - matrix1.M32) * amount;
			result.M33 = matrix1.M33 + (matrix2.M33 - matrix1.M33) * amount;
			result.M34 = matrix1.M34 + (matrix2.M34 - matrix1.M34) * amount;
			result.M41 = matrix1.M41 + (matrix2.M41 - matrix1.M41) * amount;
			result.M42 = matrix1.M42 + (matrix2.M42 - matrix1.M42) * amount;
			result.M43 = matrix1.M43 + (matrix2.M43 - matrix1.M43) * amount;
			result.M44 = matrix1.M44 + (matrix2.M44 - matrix1.M44) * amount;
			return result;
		}

		public static Matrix4x4 Negate(Matrix4x4 value)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = 0f - value.M11;
			result.M12 = 0f - value.M12;
			result.M13 = 0f - value.M13;
			result.M14 = 0f - value.M14;
			result.M21 = 0f - value.M21;
			result.M22 = 0f - value.M22;
			result.M23 = 0f - value.M23;
			result.M24 = 0f - value.M24;
			result.M31 = 0f - value.M31;
			result.M32 = 0f - value.M32;
			result.M33 = 0f - value.M33;
			result.M34 = 0f - value.M34;
			result.M41 = 0f - value.M41;
			result.M42 = 0f - value.M42;
			result.M43 = 0f - value.M43;
			result.M44 = 0f - value.M44;
			return result;
		}

		public static Matrix4x4 Add(Matrix4x4 value1, Matrix4x4 value2)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = value1.M11 + value2.M11;
			result.M12 = value1.M12 + value2.M12;
			result.M13 = value1.M13 + value2.M13;
			result.M14 = value1.M14 + value2.M14;
			result.M21 = value1.M21 + value2.M21;
			result.M22 = value1.M22 + value2.M22;
			result.M23 = value1.M23 + value2.M23;
			result.M24 = value1.M24 + value2.M24;
			result.M31 = value1.M31 + value2.M31;
			result.M32 = value1.M32 + value2.M32;
			result.M33 = value1.M33 + value2.M33;
			result.M34 = value1.M34 + value2.M34;
			result.M41 = value1.M41 + value2.M41;
			result.M42 = value1.M42 + value2.M42;
			result.M43 = value1.M43 + value2.M43;
			result.M44 = value1.M44 + value2.M44;
			return result;
		}

		public static Matrix4x4 Subtract(Matrix4x4 value1, Matrix4x4 value2)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = value1.M11 - value2.M11;
			result.M12 = value1.M12 - value2.M12;
			result.M13 = value1.M13 - value2.M13;
			result.M14 = value1.M14 - value2.M14;
			result.M21 = value1.M21 - value2.M21;
			result.M22 = value1.M22 - value2.M22;
			result.M23 = value1.M23 - value2.M23;
			result.M24 = value1.M24 - value2.M24;
			result.M31 = value1.M31 - value2.M31;
			result.M32 = value1.M32 - value2.M32;
			result.M33 = value1.M33 - value2.M33;
			result.M34 = value1.M34 - value2.M34;
			result.M41 = value1.M41 - value2.M41;
			result.M42 = value1.M42 - value2.M42;
			result.M43 = value1.M43 - value2.M43;
			result.M44 = value1.M44 - value2.M44;
			return result;
		}

		public static Matrix4x4 Multiply(Matrix4x4 value1, Matrix4x4 value2)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = value1.M11 * value2.M11 + value1.M12 * value2.M21 + value1.M13 * value2.M31 + value1.M14 * value2.M41;
			result.M12 = value1.M11 * value2.M12 + value1.M12 * value2.M22 + value1.M13 * value2.M32 + value1.M14 * value2.M42;
			result.M13 = value1.M11 * value2.M13 + value1.M12 * value2.M23 + value1.M13 * value2.M33 + value1.M14 * value2.M43;
			result.M14 = value1.M11 * value2.M14 + value1.M12 * value2.M24 + value1.M13 * value2.M34 + value1.M14 * value2.M44;
			result.M21 = value1.M21 * value2.M11 + value1.M22 * value2.M21 + value1.M23 * value2.M31 + value1.M24 * value2.M41;
			result.M22 = value1.M21 * value2.M12 + value1.M22 * value2.M22 + value1.M23 * value2.M32 + value1.M24 * value2.M42;
			result.M23 = value1.M21 * value2.M13 + value1.M22 * value2.M23 + value1.M23 * value2.M33 + value1.M24 * value2.M43;
			result.M24 = value1.M21 * value2.M14 + value1.M22 * value2.M24 + value1.M23 * value2.M34 + value1.M24 * value2.M44;
			result.M31 = value1.M31 * value2.M11 + value1.M32 * value2.M21 + value1.M33 * value2.M31 + value1.M34 * value2.M41;
			result.M32 = value1.M31 * value2.M12 + value1.M32 * value2.M22 + value1.M33 * value2.M32 + value1.M34 * value2.M42;
			result.M33 = value1.M31 * value2.M13 + value1.M32 * value2.M23 + value1.M33 * value2.M33 + value1.M34 * value2.M43;
			result.M34 = value1.M31 * value2.M14 + value1.M32 * value2.M24 + value1.M33 * value2.M34 + value1.M34 * value2.M44;
			result.M41 = value1.M41 * value2.M11 + value1.M42 * value2.M21 + value1.M43 * value2.M31 + value1.M44 * value2.M41;
			result.M42 = value1.M41 * value2.M12 + value1.M42 * value2.M22 + value1.M43 * value2.M32 + value1.M44 * value2.M42;
			result.M43 = value1.M41 * value2.M13 + value1.M42 * value2.M23 + value1.M43 * value2.M33 + value1.M44 * value2.M43;
			result.M44 = value1.M41 * value2.M14 + value1.M42 * value2.M24 + value1.M43 * value2.M34 + value1.M44 * value2.M44;
			return result;
		}

		public static Matrix4x4 Multiply(Matrix4x4 value1, float value2)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = value1.M11 * value2;
			result.M12 = value1.M12 * value2;
			result.M13 = value1.M13 * value2;
			result.M14 = value1.M14 * value2;
			result.M21 = value1.M21 * value2;
			result.M22 = value1.M22 * value2;
			result.M23 = value1.M23 * value2;
			result.M24 = value1.M24 * value2;
			result.M31 = value1.M31 * value2;
			result.M32 = value1.M32 * value2;
			result.M33 = value1.M33 * value2;
			result.M34 = value1.M34 * value2;
			result.M41 = value1.M41 * value2;
			result.M42 = value1.M42 * value2;
			result.M43 = value1.M43 * value2;
			result.M44 = value1.M44 * value2;
			return result;
		}

		public static Matrix4x4 operator -(Matrix4x4 value)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = 0f - value.M11;
			result.M12 = 0f - value.M12;
			result.M13 = 0f - value.M13;
			result.M14 = 0f - value.M14;
			result.M21 = 0f - value.M21;
			result.M22 = 0f - value.M22;
			result.M23 = 0f - value.M23;
			result.M24 = 0f - value.M24;
			result.M31 = 0f - value.M31;
			result.M32 = 0f - value.M32;
			result.M33 = 0f - value.M33;
			result.M34 = 0f - value.M34;
			result.M41 = 0f - value.M41;
			result.M42 = 0f - value.M42;
			result.M43 = 0f - value.M43;
			result.M44 = 0f - value.M44;
			return result;
		}

		public static Matrix4x4 operator +(Matrix4x4 value1, Matrix4x4 value2)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = value1.M11 + value2.M11;
			result.M12 = value1.M12 + value2.M12;
			result.M13 = value1.M13 + value2.M13;
			result.M14 = value1.M14 + value2.M14;
			result.M21 = value1.M21 + value2.M21;
			result.M22 = value1.M22 + value2.M22;
			result.M23 = value1.M23 + value2.M23;
			result.M24 = value1.M24 + value2.M24;
			result.M31 = value1.M31 + value2.M31;
			result.M32 = value1.M32 + value2.M32;
			result.M33 = value1.M33 + value2.M33;
			result.M34 = value1.M34 + value2.M34;
			result.M41 = value1.M41 + value2.M41;
			result.M42 = value1.M42 + value2.M42;
			result.M43 = value1.M43 + value2.M43;
			result.M44 = value1.M44 + value2.M44;
			return result;
		}

		public static Matrix4x4 operator -(Matrix4x4 value1, Matrix4x4 value2)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = value1.M11 - value2.M11;
			result.M12 = value1.M12 - value2.M12;
			result.M13 = value1.M13 - value2.M13;
			result.M14 = value1.M14 - value2.M14;
			result.M21 = value1.M21 - value2.M21;
			result.M22 = value1.M22 - value2.M22;
			result.M23 = value1.M23 - value2.M23;
			result.M24 = value1.M24 - value2.M24;
			result.M31 = value1.M31 - value2.M31;
			result.M32 = value1.M32 - value2.M32;
			result.M33 = value1.M33 - value2.M33;
			result.M34 = value1.M34 - value2.M34;
			result.M41 = value1.M41 - value2.M41;
			result.M42 = value1.M42 - value2.M42;
			result.M43 = value1.M43 - value2.M43;
			result.M44 = value1.M44 - value2.M44;
			return result;
		}

		public static Matrix4x4 operator *(Matrix4x4 value1, Matrix4x4 value2)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = value1.M11 * value2.M11 + value1.M12 * value2.M21 + value1.M13 * value2.M31 + value1.M14 * value2.M41;
			result.M12 = value1.M11 * value2.M12 + value1.M12 * value2.M22 + value1.M13 * value2.M32 + value1.M14 * value2.M42;
			result.M13 = value1.M11 * value2.M13 + value1.M12 * value2.M23 + value1.M13 * value2.M33 + value1.M14 * value2.M43;
			result.M14 = value1.M11 * value2.M14 + value1.M12 * value2.M24 + value1.M13 * value2.M34 + value1.M14 * value2.M44;
			result.M21 = value1.M21 * value2.M11 + value1.M22 * value2.M21 + value1.M23 * value2.M31 + value1.M24 * value2.M41;
			result.M22 = value1.M21 * value2.M12 + value1.M22 * value2.M22 + value1.M23 * value2.M32 + value1.M24 * value2.M42;
			result.M23 = value1.M21 * value2.M13 + value1.M22 * value2.M23 + value1.M23 * value2.M33 + value1.M24 * value2.M43;
			result.M24 = value1.M21 * value2.M14 + value1.M22 * value2.M24 + value1.M23 * value2.M34 + value1.M24 * value2.M44;
			result.M31 = value1.M31 * value2.M11 + value1.M32 * value2.M21 + value1.M33 * value2.M31 + value1.M34 * value2.M41;
			result.M32 = value1.M31 * value2.M12 + value1.M32 * value2.M22 + value1.M33 * value2.M32 + value1.M34 * value2.M42;
			result.M33 = value1.M31 * value2.M13 + value1.M32 * value2.M23 + value1.M33 * value2.M33 + value1.M34 * value2.M43;
			result.M34 = value1.M31 * value2.M14 + value1.M32 * value2.M24 + value1.M33 * value2.M34 + value1.M34 * value2.M44;
			result.M41 = value1.M41 * value2.M11 + value1.M42 * value2.M21 + value1.M43 * value2.M31 + value1.M44 * value2.M41;
			result.M42 = value1.M41 * value2.M12 + value1.M42 * value2.M22 + value1.M43 * value2.M32 + value1.M44 * value2.M42;
			result.M43 = value1.M41 * value2.M13 + value1.M42 * value2.M23 + value1.M43 * value2.M33 + value1.M44 * value2.M43;
			result.M44 = value1.M41 * value2.M14 + value1.M42 * value2.M24 + value1.M43 * value2.M34 + value1.M44 * value2.M44;
			return result;
		}

		public static Matrix4x4 operator *(Matrix4x4 value1, float value2)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = value1.M11 * value2;
			result.M12 = value1.M12 * value2;
			result.M13 = value1.M13 * value2;
			result.M14 = value1.M14 * value2;
			result.M21 = value1.M21 * value2;
			result.M22 = value1.M22 * value2;
			result.M23 = value1.M23 * value2;
			result.M24 = value1.M24 * value2;
			result.M31 = value1.M31 * value2;
			result.M32 = value1.M32 * value2;
			result.M33 = value1.M33 * value2;
			result.M34 = value1.M34 * value2;
			result.M41 = value1.M41 * value2;
			result.M42 = value1.M42 * value2;
			result.M43 = value1.M43 * value2;
			result.M44 = value1.M44 * value2;
			return result;
		}

		public static bool operator ==(Matrix4x4 value1, Matrix4x4 value2)
		{
			if (value1.M11 == value2.M11 && value1.M22 == value2.M22 && value1.M33 == value2.M33 && value1.M44 == value2.M44 && value1.M12 == value2.M12 && value1.M13 == value2.M13 && value1.M14 == value2.M14 && value1.M21 == value2.M21 && value1.M23 == value2.M23 && value1.M24 == value2.M24 && value1.M31 == value2.M31 && value1.M32 == value2.M32 && value1.M34 == value2.M34 && value1.M41 == value2.M41 && value1.M42 == value2.M42)
			{
				return value1.M43 == value2.M43;
			}
			return false;
		}

		public static bool operator !=(Matrix4x4 value1, Matrix4x4 value2)
		{
			if (value1.M11 == value2.M11 && value1.M12 == value2.M12 && value1.M13 == value2.M13 && value1.M14 == value2.M14 && value1.M21 == value2.M21 && value1.M22 == value2.M22 && value1.M23 == value2.M23 && value1.M24 == value2.M24 && value1.M31 == value2.M31 && value1.M32 == value2.M32 && value1.M33 == value2.M33 && value1.M34 == value2.M34 && value1.M41 == value2.M41 && value1.M42 == value2.M42 && value1.M43 == value2.M43)
			{
				return value1.M44 != value2.M44;
			}
			return true;
		}

		public bool Equals(Matrix4x4 other)
		{
			if (M11 == other.M11 && M22 == other.M22 && M33 == other.M33 && M44 == other.M44 && M12 == other.M12 && M13 == other.M13 && M14 == other.M14 && M21 == other.M21 && M23 == other.M23 && M24 == other.M24 && M31 == other.M31 && M32 == other.M32 && M34 == other.M34 && M41 == other.M41 && M42 == other.M42)
			{
				return M43 == other.M43;
			}
			return false;
		}

		public override bool Equals(object obj)
		{
			if (obj is Matrix4x4)
			{
				return Equals((Matrix4x4)obj);
			}
			return false;
		}

		public override string ToString()
		{
			CultureInfo currentCulture = CultureInfo.CurrentCulture;
			return string.Format(currentCulture, "{{ {{M11:{0} M12:{1} M13:{2} M14:{3}}} {{M21:{4} M22:{5} M23:{6} M24:{7}}} {{M31:{8} M32:{9} M33:{10} M34:{11}}} {{M41:{12} M42:{13} M43:{14} M44:{15}}} }}", M11.ToString(currentCulture), M12.ToString(currentCulture), M13.ToString(currentCulture), M14.ToString(currentCulture), M21.ToString(currentCulture), M22.ToString(currentCulture), M23.ToString(currentCulture), M24.ToString(currentCulture), M31.ToString(currentCulture), M32.ToString(currentCulture), M33.ToString(currentCulture), M34.ToString(currentCulture), M41.ToString(currentCulture), M42.ToString(currentCulture), M43.ToString(currentCulture), M44.ToString(currentCulture));
		}

		public override int GetHashCode()
		{
			return M11.GetHashCode() + M12.GetHashCode() + M13.GetHashCode() + M14.GetHashCode() + M21.GetHashCode() + M22.GetHashCode() + M23.GetHashCode() + M24.GetHashCode() + M31.GetHashCode() + M32.GetHashCode() + M33.GetHashCode() + M34.GetHashCode() + M41.GetHashCode() + M42.GetHashCode() + M43.GetHashCode() + M44.GetHashCode();
		}
	}
	public struct Plane : IEquatable<Plane>
	{
		public Vector3 Normal;

		public float D;

		public Plane(float x, float y, float z, float d)
		{
			Normal = new Vector3(x, y, z);
			D = d;
		}

		public Plane(Vector3 normal, float d)
		{
			Normal = normal;
			D = d;
		}

		public Plane(Vector4 value)
		{
			Normal = new Vector3(value.X, value.Y, value.Z);
			D = value.W;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Plane CreateFromVertices(Vector3 point1, Vector3 point2, Vector3 point3)
		{
			if (Vector.IsHardwareAccelerated)
			{
				Vector3 vector = point2 - point1;
				Vector3 vector2 = point3 - point1;
				Vector3 value = Vector3.Cross(vector, vector2);
				Vector3 vector3 = Vector3.Normalize(value);
				float d = 0f - Vector3.Dot(vector3, point1);
				return new Plane(vector3, d);
			}
			float num = point2.X - point1.X;
			float num2 = point2.Y - point1.Y;
			float num3 = point2.Z - point1.Z;
			float num4 = point3.X - point1.X;
			float num5 = point3.Y - point1.Y;
			float num6 = point3.Z - point1.Z;
			float num7 = num2 * num6 - num3 * num5;
			float num8 = num3 * num4 - num * num6;
			float num9 = num * num5 - num2 * num4;
			float x = num7 * num7 + num8 * num8 + num9 * num9;
			float num10 = 1f / MathF.Sqrt(x);
			Vector3 normal = new Vector3(num7 * num10, num8 * num10, num9 * num10);
			return new Plane(normal, 0f - (normal.X * point1.X + normal.Y * point1.Y + normal.Z * point1.Z));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Plane Normalize(Plane value)
		{
			if (Vector.IsHardwareAccelerated)
			{
				float num = value.Normal.LengthSquared();
				if (MathF.Abs(num - 1f) < 1.1920929E-07f)
				{
					return value;
				}
				float num2 = MathF.Sqrt(num);
				return new Plane(value.Normal / num2, value.D / num2);
			}
			float num3 = value.Normal.X * value.Normal.X + value.Normal.Y * value.Normal.Y + value.Normal.Z * value.Normal.Z;
			if (MathF.Abs(num3 - 1f) < 1.1920929E-07f)
			{
				return value;
			}
			float num4 = 1f / MathF.Sqrt(num3);
			return new Plane(value.Normal.X * num4, value.Normal.Y * num4, value.Normal.Z * num4, value.D * num4);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Plane Transform(Plane plane, Matrix4x4 matrix)
		{
			Matrix4x4.Invert(matrix, out var result);
			float x = plane.Normal.X;
			float y = plane.Normal.Y;
			float z = plane.Normal.Z;
			float d = plane.D;
			return new Plane(x * result.M11 + y * result.M12 + z * result.M13 + d * result.M14, x * result.M21 + y * result.M22 + z * result.M23 + d * result.M24, x * result.M31 + y * result.M32 + z * result.M33 + d * result.M34, x * result.M41 + y * result.M42 + z * result.M43 + d * result.M44);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Plane Transform(Plane plane, Quaternion rotation)
		{
			float num = rotation.X + rotation.X;
			float num2 = rotation.Y + rotation.Y;
			float num3 = rotation.Z + rotation.Z;
			float num4 = rotation.W * num;
			float num5 = rotation.W * num2;
			float num6 = rotation.W * num3;
			float num7 = rotation.X * num;
			float num8 = rotation.X * num2;
			float num9 = rotation.X * num3;
			float num10 = rotation.Y * num2;
			float num11 = rotation.Y * num3;
			float num12 = rotation.Z * num3;
			float num13 = 1f - num10 - num12;
			float num14 = num8 - num6;
			float num15 = num9 + num5;
			float num16 = num8 + num6;
			float num17 = 1f - num7 - num12;
			float num18 = num11 - num4;
			float num19 = num9 - num5;
			float num20 = num11 + num4;
			float num21 = 1f - num7 - num10;
			float x = plane.Normal.X;
			float y = plane.Normal.Y;
			float z = plane.Normal.Z;
			return new Plane(x * num13 + y * num14 + z * num15, x * num16 + y * num17 + z * num18, x * num19 + y * num20 + z * num21, plane.D);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Dot(Plane plane, Vector4 value)
		{
			return plane.Normal.X * value.X + plane.Normal.Y * value.Y + plane.Normal.Z * value.Z + plane.D * value.W;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float DotCoordinate(Plane plane, Vector3 value)
		{
			if (Vector.IsHardwareAccelerated)
			{
				return Vector3.Dot(plane.Normal, value) + plane.D;
			}
			return plane.Normal.X * value.X + plane.Normal.Y * value.Y + plane.Normal.Z * value.Z + plane.D;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float DotNormal(Plane plane, Vector3 value)
		{
			if (Vector.IsHardwareAccelerated)
			{
				return Vector3.Dot(plane.Normal, value);
			}
			return plane.Normal.X * value.X + plane.Normal.Y * value.Y + plane.Normal.Z * value.Z;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool operator ==(Plane value1, Plane value2)
		{
			if (value1.Normal.X == value2.Normal.X && value1.Normal.Y == value2.Normal.Y && value1.Normal.Z == value2.Normal.Z)
			{
				return value1.D == value2.D;
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool operator !=(Plane value1, Plane value2)
		{
			if (value1.Normal.X == value2.Normal.X && value1.Normal.Y == value2.Normal.Y && value1.Normal.Z == value2.Normal.Z)
			{
				return value1.D != value2.D;
			}
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public bool Equals(Plane other)
		{
			if (Vector.IsHardwareAccelerated)
			{
				if (Normal.Equals(other.Normal))
				{
					return D == other.D;
				}
				return false;
			}
			if (Normal.X == other.Normal.X && Normal.Y == other.Normal.Y && Normal.Z == other.Normal.Z)
			{
				return D == other.D;
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public override bool Equals(object obj)
		{
			if (obj is Plane)
			{
				return Equals((Plane)obj);
			}
			return false;
		}

		public override string ToString()
		{
			CultureInfo currentCulture = CultureInfo.CurrentCulture;
			return string.Format(currentCulture, "{{Normal:{0} D:{1}}}", Normal.ToString(), D.ToString(currentCulture));
		}

		public override int GetHashCode()
		{
			return Normal.GetHashCode() + D.GetHashCode();
		}
	}
	public struct Quaternion : IEquatable<Quaternion>
	{
		public float X;

		public float Y;

		public float Z;

		public float W;

		public static Quaternion Identity => new Quaternion(0f, 0f, 0f, 1f);

		public bool IsIdentity
		{
			get
			{
				if (X == 0f && Y == 0f && Z == 0f)
				{
					return W == 1f;
				}
				return false;
			}
		}

		public Quaternion(float x, float y, float z, float w)
		{
			X = x;
			Y = y;
			Z = z;
			W = w;
		}

		public Quaternion(Vector3 vectorPart, float scalarPart)
		{
			X = vectorPart.X;
			Y = vectorPart.Y;
			Z = vectorPart.Z;
			W = scalarPart;
		}

		public float Length()
		{
			float x = X * X + Y * Y + Z * Z + W * W;
			return MathF.Sqrt(x);
		}

		public float LengthSquared()
		{
			return X * X + Y * Y + Z * Z + W * W;
		}

		public static Quaternion Normalize(Quaternion value)
		{
			float x = value.X * value.X + value.Y * value.Y + value.Z * value.Z + value.W * value.W;
			float num = 1f / MathF.Sqrt(x);
			Quaternion result = default(Quaternion);
			result.X = value.X * num;
			result.Y = value.Y * num;
			result.Z = value.Z * num;
			result.W = value.W * num;
			return result;
		}

		public static Quaternion Conjugate(Quaternion value)
		{
			Quaternion result = default(Quaternion);
			result.X = 0f - value.X;
			result.Y = 0f - value.Y;
			result.Z = 0f - value.Z;
			result.W = value.W;
			return result;
		}

		public static Quaternion Inverse(Quaternion value)
		{
			float num = value.X * value.X + value.Y * value.Y + value.Z * value.Z + value.W * value.W;
			float num2 = 1f / num;
			Quaternion result = default(Quaternion);
			result.X = (0f - value.X) * num2;
			result.Y = (0f - value.Y) * num2;
			result.Z = (0f - value.Z) * num2;
			result.W = value.W * num2;
			return result;
		}

		public static Quaternion CreateFromAxisAngle(Vector3 axis, float angle)
		{
			float x = angle * 0.5f;
			float num = MathF.Sin(x);
			float w = MathF.Cos(x);
			Quaternion result = default(Quaternion);
			result.X = axis.X * num;
			result.Y = axis.Y * num;
			result.Z = axis.Z * num;
			result.W = w;
			return result;
		}

		public static Quaternion CreateFromYawPitchRoll(float yaw, float pitch, float roll)
		{
			float x = roll * 0.5f;
			float num = MathF.Sin(x);
			float num2 = MathF.Cos(x);
			float x2 = pitch * 0.5f;
			float num3 = MathF.Sin(x2);
			float num4 = MathF.Cos(x2);
			float x3 = yaw * 0.5f;
			float num5 = MathF.Sin(x3);
			float num6 = MathF.Cos(x3);
			Quaternion result = default(Quaternion);
			result.X = num6 * num3 * num2 + num5 * num4 * num;
			result.Y = num5 * num4 * num2 - num6 * num3 * num;
			result.Z = num6 * num4 * num - num5 * num3 * num2;
			result.W = num6 * num4 * num2 + num5 * num3 * num;
			return result;
		}

		public static Quaternion CreateFromRotationMatrix(Matrix4x4 matrix)
		{
			float num = matrix.M11 + matrix.M22 + matrix.M33;
			Quaternion result = default(Quaternion);
			if (num > 0f)
			{
				float num2 = MathF.Sqrt(num + 1f);
				result.W = num2 * 0.5f;
				num2 = 0.5f / num2;
				result.X = (matrix.M23 - matrix.M32) * num2;
				result.Y = (matrix.M31 - matrix.M13) * num2;
				result.Z = (matrix.M12 - matrix.M21) * num2;
			}
			else if (matrix.M11 >= matrix.M22 && matrix.M11 >= matrix.M33)
			{
				float num3 = MathF.Sqrt(1f + matrix.M11 - matrix.M22 - matrix.M33);
				float num4 = 0.5f / num3;
				result.X = 0.5f * num3;
				result.Y = (matrix.M12 + matrix.M21) * num4;
				result.Z = (matrix.M13 + matrix.M31) * num4;
				result.W = (matrix.M23 - matrix.M32) * num4;
			}
			else if (matrix.M22 > matrix.M33)
			{
				float num5 = MathF.Sqrt(1f + matrix.M22 - matrix.M11 - matrix.M33);
				float num6 = 0.5f / num5;
				result.X = (matrix.M21 + matrix.M12) * num6;
				result.Y = 0.5f * num5;
				result.Z = (matrix.M32 + matrix.M23) * num6;
				result.W = (matrix.M31 - matrix.M13) * num6;
			}
			else
			{
				float num7 = MathF.Sqrt(1f + matrix.M33 - matrix.M11 - matrix.M22);
				float num8 = 0.5f / num7;
				result.X = (matrix.M31 + matrix.M13) * num8;
				result.Y = (matrix.M32 + matrix.M23) * num8;
				result.Z = 0.5f * num7;
				result.W = (matrix.M12 - matrix.M21) * num8;
			}
			return result;
		}

		public static float Dot(Quaternion quaternion1, Quaternion quaternion2)
		{
			return quaternion1.X * quaternion2.X + quaternion1.Y * quaternion2.Y + quaternion1.Z * quaternion2.Z + quaternion1.W * quaternion2.W;
		}

		public static Quaternion Slerp(Quaternion quaternion1, Quaternion quaternion2, float amount)
		{
			float num = quaternion1.X * quaternion2.X + quaternion1.Y * quaternion2.Y + quaternion1.Z * quaternion2.Z + quaternion1.W * quaternion2.W;
			bool flag = false;
			if (num < 0f)
			{
				flag = true;
				num = 0f - num;
			}
			float num2;
			float num3;
			if (num > 0.999999f)
			{
				num2 = 1f - amount;
				num3 = (flag ? (0f - amount) : amount);
			}
			else
			{
				float num4 = MathF.Acos(num);
				float num5 = 1f / MathF.Sin(num4);
				num2 = MathF.Sin((1f - amount) * num4) * num5;
				num3 = (flag ? ((0f - MathF.Sin(amount * num4)) * num5) : (MathF.Sin(amount * num4) * num5));
			}
			Quaternion result = default(Quaternion);
			result.X = num2 * quaternion1.X + num3 * quaternion2.X;
			result.Y = num2 * quaternion1.Y + num3 * quaternion2.Y;
			result.Z = num2 * quaternion1.Z + num3 * quaternion2.Z;
			result.W = num2 * quaternion1.W + num3 * quaternion2.W;
			return result;
		}

		public static Quaternion Lerp(Quaternion quaternion1, Quaternion quaternion2, float amount)
		{
			float num = 1f - amount;
			Quaternion result = default(Quaternion);
			float num2 = quaternion1.X * quaternion2.X + quaternion1.Y * quaternion2.Y + quaternion1.Z * quaternion2.Z + quaternion1.W * quaternion2.W;
			if (num2 >= 0f)
			{
				result.X = num * quaternion1.X + amount * quaternion2.X;
				result.Y = num * quaternion1.Y + amount * quaternion2.Y;
				result.Z = num * quaternion1.Z + amount * quaternion2.Z;
				result.W = num * quaternion1.W + amount * quaternion2.W;
			}
			else
			{
				result.X = num * quaternion1.X - amount * quaternion2.X;
				result.Y = num * quaternion1.Y - amount * quaternion2.Y;
				result.Z = num * quaternion1.Z - amount * quaternion2.Z;
				result.W = num * quaternion1.W - amount * quaternion2.W;
			}
			float x = result.X * result.X + result.Y * result.Y + result.Z * result.Z + result.W * result.W;
			float num3 = 1f / MathF.Sqrt(x);
			result.X *= num3;
			result.Y *= num3;
			result.Z *= num3;
			result.W *= num3;
			return result;
		}

		public static Quaternion Concatenate(Quaternion value1, Quaternion value2)
		{
			float x = value2.X;
			float y = value2.Y;
			float z = value2.Z;
			float w = value2.W;
			float x2 = value1.X;
			float y2 = value1.Y;
			float z2 = value1.Z;
			float w2 = value1.W;
			float num = y * z2 - z * y2;
			float num2 = z * x2 - x * z2;
			float num3 = x * y2 - y * x2;
			float num4 = x * x2 + y * y2 + z * z2;
			Quaternion result = default(Quaternion);
			result.X = x * w2 + x2 * w + num;
			result.Y = y * w2 + y2 * w + num2;
			result.Z = z * w2 + z2 * w + num3;
			result.W = w * w2 - num4;
			return result;
		}

		public static Quaternion Negate(Quaternion value)
		{
			Quaternion result = default(Quaternion);
			result.X = 0f - value.X;
			result.Y = 0f - value.Y;
			result.Z = 0f - value.Z;
			result.W = 0f - value.W;
			return result;
		}

		public static Quaternion Add(Quaternion value1, Quaternion value2)
		{
			Quaternion result = default(Quaternion);
			result.X = value1.X + value2.X;
			result.Y = value1.Y + value2.Y;
			result.Z = value1.Z + value2.Z;
			result.W = value1.W + value2.W;
			return result;
		}

		public static Quaternion Subtract(Quaternion value1, Quaternion value2)
		{
			Quaternion result = default(Quaternion);
			result.X = value1.X - value2.X;
			result.Y = value1.Y - value2.Y;
			result.Z = value1.Z - value2.Z;
			result.W = value1.W - value2.W;
			return result;
		}

		public static Quaternion Multiply(Quaternion value1, Quaternion value2)
		{
			float x = value1.X;
			float y = value1.Y;
			float z = value1.Z;
			float w = value1.W;
			float x2 = value2.X;
			float y2 = value2.Y;
			float z2 = value2.Z;
			float w2 = value2.W;
			float num = y * z2 - z * y2;
			float num2 = z * x2 - x * z2;
			float num3 = x * y2 - y * x2;
			float num4 = x * x2 + y * y2 + z * z2;
			Quaternion result = default(Quaternion);
			result.X = x * w2 + x2 * w + num;
			result.Y = y * w2 + y2 * w + num2;
			result.Z = z * w2 + z2 * w + num3;
			result.W = w * w2 - num4;
			return result;
		}

		public static Quaternion Multiply(Quaternion value1, float value2)
		{
			Quaternion result = default(Quaternion);
			result.X = value1.X * value2;
			result.Y = value1.Y * value2;
			result.Z = value1.Z * value2;
			result.W = value1.W * value2;
			return result;
		}

		public static Quaternion Divide(Quaternion value1, Quaternion value2)
		{
			float x = value1.X;
			float y = value1.Y;
			float z = value1.Z;
			float w = value1.W;
			float num = value2.X * value2.X + value2.Y * value2.Y + value2.Z * value2.Z + value2.W * value2.W;
			float num2 = 1f / num;
			float num3 = (0f - value2.X) * num2;
			float num4 = (0f - value2.Y) * num2;
			float num5 = (0f - value2.Z) * num2;
			float num6 = value2.W * num2;
			float num7 = y * num5 - z * num4;
			float num8 = z * num3 - x * num5;
			float num9 = x * num4 - y * num3;
			float num10 = x * num3 + y * num4 + z * num5;
			Quaternion result = default(Quaternion);
			result.X = x * num6 + num3 * w + num7;
			result.Y = y * num6 + num4 * w + num8;
			result.Z = z * num6 + num5 * w + num9;
			result.W = w * num6 - num10;
			return result;
		}

		public static Quaternion operator -(Quaternion value)
		{
			Quaternion result = default(Quaternion);
			result.X = 0f - value.X;
			result.Y = 0f - value.Y;
			result.Z = 0f - value.Z;
			result.W = 0f - value.W;
			return result;
		}

		public static Quaternion operator +(Quaternion value1, Quaternion value2)
		{
			Quaternion result = default(Quaternion);
			result.X = value1.X + value2.X;
			result.Y = value1.Y + value2.Y;
			result.Z = value1.Z + value2.Z;
			result.W = value1.W + value2.W;
			return result;
		}

		public static Quaternion operator -(Quaternion value1, Quaternion value2)
		{
			Quaternion result = default(Quaternion);
			result.X = value1.X - value2.X;
			result.Y = value1.Y - value2.Y;
			result.Z = value1.Z - value2.Z;
			result.W = value1.W - value2.W;
			return result;
		}

		public static Quaternion operator *(Quaternion value1, Quaternion value2)
		{
			float x = value1.X;
			float y = value1.Y;
			float z = value1.Z;
			float w = value1.W;
			float x2 = value2.X;
			float y2 = value2.Y;
			float z2 = value2.Z;
			float w2 = value2.W;
			float num = y * z2 - z * y2;
			float num2 = z * x2 - x * z2;
			float num3 = x * y2 - y * x2;
			float num4 = x * x2 + y * y2 + z * z2;
			Quaternion result = default(Quaternion);
			result.X = x * w2 + x2 * w + num;
			result.Y = y * w2 + y2 * w + num2;
			result.Z = z * w2 + z2 * w + num3;
			result.W = w * w2 - num4;
			return result;
		}

		public static Quaternion operator *(Quaternion value1, float value2)
		{
			Quaternion result = default(Quaternion);
			result.X = value1.X * value2;
			result.Y = value1.Y * value2;
			result.Z = value1.Z * value2;
			result.W = value1.W * value2;
			return result;
		}

		public static Quaternion operator /(Quaternion value1, Quaternion value2)
		{
			float x = value1.X;
			float y = value1.Y;
			float z = value1.Z;
			float w = value1.W;
			float num = value2.X * value2.X + value2.Y * value2.Y + value2.Z * value2.Z + value2.W * value2.W;
			float num2 = 1f / num;
			float num3 = (0f - value2.X) * num2;
			float num4 = (0f - value2.Y) * num2;
			float num5 = (0f - value2.Z) * num2;
			float num6 = value2.W * num2;
			float num7 = y * num5 - z * num4;
			float num8 = z * num3 - x * num5;
			float num9 = x * num4 - y * num3;
			float num10 = x * num3 + y * num4 + z * num5;
			Quaternion result = default(Quaternion);
			result.X = x * num6 + num3 * w + num7;
			result.Y = y * num6 + num4 * w + num8;
			result.Z = z * num6 + num5 * w + num9;
			result.W = w * num6 - num10;
			return result;
		}

		public static bool operator ==(Quaternion value1, Quaternion value2)
		{
			if (value1.X == value2.X && value1.Y == value2.Y && value1.Z == value2.Z)
			{
				return value1.W == value2.W;
			}
			return false;
		}

		public static bool operator !=(Quaternion value1, Quaternion value2)
		{
			if (value1.X == value2.X && value1.Y == value2.Y && value1.Z == value2.Z)
			{
				return value1.W != value2.W;
			}
			return true;
		}

		public bool Equals(Quaternion other)
		{
			if (X == other.X && Y == other.Y && Z == other.Z)
			{
				return W == other.W;
			}
			return false;
		}

		public override bool Equals(object obj)
		{
			if (obj is Quaternion)
			{
				return Equals((Quaternion)obj);
			}
			return false;
		}

		public override string ToString()
		{
			CultureInfo currentCulture = CultureInfo.CurrentCulture;
			return string.Format(currentCulture, "{{X:{0} Y:{1} Z:{2} W:{3}}}", X.ToString(currentCulture), Y.ToString(currentCulture), Z.ToString(currentCulture), W.ToString(currentCulture));
		}

		public override int GetHashCode()
		{
			return X.GetHashCode() + Y.GetHashCode() + Z.GetHashCode() + W.GetHashCode();
		}
	}
	[StructLayout(LayoutKind.Explicit)]
	internal struct Register
	{
		[FieldOffset(0)]
		internal byte byte_0;

		[FieldOffset(1)]
		internal byte byte_1;

		[FieldOffset(2)]
		internal byte byte_2;

		[FieldOffset(3)]
		internal byte byte_3;

		[FieldOffset(4)]
		internal byte byte_4;

		[FieldOffset(5)]
		internal byte byte_5;

		[FieldOffset(6)]
		internal byte byte_6;

		[FieldOffset(7)]
		internal byte byte_7;

		[FieldOffset(8)]
		internal byte byte_8;

		[FieldOffset(9)]
		internal byte byte_9;

		[FieldOffset(10)]
		internal byte byte_10;

		[FieldOffset(11)]
		internal byte byte_11;

		[FieldOffset(12)]
		internal byte byte_12;

		[FieldOffset(13)]
		internal byte byte_13;

		[FieldOffset(14)]
		internal byte byte_14;

		[FieldOffset(15)]
		internal byte byte_15;

		[FieldOffset(0)]
		internal sbyte sbyte_0;

		[FieldOffset(1)]
		internal sbyte sbyte_1;

		[FieldOffset(2)]
		internal sbyte sbyte_2;

		[FieldOffset(3)]
		internal sbyte sbyte_3;

		[FieldOffset(4)]
		internal sbyte sbyte_4;

		[FieldOffset(5)]
		internal sbyte sbyte_5;

		[FieldOffset(6)]
		internal sbyte sbyte_6;

		[FieldOffset(7)]
		internal sbyte sbyte_7;

		[FieldOffset(8)]
		internal sbyte sbyte_8;

		[FieldOffset(9)]
		internal sbyte sbyte_9;

		[FieldOffset(10)]
		internal sbyte sbyte_10;

		[FieldOffset(11)]
		internal sbyte sbyte_11;

		[FieldOffset(12)]
		internal sbyte sbyte_12;

		[FieldOffset(13)]
		internal sbyte sbyte_13;

		[FieldOffset(14)]
		internal sbyte sbyte_14;

		[FieldOffset(15)]
		internal sbyte sbyte_15;

		[FieldOffset(0)]
		internal ushort uint16_0;

		[FieldOffset(2)]
		internal ushort uint16_1;

		[FieldOffset(4)]
		internal ushort uint16_2;

		[FieldOffset(6)]
		internal ushort uint16_3;

		[FieldOffset(8)]
		internal ushort uint16_4;

		[FieldOffset(10)]
		internal ushort uint16_5;

		[FieldOffset(12)]
		internal ushort uint16_6;

		[FieldOffset(14)]
		internal ushort uint16_7;

		[FieldOffset(0)]
		internal short int16_0;

		[FieldOffset(2)]
		internal short int16_1;

		[FieldOffset(4)]
		internal short int16_2;

		[FieldOffset(6)]
		internal short int16_3;

		[FieldOffset(8)]
		internal short int16_4;

		[FieldOffset(10)]
		internal short int16_5;

		[FieldOffset(12)]
		internal short int16_6;

		[FieldOffset(14)]
		internal short int16_7;

		[FieldOffset(0)]
		internal uint uint32_0;

		[FieldOffset(4)]
		internal uint uint32_1;

		[FieldOffset(8)]
		internal uint uint32_2;

		[FieldOffset(12)]
		internal uint uint32_3;

		[FieldOffset(0)]
		internal int int32_0;

		[FieldOffset(4)]
		internal int int32_1;

		[FieldOffset(8)]
		internal int int32_2;

		[FieldOffset(12)]
		internal int int32_3;

		[FieldOffset(0)]
		internal ulong uint64_0;

		[FieldOffset(8)]
		internal ulong uint64_1;

		[FieldOffset(0)]
		internal long int64_0;

		[FieldOffset(8)]
		internal long int64_1;

		[FieldOffset(0)]
		internal float single_0;

		[FieldOffset(4)]
		internal float single_1;

		[FieldOffset(8)]
		internal float single_2;

		[FieldOffset(12)]
		internal float single_3;

		[FieldOffset(0)]
		internal double double_0;

		[FieldOffset(8)]
		internal double double_1;
	}
	[System.Runtime.CompilerServices.Intrinsic]
	public struct Vector<T> : IEquatable<Vector<T>>, IFormattable where T : struct
	{
		private struct VectorSizeHelper
		{
			internal Vector<T> _placeholder;

			internal byte _byte;
		}

		private System.Numerics.Register register;

		private static readonly int s_count = InitializeCount();

		private static readonly Vector<T> s_zero = default(Vector<T>);

		private static readonly Vector<T> s_one = new Vector<T>(GetOneValue());

		private static readonly Vector<T> s_allOnes = new Vector<T>(GetAllBitsSetValue());

		public static int Count
		{
			[System.Runtime.CompilerServices.Intrinsic]
			get
			{
				return s_count;
			}
		}

		public static Vector<T> Zero
		{
			[System.Runtime.CompilerServices.Intrinsic]
			get
			{
				return s_zero;
			}
		}

		public static Vector<T> One
		{
			[System.Runtime.CompilerServices.Intrinsic]
			get
			{
				return s_one;
			}
		}

		internal static Vector<T> AllOnes => s_allOnes;

		public unsafe T this[int index]
		{
			[System.Runtime.CompilerServices.Intrinsic]
			get
			{
				if (index >= Count || index < 0)
				{
					throw new IndexOutOfRangeException(System.SR.Format(System.SR.Arg_ArgumentOutOfRangeException, index));
				}
				if (typeof(T) == typeof(byte))
				{
					fixed (byte* ptr = &register.byte_0)
					{
						return (T)(object)ptr[index];
					}
				}
				if (typeof(T) == typeof(sbyte))
				{
					fixed (sbyte* ptr2 = &register.sbyte_0)
					{
						return (T)(object)ptr2[index];
					}
				}
				if (typeof(T) == typeof(ushort))
				{
					fixed (ushort* ptr3 = &register.uint16_0)
					{
						return (T)(object)ptr3[index];
					}
				}
				if (typeof(T) == typeof(short))
				{
					fixed (short* ptr4 = &register.int16_0)
					{
						return (T)(object)ptr4[index];
					}
				}
				if (typeof(T) == typeof(uint))
				{
					fixed (uint* ptr5 = &register.uint32_0)
					{
						return (T)(object)ptr5[index];
					}
				}
				if (typeof(T) == typeof(int))
				{
					fixed (int* ptr6 = &register.int32_0)
					{
						return (T)(object)ptr6[index];
					}
				}
				if (typeof(T) == typeof(ulong))
				{
					fixed (ulong* ptr7 = &register.uint64_0)
					{
						return (T)(object)ptr7[index];
					}
				}
				if (typeof(T) == typeof(long))
				{
					fixed (long* ptr8 = &register.int64_0)
					{
						return (T)(object)ptr8[index];
					}
				}
				if (typeof(T) == typeof(float))
				{
					fixed (float* ptr9 = &register.single_0)
					{
						return (T)(object)ptr9[index];
					}
				}
				if (typeof(T) == typeof(double))
				{
					fixed (double* ptr10 = &register.double_0)
					{
						return (T)(object)ptr10[index];
					}
				}
				throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
			}
		}

		private unsafe static int InitializeCount()
		{
			VectorSizeHelper vectorSizeHelper = default(VectorSizeHelper);
			byte* ptr = &vectorSizeHelper._placeholder.register.byte_0;
			byte* ptr2 = &vectorSizeHelper._byte;
			int num = (int)(ptr2 - ptr);
			int num2 = -1;
			if (typeof(T) == typeof(byte))
			{
				num2 = 1;
			}
			else if (typeof(T) == typeof(sbyte))
			{
				num2 = 1;
			}
			else if (typeof(T) == typeof(ushort))
			{
				num2 = 2;
			}
			else if (typeof(T) == typeof(short))
			{
				num2 = 2;
			}
			else if (typeof(T) == typeof(uint))
			{
				num2 = 4;
			}
			else if (typeof(T) == typeof(int))
			{
				num2 = 4;
			}
			else if (typeof(T) == typeof(ulong))
			{
				num2 = 8;
			}
			else if (typeof(T) == typeof(long))
			{
				num2 = 8;
			}
			else if (typeof(T) == typeof(float))
			{
				num2 = 4;
			}
			else
			{
				if (!(typeof(T) == typeof(double)))
				{
					throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
				}
				num2 = 8;
			}
			return num / num2;
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public unsafe Vector(T value)
		{
			this = default(Vector<T>);
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					fixed (byte* ptr = &register.byte_0)
					{
						for (int i = 0; i < Count; i++)
						{
							ptr[i] = (byte)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(sbyte))
				{
					fixed (sbyte* ptr2 = &register.sbyte_0)
					{
						for (int j = 0; j < Count; j++)
						{
							ptr2[j] = (sbyte)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(ushort))
				{
					fixed (ushort* ptr3 = &register.uint16_0)
					{
						for (int k = 0; k < Count; k++)
						{
							ptr3[k] = (ushort)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(short))
				{
					fixed (short* ptr4 = &register.int16_0)
					{
						for (int l = 0; l < Count; l++)
						{
							ptr4[l] = (short)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(uint))
				{
					fixed (uint* ptr5 = &register.uint32_0)
					{
						for (int m = 0; m < Count; m++)
						{
							ptr5[m] = (uint)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(int))
				{
					fixed (int* ptr6 = &register.int32_0)
					{
						for (int n = 0; n < Count; n++)
						{
							ptr6[n] = (int)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(ulong))
				{
					fixed (ulong* ptr7 = &register.uint64_0)
					{
						for (int num = 0; num < Count; num++)
						{
							ptr7[num] = (ulong)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(long))
				{
					fixed (long* ptr8 = &register.int64_0)
					{
						for (int num2 = 0; num2 < Count; num2++)
						{
							ptr8[num2] = (long)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(float))
				{
					fixed (float* ptr9 = &register.single_0)
					{
						for (int num3 = 0; num3 < Count; num3++)
						{
							ptr9[num3] = (float)(object)value;
						}
					}
				}
				else
				{
					if (!(typeof(T) == typeof(double)))
					{
						return;
					}
					fixed (double* ptr10 = &register.double_0)
					{
						for (int num4 = 0; num4 < Count; num4++)
						{
							ptr10[num4] = (double)(object)value;
						}
					}
				}
			}
			else if (typeof(T) == typeof(byte))
			{
				register.byte_0 = (byte)(object)value;
				register.byte_1 = (byte)(object)value;
				register.byte_2 = (byte)(object)value;
				register.byte_3 = (byte)(object)value;
				register.byte_4 = (byte)(object)value;
				register.byte_5 = (byte)(object)value;
				register.byte_6 = (byte)(object)value;
				register.byte_7 = (byte)(object)value;
				register.byte_8 = (byte)(object)value;
				register.byte_9 = (byte)(object)value;
				register.byte_10 = (byte)(object)value;
				register.byte_11 = (byte)(object)value;
				register.byte_12 = (byte)(object)value;
				register.byte_13 = (byte)(object)value;
				register.byte_14 = (byte)(object)value;
				register.byte_15 = (byte)(object)value;
			}
			else if (typeof(T) == typeof(sbyte))
			{
				register.sbyte_0 = (sbyte)(object)value;
				register.sbyte_1 = (sbyte)(object)value;
				register.sbyte_2 = (sbyte)(object)value;
				register.sbyte_3 = (sbyte)(object)value;
				register.sbyte_4 = (sbyte)(object)value;
				register.sbyte_5 = (sbyte)(object)value;
				register.sbyte_6 = (sbyte)(object)value;
				register.sbyte_7 = (sbyte)(object)value;
				register.sbyte_8 = (sbyte)(object)value;
				register.sbyte_9 = (sbyte)(object)value;
				register.sbyte_10 = (sbyte)(object)value;
				register.sbyte_11 = (sbyte)(object)value;
				register.sbyte_12 = (sbyte)(object)value;
				register.sbyte_13 = (sbyte)(object)value;
				register.sbyte_14 = (sbyte)(object)value;
				register.sbyte_15 = (sbyte)(object)value;
			}
			else if (typeof(T) == typeof(ushort))
			{
				register.uint16_0 = (ushort)(object)value;
				register.uint16_1 = (ushort)(object)value;
				register.uint16_2 = (ushort)(object)value;
				register.uint16_3 = (ushort)(object)value;
				register.uint16_4 = (ushort)(object)value;
				register.uint16_5 = (ushort)(object)value;
				register.uint16_6 = (ushort)(object)value;
				register.uint16_7 = (ushort)(object)value;
			}
			else if (typeof(T) == typeof(short))
			{
				register.int16_0 = (short)(object)value;
				register.int16_1 = (short)(object)value;
				register.int16_2 = (short)(object)value;
				register.int16_3 = (short)(object)value;
				register.int16_4 = (short)(object)value;
				register.int16_5 = (short)(object)value;
				register.int16_6 = (short)(object)value;
				register.int16_7 = (short)(object)value;
			}
			else if (typeof(T) == typeof(uint))
			{
				register.uint32_0 = (uint)(object)value;
				register.uint32_1 = (uint)(object)value;
				register.uint32_2 = (uint)(object)value;
				register.uint32_3 = (uint)(object)value;
			}
			else if (typeof(T) == typeof(int))
			{
				register.int32_0 = (int)(object)value;
				register.int32_1 = (int)(object)value;
				register.int32_2 = (int)(object)value;
				register.int32_3 = (int)(object)value;
			}
			else if (typeof(T) == typeof(ulong))
			{
				register.uint64_0 = (ulong)(object)value;
				register.uint64_1 = (ulong)(object)value;
			}
			else if (typeof(T) == typeof(long))
			{
				register.int64_0 = (long)(object)value;
				register.int64_1 = (long)(object)value;
			}
			else if (typeof(T) == typeof(float))
			{
				register.single_0 = (float)(object)value;
				register.single_1 = (float)(object)value;
				register.single_2 = (float)(object)value;
				register.single_3 = (float)(object)value;
			}
			else if (typeof(T) == typeof(double))
			{
				register.double_0 = (double)(object)value;
				register.double_1 = (double)(object)value;
			}
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public Vector(T[] values)
			: this(values, 0)
		{
		}

		public unsafe Vector(T[] values, int index)
		{
			this = default(Vector<T>);
			if (values == null)
			{
				throw new NullReferenceException(System.SR.Arg_NullArgumentNullRef);
			}
			if (index < 0 || values.Length - index < Count)
			{
				throw new IndexOutOfRangeException(System.SR.Format(System.SR.Arg_InsufficientNumberOfElements, Count, "values"));
			}
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					fixed (byte* ptr = &register.byte_0)
					{
						for (int i = 0; i < Count; i++)
						{
							ptr[i] = (byte)(object)values[i + index];
						}
					}
				}
				else if (typeof(T) == typeof(sbyte))
				{
					fixed (sbyte* ptr2 = &register.sbyte_0)
					{
						for (int j = 0; j < Count; j++)
						{
							ptr2[j] = (sbyte)(object)values[j + index];
						}
					}
				}
				else if (typeof(T) == typeof(ushort))
				{
					fixed (ushort* ptr3 = &register.uint16_0)
					{
						for (int k = 0; k < Count; k++)
						{
							ptr3[k] = (ushort)(object)values[k + index];
						}
					}
				}
				else if (typeof(T) == typeof(short))
				{
					fixed (short* ptr4 = &register.int16_0)
					{
						for (int l = 0; l < Count; l++)
						{
							ptr4[l] = (short)(object)values[l + index];
						}
					}
				}
				else if (typeof(T) == typeof(uint))
				{
					fixed (uint* ptr5 = &register.uint32_0)
					{
						for (int m = 0; m < Count; m++)
						{
							ptr5[m] = (uint)(object)values[m + index];
						}
					}
				}
				else if (typeof(T) == typeof(int))
				{
					fixed (int* ptr6 = &register.int32_0)
					{
						for (int n = 0; n < Count; n++)
						{
							ptr6[n] = (int)(object)values[n + index];
						}
					}
				}
				else if (typeof(T) == typeof(ulong))
				{
					fixed (ulong* ptr7 = &register.uint64_0)
					{
						for (int num = 0; num < Count; num++)
						{
							ptr7[num] = (ulong)(object)values

Mods/RealRadio/System.Reactive.dll

Decompiled a day ago
#define TRACE
using System;
using System.CodeDom.Compiler;
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.Reactive;
using System.Reactive.Concurrency;
using System.Reactive.Disposables;
using System.Reactive.Joins;
using System.Reactive.Linq;
using System.Reactive.Linq.ObservableImpl;
using System.Reactive.PlatformServices;
using System.Reactive.Subjects;
using System.Reactive.Threading.Tasks;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyFileVersion("6.0.0.1")]
[assembly: AssemblyInformationalVersion("6.0.0.1+e29c7a50db")]
[assembly: InternalsVisibleTo("Tests.System.Reactive, PublicKey=00240000048000009400000006020000002400005253413100040000010001008f5cff058631087031f8350f30a36fa078027e5df2316b564352dc9eb7af7ce856016d3c5e9d058036fe73bb5c83987bd3fc0793fbe25d633cc4f37c2bd5f1d717cd2a81661bec08f0971dc6078e17bde372b89005e7738a0ebd501b896ca3e8315270ff64df7809dd912c372df61785a5085b3553b7872e39b1b1cc0ff5a6bc")]
[assembly: InternalsVisibleTo("Tests.System.Reactive.Uwp.DeviceRunner, PublicKey=00240000048000009400000006020000002400005253413100040000010001008f5cff058631087031f8350f30a36fa078027e5df2316b564352dc9eb7af7ce856016d3c5e9d058036fe73bb5c83987bd3fc0793fbe25d633cc4f37c2bd5f1d717cd2a81661bec08f0971dc6078e17bde372b89005e7738a0ebd501b896ca3e8315270ff64df7809dd912c372df61785a5085b3553b7872e39b1b1cc0ff5a6bc")]
[assembly: ComVisible(false)]
[assembly: CLSCompliant(true)]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyMetadata("CommitHash", "e29c7a50db88513a87651c366088da8b7f40b1f0")]
[assembly: AssemblyCompany(".NET Foundation and Contributors")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) .NET Foundation and Contributors.")]
[assembly: AssemblyDescription("Reactive Extensions (Rx) for .NET")]
[assembly: AssemblyProduct("System.Reactive (netstandard2.0)")]
[assembly: AssemblyTitle("System.Reactive")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/dotnet/reactive")]
[assembly: AssemblyVersion("6.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]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[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;
		}
	}
}
[GeneratedCode("Nerdbank.GitVersioning.Tasks", "3.6.128.36433")]
[ExcludeFromCodeCoverage]
internal static class ThisAssembly
{
	internal const string AssemblyConfiguration = "Release";

	internal const string AssemblyFileVersion = "6.0.0.1";

	internal const string AssemblyInformationalVersion = "6.0.0.1+e29c7a50db";

	internal const string AssemblyName = "System.Reactive";

	internal const string AssemblyTitle = "System.Reactive";

	internal const string AssemblyVersion = "6.0.0.0";

	internal static readonly DateTime GitCommitDate = new DateTime(638200702660000000L, DateTimeKind.Utc);

	internal const string GitCommitId = "e29c7a50db88513a87651c366088da8b7f40b1f0";

	internal const bool IsPrerelease = false;

	internal const bool IsPublicRelease = true;

	internal const string PublicKey = "00240000048000009400000006020000002400005253413100040000010001008f5cff058631087031f8350f30a36fa078027e5df2316b564352dc9eb7af7ce856016d3c5e9d058036fe73bb5c83987bd3fc0793fbe25d633cc4f37c2bd5f1d717cd2a81661bec08f0971dc6078e17bde372b89005e7738a0ebd501b896ca3e8315270ff64df7809dd912c372df61785a5085b3553b7872e39b1b1cc0ff5a6bc";

	internal const string PublicKeyToken = "94bc3704cddfc263";

	internal const string RootNamespace = "System.Reactive";
}
namespace System
{
	public static class ObservableExtensions
	{
		public static IDisposable Subscribe<T>(this IObservable<T> source)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			return source.Subscribe(new AnonymousObserver<T>(Stubs<T>.Ignore, Stubs.Throw, Stubs.Nop));
		}

		public static IDisposable Subscribe<T>(this IObservable<T> source, Action<T> onNext)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (onNext == null)
			{
				throw new ArgumentNullException("onNext");
			}
			return source.Subscribe(new AnonymousObserver<T>(onNext, Stubs.Throw, Stubs.Nop));
		}

		public static IDisposable Subscribe<T>(this IObservable<T> source, Action<T> onNext, Action<Exception> onError)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (onNext == null)
			{
				throw new ArgumentNullException("onNext");
			}
			if (onError == null)
			{
				throw new ArgumentNullException("onError");
			}
			return source.Subscribe(new AnonymousObserver<T>(onNext, onError, Stubs.Nop));
		}

		public static IDisposable Subscribe<T>(this IObservable<T> source, Action<T> onNext, Action onCompleted)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (onNext == null)
			{
				throw new ArgumentNullException("onNext");
			}
			if (onCompleted == null)
			{
				throw new ArgumentNullException("onCompleted");
			}
			return source.Subscribe(new AnonymousObserver<T>(onNext, Stubs.Throw, onCompleted));
		}

		public static IDisposable Subscribe<T>(this IObservable<T> source, Action<T> onNext, Action<Exception> onError, Action onCompleted)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (onNext == null)
			{
				throw new ArgumentNullException("onNext");
			}
			if (onError == null)
			{
				throw new ArgumentNullException("onError");
			}
			if (onCompleted == null)
			{
				throw new ArgumentNullException("onCompleted");
			}
			return source.Subscribe(new AnonymousObserver<T>(onNext, onError, onCompleted));
		}

		public static void Subscribe<T>(this IObservable<T> source, IObserver<T> observer, CancellationToken token)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (observer == null)
			{
				throw new ArgumentNullException("observer");
			}
			source.Subscribe_(observer, token);
		}

		public static void Subscribe<T>(this IObservable<T> source, CancellationToken token)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			source.Subscribe_(new AnonymousObserver<T>(Stubs<T>.Ignore, Stubs.Throw, Stubs.Nop), token);
		}

		public static void Subscribe<T>(this IObservable<T> source, Action<T> onNext, CancellationToken token)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (onNext == null)
			{
				throw new ArgumentNullException("onNext");
			}
			source.Subscribe_(new AnonymousObserver<T>(onNext, Stubs.Throw, Stubs.Nop), token);
		}

		public static void Subscribe<T>(this IObservable<T> source, Action<T> onNext, Action<Exception> onError, CancellationToken token)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (onNext == null)
			{
				throw new ArgumentNullException("onNext");
			}
			if (onError == null)
			{
				throw new ArgumentNullException("onError");
			}
			source.Subscribe_(new AnonymousObserver<T>(onNext, onError, Stubs.Nop), token);
		}

		public static void Subscribe<T>(this IObservable<T> source, Action<T> onNext, Action onCompleted, CancellationToken token)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (onNext == null)
			{
				throw new ArgumentNullException("onNext");
			}
			if (onCompleted == null)
			{
				throw new ArgumentNullException("onCompleted");
			}
			source.Subscribe_(new AnonymousObserver<T>(onNext, Stubs.Throw, onCompleted), token);
		}

		public static void Subscribe<T>(this IObservable<T> source, Action<T> onNext, Action<Exception> onError, Action onCompleted, CancellationToken token)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (onNext == null)
			{
				throw new ArgumentNullException("onNext");
			}
			if (onError == null)
			{
				throw new ArgumentNullException("onError");
			}
			if (onCompleted == null)
			{
				throw new ArgumentNullException("onCompleted");
			}
			source.Subscribe_(new AnonymousObserver<T>(onNext, onError, onCompleted), token);
		}

		private static void Subscribe_<T>(this IObservable<T> source, IObserver<T> observer, CancellationToken token)
		{
			if (token.CanBeCanceled)
			{
				if (!token.IsCancellationRequested)
				{
					ISafeObserver<T> safeObserver = SafeObserver<T>.Wrap(observer);
					IDisposable state2 = source.Subscribe(safeObserver);
					safeObserver.SetResource(token.Register(delegate(object state)
					{
						((IDisposable)state).Dispose();
					}, state2));
				}
			}
			else
			{
				source.Subscribe(observer);
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		public static IDisposable SubscribeSafe<T>(this IObservable<T> source, IObserver<T> observer)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (observer == null)
			{
				throw new ArgumentNullException("observer");
			}
			if (source is ObservableBase<T>)
			{
				return source.Subscribe(observer);
			}
			if (source is IProducer<T> producer)
			{
				return producer.SubscribeRaw(observer, enableSafeguard: false);
			}
			IDisposable result = Disposable.Empty;
			try
			{
				result = source.Subscribe(observer);
			}
			catch (Exception error)
			{
				observer.OnError(error);
			}
			return result;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	public struct TaskObservableMethodBuilder<T>
	{
		internal sealed class TaskObservable : ITaskObservable<T>, IObservable<T>, ITaskObservableAwaiter<T>, INotifyCompletion
		{
			private readonly AsyncSubject<T>? _subject;

			private readonly T? _result;

			private readonly Exception? _exception;

			public bool IsCompleted => _subject?.IsCompleted ?? true;

			public TaskObservable()
			{
				_subject = new AsyncSubject<T>();
			}

			public TaskObservable(T result)
			{
				_result = result;
			}

			public TaskObservable(Exception exception)
			{
				_exception = exception;
			}

			public void SetResult(T result)
			{
				if (IsCompleted)
				{
					throw new InvalidOperationException();
				}
				_subject.OnNext(result);
				_subject.OnCompleted();
			}

			public void SetException(Exception exception)
			{
				if (IsCompleted)
				{
					throw new InvalidOperationException();
				}
				_subject.OnError(exception);
			}

			public IDisposable Subscribe(IObserver<T> observer)
			{
				if (_subject != null)
				{
					return _subject.Subscribe(observer);
				}
				if (_exception != null)
				{
					observer.OnError(_exception);
					return Disposable.Empty;
				}
				observer.OnNext(_result);
				return Disposable.Empty;
			}

			public ITaskObservableAwaiter<T> GetAwaiter()
			{
				return this;
			}

			public T GetResult()
			{
				if (_subject != null)
				{
					return _subject.GetResult();
				}
				_exception?.Throw();
				return _result;
			}

			public void OnCompleted(Action continuation)
			{
				if (_subject != null)
				{
					_subject.OnCompleted(continuation);
				}
				else
				{
					continuation();
				}
			}
		}

		private IAsyncStateMachine _stateMachine;

		private TaskObservable _inner;

		public ITaskObservable<T> Task => _inner ?? (_inner = new TaskObservable());

		public static TaskObservableMethodBuilder<T> Create()
		{
			return default(TaskObservableMethodBuilder<T>);
		}

		public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
		{
			if (stateMachine == null)
			{
				throw new ArgumentNullException("stateMachine");
			}
			stateMachine.MoveNext();
		}

		public void SetStateMachine(IAsyncStateMachine stateMachine)
		{
			if (_stateMachine != null)
			{
				throw new InvalidOperationException();
			}
			_stateMachine = stateMachine ?? throw new ArgumentNullException("stateMachine");
		}

		public void SetResult(T result)
		{
			if (_inner == null)
			{
				_inner = new TaskObservable(result);
			}
			else
			{
				_inner.SetResult(result);
			}
		}

		public void SetException(Exception exception)
		{
			if (exception == null)
			{
				throw new ArgumentNullException("exception");
			}
			if (_inner == null)
			{
				_inner = new TaskObservable(exception);
			}
			else
			{
				_inner.SetException(exception);
			}
		}

		public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine
		{
			try
			{
				if (_stateMachine == null)
				{
					_ = Task;
					_stateMachine = stateMachine;
					_stateMachine.SetStateMachine(_stateMachine);
				}
				ref TAwaiter reference = ref awaiter;
				TAwaiter val = default(TAwaiter);
				if (val == null)
				{
					val = reference;
					reference = ref val;
				}
				reference.OnCompleted(_stateMachine.MoveNext);
			}
			catch (Exception exception)
			{
				Rethrow(exception);
			}
		}

		[SecuritySafeCritical]
		public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine
		{
			try
			{
				if (_stateMachine == null)
				{
					_ = Task;
					_stateMachine = stateMachine;
					_stateMachine.SetStateMachine(_stateMachine);
				}
				ref TAwaiter reference = ref awaiter;
				TAwaiter val = default(TAwaiter);
				if (val == null)
				{
					val = reference;
					reference = ref val;
				}
				reference.UnsafeOnCompleted(_stateMachine.MoveNext);
			}
			catch (Exception exception)
			{
				Rethrow(exception);
			}
		}

		private static void Rethrow(Exception exception)
		{
			Scheduler.Default.Schedule(exception, delegate(Exception ex, Action<Exception> recurse)
			{
				ex.Throw();
			});
		}
	}
}
namespace System.Threading.Tasks
{
	internal static class TaskExtensions
	{
		public static Task ContinueWithState<TState>(this Task task, Action<Task, TState> continuationAction, TState state, TaskContinuationOptions continuationOptions, CancellationToken cancellationToken)
		{
			return task.ContinueWith(delegate(Task t, object tupleObject)
			{
				var (action, arg) = ((Action<Task, TState>, TState))tupleObject;
				action(t, arg);
			}, (continuationAction, state), cancellationToken, continuationOptions, TaskScheduler.Default);
		}

		public static Task ContinueWithState<TResult, TState>(this Task<TResult> task, Action<Task<TResult>, TState> continuationAction, TState state, CancellationToken cancellationToken)
		{
			return task.ContinueWith(delegate(Task<TResult> t, object tupleObject)
			{
				var (action, arg) = ((Action<Task<TResult>, TState>, TState))tupleObject;
				action(t, arg);
			}, (continuationAction, state), cancellationToken);
		}

		public static Task ContinueWithState<TResult, TState>(this Task<TResult> task, Action<Task<TResult>, TState> continuationAction, TState state, TaskContinuationOptions continuationOptions, CancellationToken cancellationToken)
		{
			return task.ContinueWith(delegate(Task<TResult> t, object tupleObject)
			{
				var (action, arg) = ((Action<Task<TResult>, TState>, TState))tupleObject;
				action(t, arg);
			}, (continuationAction, state), cancellationToken, continuationOptions, TaskScheduler.Default);
		}
	}
}
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.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class MaybeNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class NotNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal sealed class MaybeNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

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

		public NotNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[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.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.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	internal sealed class MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	internal sealed class MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
}
namespace System.Reactive
{
	public sealed class AnonymousObservable<T> : ObservableBase<T>
	{
		private readonly Func<IObserver<T>, IDisposable> _subscribe;

		public AnonymousObservable(Func<IObserver<T>, IDisposable> subscribe)
		{
			_subscribe = subscribe ?? throw new ArgumentNullException("subscribe");
		}

		protected override IDisposable SubscribeCore(IObserver<T> observer)
		{
			return _subscribe(observer) ?? Disposable.Empty;
		}
	}
	public sealed class AnonymousObserver<T> : ObserverBase<T>
	{
		private readonly Action<T> _onNext;

		private readonly Action<Exception> _onError;

		private readonly Action _onCompleted;

		public AnonymousObserver(Action<T> onNext, Action<Exception> onError, Action onCompleted)
		{
			_onNext = onNext ?? throw new ArgumentNullException("onNext");
			_onError = onError ?? throw new ArgumentNullException("onError");
			_onCompleted = onCompleted ?? throw new ArgumentNullException("onCompleted");
		}

		public AnonymousObserver(Action<T> onNext)
			: this(onNext, Stubs.Throw, Stubs.Nop)
		{
		}

		public AnonymousObserver(Action<T> onNext, Action<Exception> onError)
			: this(onNext, onError, Stubs.Nop)
		{
		}

		public AnonymousObserver(Action<T> onNext, Action onCompleted)
			: this(onNext, Stubs.Throw, onCompleted)
		{
		}

		protected override void OnNextCore(T value)
		{
			_onNext(value);
		}

		protected override void OnErrorCore(Exception error)
		{
			_onError(error);
		}

		protected override void OnCompletedCore()
		{
			_onCompleted();
		}

		internal ISafeObserver<T> MakeSafe()
		{
			return new AnonymousSafeObserver<T>(_onNext, _onError, _onCompleted);
		}
	}
	internal sealed class AnonymousSafeObserver<T> : SafeObserver<T>
	{
		private readonly Action<T> _onNext;

		private readonly Action<Exception> _onError;

		private readonly Action _onCompleted;

		private int _isStopped;

		public AnonymousSafeObserver(Action<T> onNext, Action<Exception> onError, Action onCompleted)
		{
			_onNext = onNext;
			_onError = onError;
			_onCompleted = onCompleted;
		}

		public override void OnNext(T value)
		{
			if (_isStopped != 0)
			{
				return;
			}
			bool flag = false;
			try
			{
				_onNext(value);
				flag = true;
			}
			finally
			{
				if (!flag)
				{
					Dispose();
				}
			}
		}

		public override void OnError(Exception error)
		{
			if (Interlocked.Exchange(ref _isStopped, 1) == 0)
			{
				using (this)
				{
					_onError(error);
				}
			}
		}

		public override void OnCompleted()
		{
			if (Interlocked.Exchange(ref _isStopped, 1) == 0)
			{
				using (this)
				{
					_onCompleted();
				}
			}
		}
	}
	public class EventPattern<TEventArgs> : EventPattern<object, TEventArgs>
	{
		public EventPattern(object? sender, TEventArgs e)
			: base(sender, e)
		{
		}
	}
	public class EventPattern<TSender, TEventArgs> : IEquatable<EventPattern<TSender, TEventArgs>>, IEventPattern<TSender, TEventArgs>
	{
		public TSender? Sender { get; }

		public TEventArgs EventArgs { get; }

		public EventPattern(TSender? sender, TEventArgs e)
		{
			Sender = sender;
			EventArgs = e;
		}

		public void Deconstruct(out TSender? sender, out TEventArgs e)
		{
			TSender sender2 = Sender;
			TEventArgs eventArgs = EventArgs;
			sender = sender2;
			e = eventArgs;
		}

		public bool Equals(EventPattern<TSender, TEventArgs>? other)
		{
			if ((object)other == null)
			{
				return false;
			}
			if ((object)this == other)
			{
				return true;
			}
			if (EqualityComparer<TSender>.Default.Equals(Sender, other.Sender))
			{
				return EqualityComparer<TEventArgs>.Default.Equals(EventArgs, other.EventArgs);
			}
			return false;
		}

		public override bool Equals(object? obj)
		{
			return Equals(obj as EventPattern<TSender, TEventArgs>);
		}

		public override int GetHashCode()
		{
			TSender sender = Sender;
			int num = ((sender != null) ? sender.GetHashCode() : 0);
			TEventArgs eventArgs = EventArgs;
			int num2 = ((eventArgs != null) ? eventArgs.GetHashCode() : 0);
			return (num << 5) + (num ^ num2);
		}

		public static bool operator ==(EventPattern<TSender, TEventArgs> first, EventPattern<TSender, TEventArgs> second)
		{
			return object.Equals(first, second);
		}

		public static bool operator !=(EventPattern<TSender, TEventArgs> first, EventPattern<TSender, TEventArgs> second)
		{
			return !object.Equals(first, second);
		}
	}
	internal sealed class EventPatternSource<TEventArgs> : EventPatternSourceBase<object, TEventArgs>, IEventPatternSource<TEventArgs>
	{
		event EventHandler<TEventArgs> IEventPatternSource<TEventArgs>.OnNext
		{
			add
			{
				EventHandler<TEventArgs> value2 = value;
				Add(value2, delegate(object? o, TEventArgs e)
				{
					value2(o, e);
				});
			}
			remove
			{
				Remove(value);
			}
		}

		public EventPatternSource(IObservable<EventPattern<object, TEventArgs>> source, Action<Action<object?, TEventArgs>, EventPattern<object, TEventArgs>> invokeHandler)
			: base(source, invokeHandler)
		{
		}
	}
	public abstract class EventPatternSourceBase<TSender, TEventArgs>
	{
		private sealed class Observer : ObserverBase<EventPattern<TSender, TEventArgs>>, ISafeObserver<EventPattern<TSender, TEventArgs>>, IObserver<EventPattern<TSender, TEventArgs>>, IDisposable
		{
			private bool _isDone;

			private bool _isAdded;

			private readonly Delegate _handler;

			private readonly object _gate = new object();

			private readonly Action<TSender?, TEventArgs> _invoke;

			private readonly EventPatternSourceBase<TSender, TEventArgs> _sourceBase;

			public Observer(EventPatternSourceBase<TSender, TEventArgs> sourceBase, Delegate handler, Action<TSender?, TEventArgs> invoke)
			{
				_handler = handler;
				_invoke = invoke;
				_sourceBase = sourceBase;
			}

			protected override void OnNextCore(EventPattern<TSender, TEventArgs> value)
			{
				_sourceBase._invokeHandler(_invoke, value);
			}

			protected override void OnErrorCore(Exception error)
			{
				Remove();
				error.Throw();
			}

			protected override void OnCompletedCore()
			{
				Remove();
			}

			private void Remove()
			{
				lock (_gate)
				{
					if (_isAdded)
					{
						_sourceBase.Remove(_handler);
					}
					else
					{
						_isDone = true;
					}
				}
			}

			public void SetResource(IDisposable resource)
			{
				lock (_gate)
				{
					if (!_isDone)
					{
						_sourceBase.Add(_handler, resource);
						_isAdded = true;
					}
				}
			}
		}

		private readonly IObservable<EventPattern<TSender, TEventArgs>> _source;

		private readonly Dictionary<Delegate, Stack<IDisposable>> _subscriptions;

		private readonly Action<Action<TSender?, TEventArgs>, EventPattern<TSender, TEventArgs>> _invokeHandler;

		protected EventPatternSourceBase(IObservable<EventPattern<TSender, TEventArgs>> source, Action<Action<TSender?, TEventArgs>, EventPattern<TSender, TEventArgs>> invokeHandler)
		{
			_source = source ?? throw new ArgumentNullException("source");
			_invokeHandler = invokeHandler ?? throw new ArgumentNullException("invokeHandler");
			_subscriptions = new Dictionary<Delegate, Stack<IDisposable>>();
		}

		protected void Add(Delegate handler, Action<TSender?, TEventArgs> invoke)
		{
			if ((object)handler == null)
			{
				throw new ArgumentNullException("handler");
			}
			if (invoke == null)
			{
				throw new ArgumentNullException("invoke");
			}
			Observer observer = new Observer(this, handler, invoke);
			observer.SetResource(_source.Subscribe(observer));
		}

		private void Add(Delegate handler, IDisposable disposable)
		{
			lock (_subscriptions)
			{
				if (!_subscriptions.TryGetValue(handler, out Stack<IDisposable> value))
				{
					value = (_subscriptions[handler] = new Stack<IDisposable>());
				}
				value.Push(disposable);
			}
		}

		protected void Remove(Delegate handler)
		{
			if ((object)handler == null)
			{
				throw new ArgumentNullException("handler");
			}
			IDisposable disposable = null;
			lock (_subscriptions)
			{
				if (_subscriptions.TryGetValue(handler, out Stack<IDisposable> value))
				{
					disposable = value.Pop();
					if (value.Count == 0)
					{
						_subscriptions.Remove(handler);
					}
				}
			}
			disposable?.Dispose();
		}
	}
	internal sealed class EventSource<T> : IEventSource<T>
	{
		private readonly IObservable<T> _source;

		private readonly Dictionary<Delegate, Stack<IDisposable>> _subscriptions;

		private readonly Action<Action<T>, T> _invokeHandler;

		public event Action<T> OnNext
		{
			add
			{
				Action<T> value2 = value;
				object gate = new object();
				bool isAdded = false;
				bool isDone = false;
				Action remove = delegate
				{
					lock (gate)
					{
						if (isAdded)
						{
							Remove(value2);
						}
						else
						{
							isDone = true;
						}
					}
				};
				IDisposable disposable = _source.Subscribe(delegate(T x)
				{
					_invokeHandler(value2, x);
				}, delegate(Exception ex)
				{
					remove();
					ex.Throw();
				}, remove);
				lock (gate)
				{
					if (!isDone)
					{
						Add(value2, disposable);
						isAdded = true;
					}
				}
			}
			remove
			{
				Remove(value);
			}
		}

		public EventSource(IObservable<T> source, Action<Action<T>, T> invokeHandler)
		{
			_source = source;
			_invokeHandler = invokeHandler;
			_subscriptions = new Dictionary<Delegate, Stack<IDisposable>>();
		}

		private void Add(Delegate handler, IDisposable disposable)
		{
			lock (_subscriptions)
			{
				if (!_subscriptions.TryGetValue(handler, out Stack<IDisposable> value))
				{
					value = (_subscriptions[handler] = new Stack<IDisposable>());
				}
				value.Push(disposable);
			}
		}

		private void Remove(Delegate handler)
		{
			IDisposable disposable = null;
			lock (_subscriptions)
			{
				Stack<IDisposable> value = new Stack<IDisposable>();
				if (_subscriptions.TryGetValue(handler, out value))
				{
					disposable = value.Pop();
					if (value.Count == 0)
					{
						_subscriptions.Remove(handler);
					}
				}
			}
			disposable?.Dispose();
		}
	}
	[Experimental]
	[AttributeUsage(AttributeTargets.All)]
	public sealed class ExperimentalAttribute : Attribute
	{
	}
	public interface IEventPattern<out TSender, out TEventArgs>
	{
		TSender? Sender { get; }

		TEventArgs EventArgs { get; }
	}
	public interface IEventPatternSource<TEventArgs>
	{
		event EventHandler<TEventArgs> OnNext;
	}
	public interface IEventSource<out T>
	{
		event Action<T> OnNext;
	}
	internal sealed class AnonymousEnumerable<T> : IEnumerable<T>, IEnumerable
	{
		private readonly Func<IEnumerator<T>> _getEnumerator;

		public AnonymousEnumerable(Func<IEnumerator<T>> getEnumerator)
		{
			_getEnumerator = getEnumerator;
		}

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

		IEnumerator IEnumerable.GetEnumerator()
		{
			return _getEnumerator();
		}
	}
	internal sealed class AsyncLockObserver<T> : ObserverBase<T>
	{
		private readonly AsyncLock _gate;

		private readonly IObserver<T> _observer;

		public AsyncLockObserver(IObserver<T> observer, AsyncLock gate)
		{
			_gate = gate;
			_observer = observer;
		}

		protected override void OnNextCore(T value)
		{
			_gate.Wait((_observer, value), delegate((IObserver<T> _observer, T value) tuple)
			{
				tuple._observer.OnNext(tuple.value);
			});
		}

		protected override void OnErrorCore(Exception exception)
		{
			_gate.Wait((_observer, exception), delegate((IObserver<T> _observer, Exception exception) tuple)
			{
				tuple._observer.OnError(tuple.exception);
			});
		}

		protected override void OnCompletedCore()
		{
			_gate.Wait(_observer, delegate(IObserver<T> closureObserver)
			{
				closureObserver.OnCompleted();
			});
		}
	}
	internal sealed class AutoDetachObserver<T> : ObserverBase<T>, ISafeObserver<T>, IObserver<T>, IDisposable
	{
		private readonly IObserver<T> _observer;

		private SingleAssignmentDisposableValue _disposable;

		public AutoDetachObserver(IObserver<T> observer)
		{
			_observer = observer;
		}

		public void SetResource(IDisposable resource)
		{
			_disposable.Disposable = resource;
		}

		protected override void OnNextCore(T value)
		{
			bool flag = false;
			try
			{
				_observer.OnNext(value);
				flag = true;
			}
			finally
			{
				if (!flag)
				{
					Dispose();
				}
			}
		}

		protected override void OnErrorCore(Exception exception)
		{
			try
			{
				_observer.OnError(exception);
			}
			finally
			{
				Dispose();
			}
		}

		protected override void OnCompletedCore()
		{
			try
			{
				_observer.OnCompleted();
			}
			finally
			{
				Dispose();
			}
		}

		protected override void Dispose(bool disposing)
		{
			base.Dispose(disposing);
			if (disposing)
			{
				_disposable.Dispose();
			}
		}
	}
	internal sealed class BinaryObserver<TLeft, TRight> : IObserver<Either<Notification<TLeft>, Notification<TRight>>>
	{
		public IObserver<TLeft> LeftObserver { get; }

		public IObserver<TRight> RightObserver { get; }

		public BinaryObserver(IObserver<TLeft> leftObserver, IObserver<TRight> rightObserver)
		{
			LeftObserver = leftObserver;
			RightObserver = rightObserver;
		}

		public BinaryObserver(Action<Notification<TLeft>> left, Action<Notification<TRight>> right)
			: this(left.ToObserver(), right.ToObserver())
		{
		}

		void IObserver<Either<Notification<TLeft>, Notification<TRight>>>.OnNext(Either<Notification<TLeft>, Notification<TRight>> value)
		{
			value.Switch(delegate(Notification<TLeft> left)
			{
				left.Accept(LeftObserver);
			}, delegate(Notification<TRight> right)
			{
				right.Accept(RightObserver);
			});
		}

		void IObserver<Either<Notification<TLeft>, Notification<TRight>>>.OnError(Exception exception)
		{
		}

		void IObserver<Either<Notification<TLeft>, Notification<TRight>>>.OnCompleted()
		{
		}
	}
	internal sealed class CheckedObserver<T> : IObserver<T>
	{
		private readonly IObserver<T> _observer;

		private int _state;

		private const int Idle = 0;

		private const int Busy = 1;

		private const int Done = 2;

		public CheckedObserver(IObserver<T> observer)
		{
			_observer = observer;
		}

		public void OnNext(T value)
		{
			CheckAccess();
			try
			{
				_observer.OnNext(value);
			}
			finally
			{
				Interlocked.Exchange(ref _state, 0);
			}
		}

		public void OnError(Exception error)
		{
			CheckAccess();
			try
			{
				_observer.OnError(error);
			}
			finally
			{
				Interlocked.Exchange(ref _state, 2);
			}
		}

		public void OnCompleted()
		{
			CheckAccess();
			try
			{
				_observer.OnCompleted();
			}
			finally
			{
				Interlocked.Exchange(ref _state, 2);
			}
		}

		private void CheckAccess()
		{
			switch (Interlocked.CompareExchange(ref _state, 1, 0))
			{
			case 1:
				throw new InvalidOperationException(Strings_Core.REENTRANCY_DETECTED);
			case 2:
				throw new InvalidOperationException(Strings_Core.OBSERVER_TERMINATED);
			}
		}
	}
	internal abstract class ConcatSink<TSource> : TailRecursiveSink<TSource>
	{
		protected ConcatSink(IObserver<TSource> observer)
			: base(observer)
		{
		}

		protected override IEnumerable<IObservable<TSource>>? Extract(IObservable<TSource> source)
		{
			return (source as IConcatenatable<TSource>)?.GetSources();
		}

		public override void OnCompleted()
		{
			Recurse();
		}
	}
	internal static class Constants_Core
	{
		private const string ObsoleteRefactoring = "This property is no longer supported due to refactoring of the API surface and elimination of platform-specific dependencies.";

		public const string ObsoleteSchedulerNewthread = "This property is no longer supported due to refactoring of the API surface and elimination of platform-specific dependencies. Please use NewThreadScheduler.Default to obtain an instance of this scheduler type.";

		public const string ObsoleteSchedulerTaskpool = "This property is no longer supported due to refactoring of the API surface and elimination of platform-specific dependencies. Please use TaskPoolScheduler.Default to obtain an instance of this scheduler type.";

		public const string ObsoleteSchedulerThreadpool = "This property is no longer supported due to refactoring of the API surface and elimination of platform-specific dependencies. Consider using Scheduler.Default to obtain the platform's most appropriate pool-based scheduler. In order to access a specific pool-based scheduler, please add a reference to the System.Reactive.PlatformServices assembly for your target platform and use the appropriate scheduler in the System.Reactive.Concurrency namespace.";

		public const string ObsoleteSchedulerequired = "This instance property is no longer supported. Use CurrentThreadScheduler.IsScheduleRequired instead.";

		internal const string AsQueryableTrimIncompatibilityMessage = "This type uses Queryable.AsQueryable, which is not compatible with trimming because expressions referencing IQueryable extension methods can get rebound to IEnumerable extension methods, and those IEnumerable methods might be trimmed.";

		internal const string EventReflectionTrimIncompatibilityMessage = "This member uses reflection to discover event members and associated delegate types.";
	}
	internal static class Constants_Linq
	{
		public const string UseAsync = "This blocking operation is no longer supported. Instead, use the async version in combination with C# and Visual Basic async/await support. In case you need a blocking operation, use Wait or convert the resulting observable sequence to a Task object and block.";

		public const string UseTaskFromAsyncPattern = "This conversion is no longer supported. Replace use of the Begin/End asynchronous method pair with a new Task-based async method, and convert the result using ToObservable. If no Task-based async method is available, use Task.Factory.FromAsync to obtain a Task object.";
	}
	internal abstract class Either<TLeft, TRight>
	{
		public sealed class Left : Either<TLeft, TRight>, IEquatable<Left>
		{
			public TLeft Value { get; }

			public Left(TLeft value)
			{
				Value = value;
			}

			public override TResult Switch<TResult>(Func<TLeft, TResult> caseLeft, Func<TRight, TResult> caseRight)
			{
				return caseLeft(Value);
			}

			public override void Switch(Action<TLeft> caseLeft, Action<TRight> caseRight)
			{
				caseLeft(Value);
			}

			public bool Equals(Left? other)
			{
				if (other == this)
				{
					return true;
				}
				if (other == null)
				{
					return false;
				}
				return EqualityComparer<TLeft>.Default.Equals(Value, other.Value);
			}

			public override bool Equals(object? obj)
			{
				return Equals(obj as Either<TLeft, TRight>.Left);
			}

			public override int GetHashCode()
			{
				TLeft value = Value;
				if (value == null)
				{
					return 0;
				}
				return value.GetHashCode();
			}

			public override string ToString()
			{
				return string.Format(CultureInfo.CurrentCulture, "Left({0})", Value);
			}
		}

		public sealed class Right : Either<TLeft, TRight>, IEquatable<Right>
		{
			public TRight Value { get; }

			public Right(TRight value)
			{
				Value = value;
			}

			public override TResult Switch<TResult>(Func<TLeft, TResult> caseLeft, Func<TRight, TResult> caseRight)
			{
				return caseRight(Value);
			}

			public override void Switch(Action<TLeft> caseLeft, Action<TRight> caseRight)
			{
				caseRight(Value);
			}

			public bool Equals(Right? other)
			{
				if (other == this)
				{
					return true;
				}
				if (other == null)
				{
					return false;
				}
				return EqualityComparer<TRight>.Default.Equals(Value, other.Value);
			}

			public override bool Equals(object? obj)
			{
				return Equals(obj as Either<TLeft, TRight>.Right);
			}

			public override int GetHashCode()
			{
				TRight value = Value;
				if (value == null)
				{
					return 0;
				}
				return value.GetHashCode();
			}

			public override string ToString()
			{
				return string.Format(CultureInfo.CurrentCulture, "Right({0})", Value);
			}
		}

		private Either()
		{
		}

		public static Either<TLeft, TRight> CreateLeft(TLeft value)
		{
			return new Left(value);
		}

		public static Either<TLeft, TRight> CreateRight(TRight value)
		{
			return new Right(value);
		}

		public abstract TResult Switch<TResult>(Func<TLeft, TResult> caseLeft, Func<TRight, TResult> caseRight);

		public abstract void Switch(Action<TLeft> caseLeft, Action<TRight> caseRight);
	}
	internal static class ExceptionHelper
	{
		public static Exception Terminated { get; } = new EndOfStreamException("On[Error|Completed]");


		public static bool TrySetException(ref Exception? field, Exception ex)
		{
			return Interlocked.CompareExchange(ref field, ex, null) == null;
		}
	}
	internal static class ExceptionHelpers
	{
		private static readonly Lazy<IExceptionServices> Services = new Lazy<IExceptionServices>(Initialize);

		[DoesNotReturn]
		public static void Throw(this Exception exception)
		{
			Services.Value.Rethrow(exception);
		}

		private static IExceptionServices Initialize()
		{
			return PlatformEnlightenmentProvider.Current.GetService<IExceptionServices>(Array.Empty<object>()) ?? new DefaultExceptionServices();
		}
	}
	internal sealed class Grouping<TKey, TElement> : Dictionary<TKey, Subject<TElement>>
	{
		public Grouping(IEqualityComparer<TKey> comparer)
			: base(comparer)
		{
		}

		public Grouping(int capacity, IEqualityComparer<TKey> comparer)
			: base(capacity, comparer)
		{
		}
	}
	internal static class HalfSerializer
	{
		public static void ForwardOnNext<T>(ISink<T> sink, T item, ref int wip, ref Exception? error)
		{
			if (Interlocked.CompareExchange(ref wip, 1, 0) == 0)
			{
				sink.ForwardOnNext(item);
				if (Interlocked.Decrement(ref wip) != 0)
				{
					Exception ex = error;
					if (ex != ExceptionHelper.Terminated)
					{
						error = ExceptionHelper.Terminated;
						sink.ForwardOnError(ex);
					}
					else
					{
						sink.ForwardOnCompleted();
					}
				}
			}
			else if (error == null)
			{
				Trace.TraceWarning("OnNext called while another OnNext call was in progress on the same Observer.");
			}
		}

		public static void ForwardOnError<T>(ISink<T> sink, Exception ex, ref int wip, ref Exception? error)
		{
			if (ExceptionHelper.TrySetException(ref error, ex) && Interlocked.Increment(ref wip) == 1)
			{
				error = ExceptionHelper.Terminated;
				sink.ForwardOnError(ex);
			}
		}

		public static void ForwardOnCompleted<T>(ISink<T> sink, ref int wip, ref Exception? error)
		{
			if (ExceptionHelper.TrySetException(ref error, ExceptionHelper.Terminated) && Interlocked.Increment(ref wip) == 1)
			{
				sink.ForwardOnCompleted();
			}
		}
	}
	internal static class Helpers
	{
		public static bool All(this bool[] values)
		{
			for (int i = 0; i < values.Length; i++)
			{
				if (!values[i])
				{
					return false;
				}
			}
			return true;
		}

		public static bool AllExcept(this bool[] values, int index)
		{
			for (int i = 0; i < values.Length; i++)
			{
				if (i != index && !values[i])
				{
					return false;
				}
			}
			return true;
		}
	}
	internal interface IConcatenatable<out TSource>
	{
		IEnumerable<IObservable<TSource>> GetSources();
	}
	internal abstract class IdentitySink<T> : Sink<T, T>
	{
		protected IdentitySink(IObserver<T> observer)
			: base(observer)
		{
		}

		public override void OnNext(T value)
		{
			ForwardOnNext(value);
		}
	}
	internal interface IEvaluatableObservable<out T>
	{
		IObservable<T> Eval();
	}
	internal sealed class ImmutableList<T>
	{
		public static readonly ImmutableList<T> Empty = new ImmutableList<T>();

		private readonly T[] _data;

		public T[] Data => _data;

		private ImmutableList()
		{
			_data = Array.Empty<T>();
		}

		public ImmutableList(T[] data)
		{
			_data = data;
		}

		public ImmutableList<T> Add(T value)
		{
			T[] array = new T[_data.Length + 1];
			Array.Copy(_data, array, _data.Length);
			array[_data.Length] = value;
			return new ImmutableList<T>(array);
		}

		public ImmutableList<T> Remove(T value)
		{
			int num = Array.IndexOf(_data, value);
			if (num < 0)
			{
				return this;
			}
			int num2 = _data.Length;
			if (num2 == 1)
			{
				return Empty;
			}
			T[] array = new T[num2 - 1];
			Array.Copy(_data, 0, array, 0, num);
			Array.Copy(_data, num + 1, array, num, num2 - num - 1);
			return new ImmutableList<T>(array);
		}
	}
	internal interface ISafeObserver<in T> : IObserver<T>, IDisposable
	{
		void SetResource(IDisposable resource);
	}
	internal sealed class Lookup<K, E> : ILookup<K, E>, IEnumerable<IGrouping<K, E>>, IEnumerable
	{
		private sealed class Grouping : IGrouping<K, E>, IEnumerable<E>, IEnumerable
		{
			private readonly KeyValuePair<K, List<E>> _keyValuePair;

			public K Key
			{
				get
				{
					KeyValuePair<K, List<E>> keyValuePair = _keyValuePair;
					return keyValuePair.Key;
				}
			}

			public Grouping(KeyValuePair<K, List<E>> keyValuePair)
			{
				_keyValuePair = keyValuePair;
			}

			public IEnumerator<E> GetEnumerator()
			{
				KeyValuePair<K, List<E>> keyValuePair = _keyValuePair;
				return keyValuePair.Value.GetEnumerator();
			}

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

		private readonly Dictionary<K, List<E>> _dictionary;

		public int Count => _dictionary.Count;

		public IEnumerable<E> this[K key]
		{
			get
			{
				if (!_dictionary.TryGetValue(key, out var value))
				{
					return Enumerable.Empty<E>();
				}
				return Hide(value);
			}
		}

		public Lookup(IEqualityComparer<K> comparer)
		{
			_dictionary = new Dictionary<K, List<E>>(comparer);
		}

		public void Add(K key, E element)
		{
			if (!_dictionary.TryGetValue(key, out var value))
			{
				value = (_dictionary[key] = new List<E>());
			}
			value.Add(element);
		}

		public bool Contains(K key)
		{
			return _dictionary.ContainsKey(key);
		}

		private static IEnumerable<E> Hide(List<E> elements)
		{
			return elements.Skip(0);
		}

		public IEnumerator<IGrouping<K, E>> GetEnumerator()
		{
			foreach (KeyValuePair<K, List<E>> item in _dictionary)
			{
				yield return new Grouping(item);
			}
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}
	}
	internal sealed class Map<TKey, TValue>
	{
		private const int DefaultConcurrencyMultiplier = 4;

		private readonly ConcurrentDictionary<TKey, TValue> _map;

		private static int DefaultConcurrencyLevel => 4 * Environment.ProcessorCount;

		public IEnumerable<TValue> Values => _map.Values.ToArray();

		public Map(int? capacity, IEqualityComparer<TKey> comparer)
		{
			if (capacity.HasValue)
			{
				_map = new ConcurrentDictionary<TKey, TValue>(DefaultConcurrencyLevel, capacity.Value, comparer);
			}
			else
			{
				_map = new ConcurrentDictionary<TKey, TValue>(comparer);
			}
		}

		public TValue GetOrAdd(TKey key, Func<TValue> valueFactory, out bool added)
		{
			added = false;
			TValue val = default(TValue);
			bool flag = false;
			TValue value;
			while (!_map.TryGetValue(key, out value))
			{
				if (!flag)
				{
					val = valueFactory();
					flag = true;
				}
				if (_map.TryAdd(key, val))
				{
					added = true;
					return val;
				}
			}
			return value;
		}

		public bool Remove(TKey key)
		{
			TValue value;
			return _map.TryRemove(key, out value);
		}
	}
	internal sealed class NopObserver<T> : IObserver<T>
	{
		public static readonly IObserver<T> Instance = new NopObserver<T>();

		public void OnCompleted()
		{
		}

		public void OnError(Exception error)
		{
		}

		public void OnNext(T value)
		{
		}
	}
	internal sealed class PriorityQueue<T> where T : IComparable<T>
	{
		private struct IndexedItem : IComparable<IndexedItem>
		{
			public T Value;

			public long Id;

			public int CompareTo(IndexedItem other)
			{
				int num = Value.CompareTo(other.Value);
				if (num == 0)
				{
					num = Id.CompareTo(other.Id);
				}
				return num;
			}
		}

		private long _count = long.MinValue;

		private IndexedItem[] _items;

		private int _size;

		public int Count => _size;

		public PriorityQueue()
			: this(16)
		{
		}

		public PriorityQueue(int capacity)
		{
			_items = new IndexedItem[capacity];
			_size = 0;
		}

		private bool IsHigherPriority(int left, int right)
		{
			return _items[left].CompareTo(_items[right]) < 0;
		}

		private int Percolate(int index)
		{
			if (index >= _size || index < 0)
			{
				return index;
			}
			int num = (index - 1) / 2;
			while (num >= 0 && num != index && IsHigherPriority(index, num))
			{
				ref IndexedItem reference = ref _items[num];
				ref IndexedItem reference2 = ref _items[index];
				IndexedItem indexedItem = _items[index];
				IndexedItem indexedItem2 = _items[num];
				reference = indexedItem;
				reference2 = indexedItem2;
				index = num;
				num = (index - 1) / 2;
			}
			return index;
		}

		private void Heapify(int index)
		{
			if (index >= _size || index < 0)
			{
				return;
			}
			while (true)
			{
				int num = 2 * index + 1;
				int num2 = 2 * index + 2;
				int num3 = index;
				if (num < _size && IsHigherPriority(num, num3))
				{
					num3 = num;
				}
				if (num2 < _size && IsHigherPriority(num2, num3))
				{
					num3 = num2;
				}
				if (num3 != index)
				{
					ref IndexedItem reference = ref _items[num3];
					ref IndexedItem reference2 = ref _items[index];
					IndexedItem indexedItem = _items[index];
					IndexedItem indexedItem2 = _items[num3];
					reference = indexedItem;
					reference2 = indexedItem2;
					index = num3;
					continue;
				}
				break;
			}
		}

		public T Peek()
		{
			if (_size == 0)
			{
				throw new InvalidOperationException(Strings_Core.HEAP_EMPTY);
			}
			return _items[0].Value;
		}

		private void RemoveAt(int index)
		{
			_items[index] = _items[--_size];
			_items[_size] = default(IndexedItem);
			if (Percolate(index) == index)
			{
				Heapify(index);
			}
			if (_size < _items.Length / 4)
			{
				IndexedItem[] items = _items;
				_items = new IndexedItem[_items.Length / 2];
				Array.Copy(items, 0, _items, 0, _size);
			}
		}

		public T Dequeue()
		{
			T result = Peek();
			RemoveAt(0);
			return result;
		}

		public void Enqueue(T item)
		{
			if (_size >= _items.Length)
			{
				IndexedItem[] items = _items;
				_items = new IndexedItem[_items.Length * 2];
				Array.Copy(items, _items, items.Length);
			}
			int num = _size++;
			_items[num] = new IndexedItem
			{
				Value = item,
				Id = ++_count
			};
			Percolate(num);
		}

		public bool Remove(T item)
		{
			for (int i = 0; i < _size; i++)
			{
				if (EqualityComparer<T>.Default.Equals(_items[i].Value, item))
				{
					RemoveAt(i);
					return true;
				}
			}
			return false;
		}
	}
	internal interface IProducer<out TSource> : IObservable<TSource>
	{
		IDisposable SubscribeRaw(IObserver<TSource> observer, bool enableSafeguard);
	}
	internal abstract class BasicProducer<TSource> : IProducer<TSource>, IObservable<TSource>
	{
		public IDisposable Subscribe(IObserver<TSource> observer)
		{
			if (observer == null)
			{
				throw new ArgumentNullException("observer");
			}
			return SubscribeRaw(observer, enableSafeguard: true);
		}

		public IDisposable SubscribeRaw(IObserver<TSource> observer, bool enableSafeguard)
		{
			ISafeObserver<TSource> safeObserver = null;
			if (enableSafeguard)
			{
				observer = (safeObserver = SafeObserver<TSource>.Wrap(observer));
			}
			IDisposable disposable;
			if (CurrentThreadScheduler.IsScheduleRequired)
			{
				SingleAssignmentDisposable singleAssignmentDisposable = new SingleAssignmentDisposable();
				CurrentThreadScheduler.Instance.ScheduleAction((this, singleAssignmentDisposable, observer), ((BasicProducer<TSource> @this, SingleAssignmentDisposable runAssignable, IObserver<TSource> observer) tuple) => tuple.runAssignable.Disposable = tuple.@this.Run(tuple.observer));
				disposable = singleAssignmentDisposable;
			}
			else
			{
				disposable = Run(observer);
			}
			safeObserver?.SetResource(disposable);
			return disposable;
		}

		protected abstract IDisposable Run(IObserver<TSource> observer);
	}
	internal abstract class Producer<TTarget, TSink> : IProducer<TTarget>, IObservable<TTarget> where TSink : IDisposable
	{
		public IDisposable Subscribe(IObserver<TTarget> observer)
		{
			if (observer == null)
			{
				throw new ArgumentNullException("observer");
			}
			return SubscribeRaw(observer, enableSafeguard: true);
		}

		public IDisposable SubscribeRaw(IObserver<TTarget> observer, bool enableSafeguard)
		{
			ISafeObserver<TTarget> safeObserver = null;
			if (enableSafeguard)
			{
				observer = (safeObserver = SafeObserver<TTarget>.Wrap(observer));
			}
			TSink val = CreateSink(observer);
			safeObserver?.SetResource(val);
			if (CurrentThreadScheduler.IsScheduleRequired)
			{
				CurrentThreadScheduler.Instance.ScheduleAction((this, val), delegate((Producer<TTarget, TSink> @this, TSink sink) tuple)
				{
					tuple.@this.Run(tuple.sink);
				});
			}
			else
			{
				Run(val);
			}
			return val;
		}

		protected abstract void Run(TSink sink);

		protected abstract TSink CreateSink(IObserver<TTarget> observer);
	}
	internal static class ReflectionUtils
	{
		public static TDelegate CreateDelegate<TDelegate>(object o, MethodInfo method)
		{
			return (TDelegate)(object)method.CreateDelegate(typeof(TDelegate), o);
		}

		public static Delegate CreateDelegate(Type delegateType, object o, MethodInfo method)
		{
			return method.CreateDelegate(delegateType, o);
		}

		public static void GetEventMethods<TSender, TEventArgs>(Type targetType, object? target, string eventName, out MethodInfo addMethod, out MethodInfo removeMethod, out Type delegateType, out bool isWinRT)
		{
			EventInfo @event;
			if (target == null)
			{
				@event = targetType.GetEvent(eventName, BindingFlags.Static | BindingFlags.Public);
				if (@event == null)
				{
					throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings_Linq.COULD_NOT_FIND_STATIC_EVENT, eventName, targetType.FullName));
				}
			}
			else
			{
				@event = targetType.GetEvent(eventName, BindingFlags.Instance | BindingFlags.Public);
				if (@event == null)
				{
					throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings_Linq.COULD_NOT_FIND_INSTANCE_EVENT, eventName, targetType.FullName));
				}
			}
			addMethod = @event.GetAddMethod() ?? throw new InvalidOperationException(Strings_Linq.EVENT_MISSING_ADD_METHOD);
			removeMethod = @event.GetRemoveMethod() ?? throw new InvalidOperationException(Strings_Linq.EVENT_MISSING_REMOVE_METHOD);
			ParameterInfo[] parameters = addMethod.GetParameters();
			if (parameters.Length != 1)
			{
				throw new InvalidOperationException(Strings_Linq.EVENT_ADD_METHOD_SHOULD_TAKE_ONE_PARAMETER);
			}
			ParameterInfo[] parameters2 = removeMethod.GetParameters();
			if (parameters2.Length != 1)
			{
				throw new InvalidOperationException(Strings_Linq.EVENT_REMOVE_METHOD_SHOULD_TAKE_ONE_PARAMETER);
			}
			isWinRT = false;
			if (IsWinRTEventRegistrationTokenType(addMethod.ReturnType))
			{
				isWinRT = true;
				if (IsWinRTEventRegistrationTokenType(parameters2[0].ParameterType))
				{
					throw new InvalidOperationException(Strings_Linq.EVENT_WINRT_REMOVE_METHOD_SHOULD_TAKE_ERT);
				}
			}
			delegateType = parameters[0].ParameterType;
			MethodInfo? method = delegateType.GetMethod("Invoke");
			ParameterInfo[] parameters3 = method.GetParameters();
			if (parameters3.Length != 2)
			{
				throw new InvalidOperationException(Strings_Linq.EVENT_PATTERN_REQUIRES_TWO_PARAMETERS);
			}
			if (!typeof(TSender).IsAssignableFrom(parameters3[0].ParameterType))
			{
				throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings_Linq.EVENT_SENDER_NOT_ASSIGNABLE, typeof(TSender).FullName));
			}
			if (!typeof(TEventArgs).IsAssignableFrom(parameters3[1].ParameterType))
			{
				throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings_Linq.EVENT_ARGS_NOT_ASSIGNABLE, typeof(TEventArgs).FullName));
			}
			if (method.ReturnType != typeof(void))
			{
				throw new InvalidOperationException(Strings_Linq.EVENT_MUST_RETURN_VOID);
			}
		}

		private static bool IsWinRTEventRegistrationTokenType(Type t)
		{
			if (t.Name == "EventRegistrationToken")
			{
				if (!(t.Namespace == "System.Runtime.InteropServices.WindowsRuntime"))
				{
					return t.Namespace == "WinRT";
				}
				return true;
			}
			return false;
		}
	}
	internal abstract class SafeObserver<TSource> : ISafeObserver<TSource>, IObserver<TSource>, IDisposable
	{
		private sealed class WrappingSafeObserver : SafeObserver<TSource>
		{
			private readonly IObserver<TSource> _observer;

			public WrappingSafeObserver(IObserver<TSource> observer)
			{
				_observer = observer;
			}

			public override void OnNext(TSource value)
			{
				bool flag = false;
				try
				{
					_observer.OnNext(value);
					flag = true;
				}
				finally
				{
					if (!flag)
					{
						Dispose();
					}
				}
			}

			public override void OnError(Exception error)
			{
				using (this)
				{
					_observer.OnError(error);
				}
			}

			public override void OnCompleted()
			{
				using (this)
				{
					_observer.OnCompleted();
				}
			}
		}

		private SingleAssignmentDisposableValue _disposable;

		public static ISafeObserver<TSource> Wrap(IObserver<TSource> observer)
		{
			if (observer is AnonymousObserver<TSource> anonymousObserver)
			{
				return anonymousObserver.MakeSafe();
			}
			return new WrappingSafeObserver(observer);
		}

		public abstract void OnNext(TSource value);

		public abstract void OnError(Exception error);

		public abstract void OnCompleted();

		public void SetResource(IDisposable resource)
		{
			_disposable.Disposable = resource;
		}

		public void Dispose()
		{
			Dispose(disposing: true);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (disposing)
			{
				_disposable.Dispose();
			}
		}
	}
	internal class ScheduledObserver<T> : ObserverBase<T>, IScheduledObserver<T>, IObserver<T>, IDisposable
	{
		private sealed class SemaphoreSlimRelease : IDisposable
		{
			private volatile SemaphoreSlim? _dispatcherEvent;

			public SemaphoreSlimRelease(SemaphoreSlim dispatcherEvent)
			{
				_dispatcherEvent = dispatcherEvent;
			}

			public void Dispose()
			{
				Interlocked.Exchange(ref _dispatcherEvent, null)?.Release();
			}
		}

		private int _state;

		private const int Stopped = 0;

		private const int Running = 1;

		private const int Pending = 2;

		private const int Faulted = 9;

		private readonly ConcurrentQueue<T> _queue = new ConcurrentQueue<T>();

		private bool _failed;

		private Exception? _error;

		private bool _completed;

		private readonly IObserver<T> _observer;

		private readonly IScheduler _scheduler;

		private readonly ISchedulerLongRunning? _longRunning;

		private SerialDisposableValue _disposable;

		private readonly object _dispatcherInitGate = new object();

		private readonly SemaphoreSlim? _dispatcherEvent;

		private readonly IDisposable? _dispatcherEventRelease;

		private IDisposable? _dispatcherJob;

		public ScheduledObserver(IScheduler scheduler, IObserver<T> observer)
		{
			_scheduler = scheduler;
			_observer = observer;
			_longRunning = _scheduler.AsLongRunning();
			if (_longRunning != null)
			{
				_dispatcherEvent = new SemaphoreSlim(0);
				_dispatcherEventRelease = new SemaphoreSlimRelease(_dispatcherEvent);
			}
		}

		private void EnsureDispatcher()
		{
			if (_dispatcherJob != null)
			{
				return;
			}
			lock (_dispatcherInitGate)
			{
				if (_dispatcherJob == null)
				{
					_dispatcherJob = _longRunning.ScheduleLongRunning(Dispatch);
					_disposable.Disposable = StableCompositeDisposable.Create(_dispatcherJob, _dispatcherEventRelease);
				}
			}
		}

		private void Dispatch(ICancelable cancel)
		{
			do
			{
				_dispatcherEvent.Wait();
				if (cancel.IsDisposed)
				{
					return;
				}
				T result;
				while (_queue.TryDequeue(out result))
				{
					try
					{
						_observer.OnNext(result);
					}
					catch
					{
						T result2;
						while (_queue.TryDequeue(out result2))
						{
						}
						throw;
					}
					_dispatcherEvent.Wait();
					if (cancel.IsDisposed)
					{
						return;
					}
				}
				if (_failed)
				{
					_observer.OnError(_error);
					Dispose();
					return;
				}
			}
			while (!_completed);
			_observer.OnCompleted();
			Dispose();
		}

		public void EnsureActive()
		{
			EnsureActive(1);
		}

		public void EnsureActive(int n)
		{
			if (_longRunning != null)
			{
				if (n > 0)
				{
					_dispatcherEvent.Release(n);
				}
				EnsureDispatcher();
			}
			else
			{
				EnsureActiveSlow();
			}
		}

		private void EnsureActiveSlow()
		{
			bool flag = false;
			do
			{
				IL_0002:
				switch (Interlocked.CompareExchange(ref _state, 1, 0))
				{
				default:
					goto IL_0002;
				case 0:
					flag = true;
					break;
				case 9:
					return;
				case 1:
					continue;
				case 2:
					break;
				}
				break;
			}
			while (Interlocked.CompareExchange(ref _state, 2, 1) != 1);
			if (flag)
			{
				_disposable.Disposable = _scheduler.Schedule<object>(null, Run);
			}
		}

		private void Run(object? state, Action<object?> recurse)
		{
			T result;
			while (!_queue.TryDequeue(out result))
			{
				if (_failed)
				{
					if (_queue.IsEmpty)
					{
						Interlocked.Exchange(ref _state, 0);
						_observer.OnError(_error);
						Dispose();
						return;
					}
				}
				else if (_completed)
				{
					if (_queue.IsEmpty)
					{
						Interlocked.Exchange(ref _state, 0);
						_observer.OnCompleted();
						Dispose();
						return;
					}
				}
				else
				{
					int num = Interlocked.CompareExchange(ref _state, 0, 1);
					if (num == 1 || num == 9)
					{
						return;
					}
					_state = 1;
				}
			}
			Interlocked.Exchange(ref _state, 1);
			try
			{
				_observer.OnNext(result);
			}
			catch
			{
				Interlocked.Exchange(ref _state, 9);
				T result2;
				while (_queue.TryDequeue(out result2))
				{
				}
				throw;
			}
			recurse(state);
		}

		protected override void OnNextCore(T value)
		{
			_queue.Enqueue(value);
		}

		protected override void OnErrorCore(Exception exception)
		{
			_error = exception;
			_failed = true;
		}

		protected override void OnCompletedCore()
		{
			_completed = true;
		}

		protected override void Dispose(bool disposing)
		{
			base.Dispose(disposing);
			if (disposing)
			{
				_disposable.Dispose();
			}
		}
	}
	internal sealed class ObserveOnObserver<T> : ScheduledObserver<T>
	{
		private SingleAssignmentDisposableValue _run;

		public ObserveOnObserver(IScheduler scheduler, IObserver<T> observer)
			: base(scheduler, observer)
		{
		}

		public void Run(IObservable<T> source)
		{
			_run.Disposable = source.SubscribeSafe(this);
		}

		protected override void OnNextCore(T value)
		{
			base.OnNextCore(value);
			EnsureActive();
		}

		protected override void OnErrorCore(Exception exception)
		{
			base.OnErrorCore(exception);
			EnsureActive();
		}

		protected override void OnCompletedCore()
		{
			base.OnCompletedCore();
			EnsureActive();
		}

		protected override void Dispose(bool disposing)
		{
			base.Dispose(disposing);
			if (disposing)
			{
				_run.Dispose();
			}
		}
	}
	internal interface IScheduledObserver<T> : IObserver<T>, IDisposable
	{
		void EnsureActive();

		void EnsureActive(int count);
	}
	internal sealed class ObserveOnObserverNew<T> : IdentitySink<T>
	{
		private readonly IScheduler _scheduler;

		private readonly ConcurrentQueue<T> _queue;

		private IDisposable? _task;

		private int _wip;

		private bool _done;

		private Exception? _error;

		private bool _disposed;

		private static readonly Func<IScheduler, ObserveOnObserverNew<T>, IDisposable> DrainShortRunningFunc = (IScheduler scheduler, ObserveOnObserverNew<T> self) => self.DrainShortRunning(scheduler);

		public ObserveOnObserverNew(IScheduler scheduler, IObserver<T> downstream)
			: base(downstream)
		{
			_scheduler = scheduler;
			_queue = new ConcurrentQueue<T>();
		}

		protected override void Dispose(bool disposing)
		{
			Volatile.Write(ref _disposed, value: true);
			base.Dispose(disposing);
			if (disposing)
			{
				Disposable.Dispose(ref _task);
				Clear(_queue);
			}
		}

		private static void Clear(ConcurrentQueue<T> q)
		{
			T result;
			while (q.TryDequeue(out result))
			{
			}
		}

		public override void OnCompleted()
		{
			Volatile.Write(ref _done, value: true);
			Schedule();
		}

		public override void OnError(Exception error)
		{
			_error = error;
			Volatile.Write(ref _done, value: true);
			Schedule();
		}

		public override void OnNext(T value)
		{
			_queue.Enqueue(value);
			Schedule();
		}

		private void Schedule()
		{
			if (Interlocked.Increment(ref _wip) == 1)
			{
				SingleAssignmentDisposable singleAssignmentDisposable = new SingleAssignmentDisposable();
				if (Disposable.TrySetMultiple(ref _task, singleAssignmentDisposable))
				{
					singleAssignmentDisposable.Disposable = _scheduler.Schedule(this, DrainShortRunningFunc);
				}
				if (Volatile.Read(ref _disposed))
				{
					Clear(_queue);
				}
			}
		}

		private IDisposable DrainShortRunning(IScheduler recursiveScheduler)
		{
			DrainStep(_queue);
			if (Interlocked.Decrement(ref _wip) != 0)
			{
				IDisposable value = recursiveScheduler.Schedule(this, DrainShortRunningFunc);
				Disposable.TrySetMultiple(ref _task, value);
			}
			return Disposable.Empty;
		}

		private void DrainStep(ConcurrentQueue<T> q)
		{
			if (Volatile.Read(ref _disposed))
			{
				Clear(q);
				return;
			}
			bool flag = Volatile.Read(ref _done);
			if (flag)
			{
				Exception error = _error;
				if (error != null)
				{
					Volatile.Write(ref _disposed, value: true);
					ForwardOnError(error);
					return;
				}
			}
			if (q.TryDequeue(out T result))
			{
				ForwardOnNext(result);
			}
			else if (flag)
			{
				Volatile.Write(ref _disposed, value: true);
				ForwardOnCompleted();
			}
		}
	}
	internal sealed class ObserveOnObserverLongRunning<TSource> : IdentitySink<TSource>
	{
		private readonly ISchedulerLongRunning _scheduler;

		private readonly ConcurrentQueue<TSource> _queue;

		private readonly object _suspendGuard;

		private long _wip;

		private bool _done;

		private Exception? _error;

		private bool _disposed;

		private int _runDrainOnce;

		private SingleAssignmentDisposableValue _drainTask;

		private static readonly Action<ObserveOnObserverLongRunning<TSource>, ICancelable> DrainLongRunning = delegate(ObserveOnObserverLongRunning<TSource> self, ICancelable cancelable)
		{
			self.Drain();
		};

		public ObserveOnObserverLongRunning(ISchedulerLongRunning scheduler, IObserver<TSource> observer)
			: base(observer)
		{
			_scheduler = scheduler;
			_queue = new ConcurrentQueue<TSource>();
			_suspendGuard = new object();
		}

		public override void OnCompleted()
		{
			Volatile.Write(ref _done, value: true);
			Schedule();
		}

		public override void OnError(Exception error)
		{
			_error = error;
			Volatile.Write(ref _done, value: true);
			Schedule();
		}

		public override void OnNext(TSource value)
		{
			_queue.Enqueue(value);
			Schedule();
		}

		private void Schedule()
		{
			if (Volatile.Read(ref _runDrainOnce) == 0 && Interlocked.CompareExchange(ref _runDrainOnce, 1, 0) == 0)
			{
				_drainTask.Disposable = _scheduler.ScheduleLongRunning(this, DrainLongRunning);
			}
			if (Interlocked.Increment(ref _wip) == 1)
			{
				lock (_suspendGuard)
				{
					Monitor.Pulse(_suspendGuard);
				}
			}
		}

		protected override void Dispose(bool disposing)
		{
			Volatile.Write(ref _disposed, value: true);
			lock (_suspendGuard)
			{
				Monitor.Pulse(_suspendGuard);
			}
			_drainTask.Dispose();
			base.Dispose(disposing);
		}

		private void Drain()
		{
			ConcurrentQueue<TSource> queue = _queue;
			while (true)
			{
				if (Volatile.Read(ref _disposed))
				{
					TSource result;
					while (queue.TryDequeue(out result))
					{
					}
					return;
				}
				bool num = Volatile.Read(ref _done);
				TSource result2;
				bool flag = queue.TryDequeue(out result2);
				if (num && !flag)
				{
					break;
				}
				if (flag)
				{
					ForwardOnNext(result2);
					if (Interlocked.Decrement(ref _wip) != 0L)
					{
						continue;
					}
				}
				if (Volatile.Read(ref _wip) != 0L || Volatile.Read(ref _disposed))
				{
					continue;
				}
				object suspendGuard = _suspendGuard;
				if (Monitor.TryEnter(suspendGuard))
				{
					if (Volatile.Read(ref _wip) == 0L && !Volatile.Read(ref _disposed))
					{
						Monitor.Wait(suspendGuard);
					}
					Monitor.Exit(suspendGuard);
				}
			}
			Exception error = _error;
			if (error != null)
			{
				ForwardOnError(error);
			}
			else
			{
				ForwardOnCompleted();
			}
		}
	}
	internal interface ISink<in TTarget>
	{
		void ForwardOnNext(TTarget value);

		void ForwardOnCompleted();

		void ForwardOnError(Exception error);
	}
	internal abstract class Sink<TTarget> : ISink<TTarget>, IDisposable
	{
		private SingleAssignmentDisposableValue _upstream;

		private volatile IObserver<TTarget> _observer;

		protected Sink(IObserver<TTarget> observer)
		{
			_observer = observer;
		}

		public void Dispose()
		{
			if (Interlocked.Exchange(ref _observer, NopObserver<TTarget>.Instance) != NopObserver<TTarget>.Instance)
			{
				Dispose(disposing: true);
			}
		}

		protected virtual void Dispose(bool disposing)
		{
			_upstream.Dispose();
		}

		public void ForwardOnNext(TTarget value)
		{
			_observer.OnNext(value);
		}

		public void ForwardOnCompleted()
		{
			_observer.OnCompleted();
			Dispose();
		}

		public void ForwardOnError(Exception error)
		{
			_observer.OnError(error);
			Dispose();
		}

		protected void SetUpstream(IDisposable upstream)
		{
			_upstream.Disposable = upstream;
		}

		protected void DisposeUpstream()
		{
			_upstream.Dispose();
		}
	}
	internal abstract class Sink<TSource, TTarget> : Sink<TTarget>, IObserver<TSource>
	{
		private sealed class @_ : IObserver<TTarget>
		{
			private readonly Sink<TSource, TTarget> _forward;

			public _(Sink<TSource, TTarget> forward)
			{
				_forward = forward;
			}

			public void OnNext(TTarget value)
			{
				_forward.ForwardOnNext(value);
			}

			public void OnError(Exception error)
			{
				_forward.ForwardOnError(error);
			}

			public void OnCompleted()
			{
				_forward.ForwardOnCompleted();
			}
		}

		protected Sink(IObserver<TTarget> observer)
			: base(observer)
		{
		}

		public virtual void Run(IObservable<TSource> source)
		{
			SetUpstream(source.SubscribeSafe(this));
		}

		public abstract void OnNext(TSource value);

		public virtual void OnError(Exception error)
		{
			ForwardOnError(error);
		}

		public virtual void OnCompleted()
		{
			ForwardOnCompleted();
		}

		public IObserver<TTarget> GetForwarder()
		{
			return new @_(this);
		}
	}
	internal static class Stubs<T>
	{
		public static readonly Action<T> Ignore = delegate
		{
		};

		public static readonly Func<T, T> I = (T _) => _;
	}
	internal static class Stubs
	{
		public static readonly Action Nop = delegate
		{
		};

		public static readonly Action<Exception> Throw = delegate(Exception ex)
		{
			ex.Throw();
		};
	}
	internal static class TimerStubs
	{
		public static readonly System.Threading.Timer Never = new System.Threading.Timer(delegate
		{
		});
	}
	internal sealed class SynchronizedObserver<T> : ObserverBase<T>
	{
		private readonly object _gate;

		private readonly IObserver<T> _observer;

		public SynchronizedObserver(IObserver<T> observer, object gate)
		{
			_gate = gate;
			_observer = observer;
		}

		protected override void OnNextCore(T value)
		{
			lock (_gate)
			{
				_observer.OnNext(value);
			}
		}

		protected override void OnErrorCore(Exception exception)
		{
			lock (_gate)
			{
				_observer.OnError(exception);
			}
		}

		protected override void OnCompletedCore()
		{
			lock (_gate)
			{
				_observer.OnCompleted();
			}
		}
	}
	internal abstract class TailRecursiveSink<TSource> : IdentitySink<TSource>
	{
		private readonly Stack<IEnumerator<IObservable<TSource>>> _stack = new Stack<IEnumerator<IObservable<TSource>>>();

		private bool _isDisposed;

		private int _trampoline;

		private IDisposable? _currentSubscription;

		protected TailRecursiveSink(IObserver<TSource> observer)
			: base(observer)
		{
		}

		public void Run(IEnumerable<IObservable<TSource>> sources)
		{
			if (TryGetEnumerator(sources, out IEnumerator<IObservable<TSource>> result))
			{
				_stack.Push(result);
				Drain();
			}
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				DisposeAll();
			}
			base.Dispose(disposing);
		}

		private void Drain()
		{
			if (Interlocked.Increment(ref _trampoline) != 1)
			{
				return;
			}
			do
			{
				IL_000f:
				if (Volatile.Read(ref _isDisposed))
				{
					while (_stack.Count != 0)
					{
						_stack.Pop().Dispose();
					}
					Disposable.Dispose(ref _currentSubscription);
				}
				else if (_stack.Count != 0)
				{
					IEnumerator<IObservable<TSource>> enumerator = _stack.Peek();
					IObservable<TSource> source2 = null;
					try
					{
						if (enumerator.MoveNext())
						{
							source2 = enumerator.Current;
						}
					}
					catch (Exception error)
					{
						enumerator.Dispose();
						ForwardOnError(error);
						Volatile.Write(ref _isDisposed, value: true);
						goto IL_000f;
					}
					IObservable<TSource> observable;
					try
					{
						observable = Unpack<TSource>(source2);
					}
					catch (Exception error2)
					{
						if (!Fail(error2))
						{
							Volatile.Write(ref _isDisposed, value: true);
						}
						goto IL_000f;
					}
					if (observable == null)
					{
						_stack.Pop();
						enumerator.Dispose();
						goto IL_000f;
					}
					IEnumerable<IObservable<TSource>> enumerable = Extract(observable);
					if (enumerable != null)
					{
						if (TryGetEnumerator(enumerable, out IEnumerator<IObservable<TSource>> result))
						{
							_stack.Push(result);
						}
						else
						{
							Volatile.Write(ref _isDisposed, value: true);
						}
						goto IL_000f;
					}
					IDisposable ready = ReadyToken.Ready;
					if (Disposable.TrySetSingle(ref _currentSubscription, ready) != 0)
					{
						goto IL_000f;
					}
					IDisposable disposable = observable.SubscribeSafe(this);
					IDisposable disposable2 = Interlocked.CompareExchange(ref _currentSubscription, disposable, ready);
					if (disposable2 != ready)
					{
						disposable.Dispose();
						if (disposable2 == BooleanDisposable.True)
						{
							goto IL_000f;
						}
					}
				}
				else
				{
					Volatile.Write(ref _isDisposed, value: true);
					Done();
				}
			}
			while (Interlocked.Decrement(ref _trampoline) != 0);
			static IObservable<T>? Unpack<T>(IObservable<T>? source) where T : notnull
			{
				bool flag;
				do
				{
					flag = false;
					if (source is IEvaluatableObservable<T> evaluatableObservable)
					{
						source = evaluatableObservable.Eval();
						flag = true;
					}
				}
				while (flag);
				return source;
			}
		}

		private void DisposeAll()
		{
			Volatile.Write(ref _isDisposed, value: true);
			Drain();
		}

		protected void Recurse()
		{
			if (Disposable.TrySetSerial(ref _currentSubscription, null))
			{
				Drain();
			}
		}

		protected abstract IEnumerable<IObservable<TSource>>? Extract(IObservable<TSource> source);

		private bool TryGetEnumerator(IEnumerable<IObservable<TSource>> sources, [NotNullWhen(true)] out IEnumerator<IObservable<TSource>>? result)
		{
			try
			{
				result = sources.GetEnumerator();
				return true;
			}
			catch (Exception error)
			{
				ForwardOnError(error);
				result = null;
				return false;
			}
		}

		protected virtual void Done()
		{
			ForwardOnCompleted();
		}

		protected virtual bool Fail(Exception error)
		{
			ForwardOnError(error);
			return false;
		}
	}
	internal static class ReadyToken
	{
		private sealed class ReadyDisposable : IDisposable
		{
			public void Dispose()
			{
			}
		}

		internal static readonly IDisposable Ready = new ReadyDisposable();
	}
	public interface IObserver<in TValue, out TResult>
	{
		TResult OnNext(TValue value);

		TResult OnError(Exception exception);

		TResult OnCompleted();
	}
	[Experimental]
	public class ListObservable<T> : IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable, IObservable<object>
	{
		private readonly IDisposable _subscription;

		private readonly AsyncSubject<object> _subject = new AsyncSubject<object>();

		private readonly List<T> _results = new List<T>();

		public T Value
		{
			get
			{
				Wait();
				if (_results.Count == 0)
				{
					throw new InvalidOperationException(Strings_Linq.NO_ELEMENTS);
				}
				return _results[_results.Count - 1];
			}
		}

		public T this[int index]
		{
			get
			{
				Wait();
				return _results[index];
			}
			set
			{
				Wait();
				_results[index] = value;
			}
		}

		public int Count
		{
			get
			{
				Wait();
				return _results.Count;
			}
		}

		public bool IsReadOnly => false;

		public ListObservable(IObservable<T> source)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			_subscription = source.Subscribe(_results.Add, _subject.OnError, _subject.OnCompleted);
		}

		private void Wait()
		{
			_subject.DefaultIfEmpty().Wait();
		}

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

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

		public void RemoveAt(int index)
		{
			Wait();
			_results.RemoveAt(index);
		}

		public void Add(T item)
		{
			Wait();
			_results.Add(item);
		}

		public void Clear()
		{
			Wait();
			_results.Clear();
		}

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

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

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

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

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

		public IDisposable Subscribe(IObserver<object> observer)
		{
			if (observer == null)
			{
				throw new ArgumentNullException("observer");
			}
			return StableCompositeDisposable.Create(_subscription, _subject.Subscribe(observer));
		}
	}
	[CompilerGenerated]
	internal class NamespaceDoc
	{
	}
	public enum NotificationKind
	{
		OnNext,
		OnError,
		OnCompleted
	}
	[Serializable]
	public abstract class Notification<T> : IEquatable<Notification<T>>
	{
		[Serializable]
		[DebuggerDisplay("OnNext({Value})")]
		internal sealed class OnNextNotification : Notification<T>
		{
			public override T Value { get; }

			public override Exception? Exception => null;

			public override bool HasValue => true;

			public override NotificationKind Kind => NotificationKind.OnNext;

			public OnNextNotification(T value)
			{
				Value = value;
			}

			public override int GetHashCode()
			{
				T value = Value;
				if (value == null)
				{
					return 0;
				}
				return value.GetHashCode();
			}

			public override bool Equals(Notification<T>? other)
			{
				if ((object)this == other)
				{
					return true;
				}
				if ((object)other == null)
				{
					return false;
				}
				if (other.Kind != 0)
				{
					return false;
				}
				return EqualityComparer<T>.Default.Equals(Value, other.Value);
			}

			public override string ToString()
			{
				return string.Format(CultureInfo.CurrentCulture, "OnNext({0})", Value);
			}

			public override void Accept(IObserver<T> observer)
			{
				if (observer == null)
				{
					throw new ArgumentNullException("observer");
				}
				observer.OnNext(Value);
			}

			public override TResult Accept<TResult>(IObserver<T, TResult> observer)
			{
				if (observer == null)
				{
					throw new ArgumentNullException("observer");
				}
				return observer.OnNext(Value);
			}

			public override void Accept(Action<T> onNext, Action<Exception> onError, Action onCompleted)
			{
				if (onNext == null)
				{
					throw new ArgumentNullException("onNext");
				}
				if (onError == null)
				{
					throw new ArgumentNullException("onError");
				}
				if (onCompleted == null)
				{
					throw new ArgumentNullException("onCompleted");
				}
				onNext(Value);
			}

			public override TResult Accept<TResult>(Func<T, TResult> onNext, Func<Exception, TResult> onError, Func<TResult> onCompleted)
			{
				if (onNext == null)
				{
					throw new ArgumentNullException("onNext");
				}
				if (onError == null)
				{
					throw new ArgumentNullException("onError");
				}
				if (onCompleted == null)
				{
					throw new ArgumentNullException("onCompleted");
				}
				return onNext(Value);
			}
		}

		[Serializable]
		[DebuggerDisplay("OnError({Exception})")]
		internal sealed class OnErrorNotification : Notification<T>
		{
			public override T Value
			{
				get
				{
					Exception.Throw();
					return default(T);
				}
			}

			public override Exception Exception { get; }

			public override bool HasValue => false;

			public override NotificationKind Kind => NotificationKind.OnError;

			public OnErrorNotification(Exception exception)
			{
				Exception = exception;
			}

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

			public override bool Equals(Notification<T>? other)
			{
				if ((object)this == other)
				{
					return true;
				}
				if ((object)other == null)
				{
					return false;
				}
				if (other.Kind != NotificationKind.OnError)
				{
					return false;
				}
				return object.Equals(Exception, other.Exception);
			}

			public override string ToString()
			{
				return string.Format(CultureInfo.CurrentCulture, "OnError({0})", Exception.GetType().FullName);
			}

			public override void Accept(IObserver<T> observer)
			{
				if (observer == null)
				{
					throw new ArgumentNullException("observer");
				}
				observer.OnError(Exception);
			}

			public override TResult Accept<TResult>(IObserver<T, TResult> observer)
			{
				if (observer == null)
				{
					throw new ArgumentNullException("observer");
				}
				return observer.OnError(Exception);
			}

			public override void Accept(Action<T> onNext, Action<Exception> onError, Action onCompleted)
			{
				if (onNext == null)
				{
					throw new ArgumentNullException("onNext");
				}
				if (onError == null)
				{
					throw new ArgumentNullException("onError");
				}
				if (onCompleted == null)
				{
					throw new ArgumentNullException("onCompleted");
				}
				onError(Exception);
			}

			public override TResult Accept<TResult>(Func<T, TResult> onNext, Func<Exception, TResult> onError, Func<TResult> onCompleted)
			{
				if (onNext == null)
				{
					throw new ArgumentNullException("onNext");
				}
				if (onError == null)
				{
					throw new ArgumentNullException("onError");
				}
				if (onCompleted == null)
				{
					throw new ArgumentNullException("onCompleted");
				}
				return onError(Exception);
			}
		}

		[Serializable]
		[DebuggerDisplay("OnCompleted()")]
		internal sealed class OnCompletedNotification : Notification<T>
		{
			internal static readonly Notification<T> Instance = new Notification<T>.OnCompletedNotification();

			public override T Value
			{
				get
				{
					throw new InvalidOperationException(Strings_Core.COMPLETED_NO_VALUE);
				}
			}

			public override Exception? Exception => null;

			public override bool HasValue => false;

			public override NotificationKind Kind => NotificationKind.OnCompleted;

			private OnCompletedNotification()
			{
			}

			public override int GetHashCode()
			{
				return typeof(T).GetHashCode() ^ 0x213E;
			}

			public override bool Equals(Notification<T>? other)
			{
				if ((object)this == other)
				{
					return true;
				}
				if ((object)other == null)
				{
					return false;
				}
				return other.Kind == NotificationKind.OnCompleted;
			}

			public override string ToString()
			{
				return "OnCompleted()";
			}

			public override void Accept(IObserver<T> observer)
			{
				if (observer == null)
				{
					throw new ArgumentNullException("observer");
				}
				observer.OnCompleted();
			}

			public override TResult Accept<TResult>(IObserver<T, TResult> observer)
			{
				if (observer == null)
				{
					throw new ArgumentNullException("observer");
				}
				return observer.OnCompleted();
			}

			public override void Accept(Action<T> onNext, Action<Exception> onError, Action onCompleted)
			{
				if (onNext == null)
				{
					throw new ArgumentNullException("onNext");
				}
				if (onError == null)
				{
					throw new ArgumentNullException("onError");
				}
				if (onCompleted == null)
				{
					throw new ArgumentNullException("onCompleted");
				}
				onCompleted();
			}

			public override TResult Accept<TResult>(Func<T, TResult> onNext, Func<Exception, TResult> onError, Func<TResult> onCompleted)
			{
				if (onNext == null)
				{
					throw new ArgumentNullException("onNext");
				}
				if (onError == null)
				{
					throw new ArgumentNullException("onError");
				}
				if (onCompleted == null)
				{
					throw new ArgumentNullException("onCompleted");
				}
				return onCompleted();
			}
		}

		private sealed class NotificationToObservable : ObservableBase<T>
		{
			private readonly IScheduler _scheduler;

			private readonly Notification<T> _parent;

			public NotificationToObservable(IScheduler scheduler, Notification<T> parent)
			{
				_scheduler = scheduler;
				_parent = parent;
			}

			protected override IDisposable SubscribeCore(IObserver<T> observer)
			{
				return _scheduler.ScheduleAction((_parent, observer), delegate((Notification<T> _parent, IObserver<T> observer) state)
				{
					var (notification, observer2) = state;
					notification.Accept(observer2);
					if (notification.Kind == NotificationKind.OnNext)
					{
						observer2.OnCompleted();
					}
				});
			}
		}

		public abstract T Value { get; }

		public abstract bool HasValue { get; }

		public abstract Exception? Exception { get; }

		public abstract NotificationKind Kind { get; }

		protected internal Notification()
		{
		}

		public abstract bool Equals(Notification<T>? other);

		public static bool operator ==(Notification<T> left, Notification<T> right)
		{
			if ((object)left == right)
			{
				return true;
			}
			if ((object)left == null || (object)right == null)
			{
				return false;
			}
			return left.Equals(right);
		}

		public static bool operator !=(Notification<T> left, Notification<T> right)
		{
			return !(left == right);
		}

		public override bool Equals(object? obj)
		{
			return Equals(obj as Notification<T>);
		}

		public abstract void Accept(IObserver<T> observer);

		public abstract TResult Accept<TResult>(IObserver<T, TResult> observer);

		public abstract void Accept(Action<T> onNext, Action<Exception> onError, Action onCompleted);

		public abstract TResult Accept<TResult>(Func<T, TResult> onNext, Func<Exception, TResult> onError, Func<TResult> onCompleted);

		public IObservable<T> ToObservable()
		{
			return ToObservable(ImmediateScheduler.Instance);
		}

		public IObservable<T> ToObservable(IScheduler scheduler)
		{
			if (scheduler == null)
			{
				throw new ArgumentNullException("scheduler");
			}
			return new NotificationToObservable(scheduler, this);
		}
	}
	public static class Notification
	{
		public static Notification<T> CreateOnNext<T>(T value)
		{
			return new Notification<T>.OnNextNotification(value);
		}

		public static Notification<T> CreateOnError<T>(Exception error)
		{
			if (error == null)
			{
				throw new ArgumentNullException("error");
			}
			return new Notification<T>.OnErrorNotification(error);
		}

		public static Notification<T> CreateOnCompleted<T>()
		{
			return Notification<T>.OnCompletedNotification.Instance;
		}
	}
	public abstract class ObservableBase<T> : IObservable<T>
	{
		public IDisposable Subscribe(IObserver<T> observer)
		{
			if (observer == null)
			{
				throw new ArgumentNullException("observer");
			}
			AutoDetachObserver<T> autoDetachObserver = new AutoDetachObserver<T>(observer);
			if (CurrentThreadScheduler.IsScheduleRequired)
			{
				((IScheduler)CurrentThreadScheduler.Instance).ScheduleAction(autoDetachObserver, (Action<AutoDetachObserver<T>>)ScheduledSubscribe);
			}
			else
			{
				try
				{
					autoDetachObserver.SetResource(SubscribeCore(autoDetachObserver));
				}
				catch (Exception error)
				{
					if (!autoDetachObserver.Fail(error))
					{
						throw;
					}
				}
			}
			return autoDetachObserver;
		}

		private void ScheduledSubscribe(AutoDetachObserver<T> autoDetachObserver)
		{
			try
			{
				autoDetachObserver.SetResource(SubscribeCore(autoDetachObserver));
			}
			catch (Exception error)
			{
				if (!autoDetachObserver.Fail(error))
				{
					throw;
				}
			}
		}

		protected abstract IDisposable SubscribeCore(IObserver<T> observer);
	}
	internal class ObservableQueryProvider : IQbservableProvider, IQueryProvider
	{
		private static MethodInfo? _staticAsQueryable;

		private static MethodInfo AsQueryable => _staticAsQueryable ?? (_staticAsQueryable = Qbservable.InfoOf((Expression<Func<object>>)(() => ((IEnumerable<object>)null).AsQueryable())).GetGenericMethodDefinition());

		public IQbservable<TResult> CreateQuery<TResult>(Expression expression)
		{
			if (expression == null)
			{
				throw new ArgumentNullException("expression");
			}
			if (!typeof(IObservable<TResult>).IsAssignableFrom(expression.Type))
			{
				throw new ArgumentException(Strings_Providers.INVALID_TREE_TYPE, "expression");
			}
			return new ObservableQuery<TResult>(expression);
		}

		IQueryable<TElement> IQueryProvider.CreateQuery<TElement>(Expression expression)
		{
			if (!(expression is MethodCallExpression methodCallExpression) || methodCallExpression.Method.DeclaringType != typeof(Qbservable) || methodCallExpression.Method.Name != "ToQueryable")
			{
				throw new ArgumentException(Strings_Providers.EXPECTED_TOQUERYABLE_METHODCALL, "expression");
			}
			Expression arg = methodCallExpression.Arguments[0];
			return Expression.Lambda<Func<IQueryable<TElement>>>(Expression.Call(AsQueryable.MakeGenericMethod(typeof(TElement)), Expression.Call(typeof(Observable).GetMethod("ToEnumerable").MakeGenericMethod(typeof(TElement)), arg)), Array.Empty<ParameterExpression>()).Compile()();
		}

		IQueryable IQueryProvider.CreateQuery(Expression expression)
		{
			throw new NotImplementedException();
		}

		TResult IQueryProvider.Execute<TResult>(Expression expression)
		{
			throw new NotImplementedException();
		}

		object IQueryProvider.Execute(Expression expression)
		{
			throw new NotImplementedException();
		}
	}
	internal class ObservableQuery
	{
		protected object? _source;

		protected Expression _expression;

		public object? Source => _source;

		public Expression Expression => _expression;

		public ObservableQuery(object source)
		{
			_source = source;
			_expression = System.Linq.Expressions.Expression.Constant(this);
		}

		public ObservableQuery(Expression expression)
		{
			_expression = expression;
		}
	}
	internal class ObservableQuery<TSource> : ObservableQuery, IQbservable<TSource>, IQbservable, IObservable<TSource>
	{
		private class ObservableRewriter : ExpressionVisitor
		{
			private class Lazy<T>
			{
				private readonly Func<T> _factory;

				private T? _value;

				private bool _initialized;

				public T Value
				{
					get
					{
						lock (_factory)
						{
							if (!_initialized)
							{
								_value = _factory();
								_initialized = true;
							}
						}
						return _value;
					}
				}

				public Lazy(Func<T> factory)
				{
					_factory = factory;
				}
			}

			private static readonly Lazy<ILookup<string, MethodInfo>> ObservableMethods = new Lazy<ILookup<string, MethodInfo>>(() => GetMethods(typeof(Observable)));

			protected override Expression VisitConstant(ConstantExpression node)
			{
				if (node.Value is ObservableQuery observableQuery)
				{
					object source = observableQuery.Source;
					if (source != null)
					{
						return System.Linq.Expressions.Expression.Constant(source);
					}
					return Visit(observableQuery.Expression);
				}
				return node;
			}

			protected override Expression VisitMethodCall(MethodCallExpression node)
			{
				MethodInfo method = node.Method;
				if (method.DeclaringType?.BaseType == typeof(QueryablePattern))
				{
					if (method.Name == "Then")
					{
						return System.Linq.Expressions.Expression.Call(Visit(node.Object), arguments: node.Arguments.Select((Expression arg) => Unquote(Visit(arg))).ToArray(), methodName: method.Name, typeArguments: method.GetGenericArguments());
					}
					if (method.Name == "And")
					{
						return System.Linq.Expressions.Expression.Call(Visit(node.Object), arguments: node.Arguments.Select((Expression arg) => Visit(arg)).ToArray(), methodName: method.Name, typeArguments: method.GetGenericArguments());
					}
				}
				else
				{
					IEnumerable<Expression> enumerable = node.Arguments.AsEnumerable();
					bool flag = false;
					ParameterInfo parameterInfo = method.GetParameters().FirstOrDefault();
					if (parameterInfo != null)
					{
						Type parameterType = parameterInfo.ParameterType;
						if (parameterType == typeof(IQbservableProvider))
						{
							flag = true;
							if (!(System.Linq.Expressions.Expression.Lambda<Func<IQbservableProvider>>(Visit(node.Arguments[0]), Array.Empty<ParameterExpression>()).Compile()() is ObservableQueryProvider))
							{
								return node;
							}
							enumerable = enumerable.Skip(1);
						}
						else if (typeof(IQbservable).IsAssignableFrom(parameterType))
						{
							flag = true;
						}
					}
					if (flag)
					{
						IList<Expression> arguments3 = VisitQbservableOperatorArguments(method, enumerable);
						return FindObservableMethod(method, arguments3);
					}
				}
				return base.VisitMethodCall(node);
			}

			protected override Expression VisitLambda<T>(Expression<T> node)
			{
				return node;
			}

			private IList<Expression> VisitQbservableOperatorArguments(MethodInfo method, IEnumerable<Expression> arguments)
			{
				if (method.Name == "When")
				{
					Expression expression = arguments.Last();
					if (expression.NodeType == ExpressionType.NewArrayInit)
					{
						NewArrayExpression newArrayExpression = (NewArrayExpression)expression;
						List<Expression> list = new List<Expression>();
						list.Add(System.Linq.Expressions.Expression.NewArrayInit(typeof(Plan<>).MakeGenericType(method.GetGenericArguments()[0]), newArrayExpression.Expressions.Select((Expression param) => Visit(param))));
						return list;
					}
				}
				return arguments.Select((Expression arg) => Visit(arg)).ToList();
			}

			private static MethodCallExpression FindObservableMethod(MethodInfo method, IList<Expression> arguments)
			{
				IList<Expression> arguments2 = arguments;
				Type type;
				ILookup<string, MethodInfo> lookup;
				if (method.DeclaringType == typeof(Qbservable))
				{
					type = typeof(Observable);
					lookup = ObservableMethods.Value;
				}
				else
				{
					type = method.DeclaringType;
					if (type.IsDefined(typeof(LocalQueryMethodImplementationTypeAttribute), inherit: false))
					{
						type = ((LocalQueryMethodImplementationTypeAttribute)type.GetCustomAttributes(typeof(LocalQueryMethodImplementationTypeAttribute), inherit: false)[0]).TargetType;
					}
					lookup = GetMethods(type);
				}
				Type[] typeArgs = (method.IsGenericMethod ? method.GetGenericArguments() : null);
				MethodInfo methodInfo = lookup[method.Name].FirstOrDefault((MethodInfo candidateMethod) => ArgsMatch(candidateMethod, arguments2, typeArgs)) ?? throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings_Providers.NO_MATCHING_METHOD_FOUND, method.Name, type.Name));
				if (typeArgs != null)
				{
					methodInfo = methodInfo.MakeGenericMethod(typeArgs);
				}
				ParameterInfo[] parameters = methodInfo.GetParameters();
				int i = 0;
				for (int num = parameters.Length; i < num; i++)
				{
					arguments2[i] = Unquote(arguments2[i]);
				}
				return System.Linq.Expressions.Expression.Call(null, methodInfo, arguments2);
			}

			private static ILookup<string, MethodInfo> GetMethods(Type type)
			{
				return type.GetTypeInfo().DeclaredMethods.Where((MethodInfo m) => m.IsStatic && m.IsPublic).ToLookup((MethodInfo m) => m.Name);
			}

			private static bool ArgsMatch(MethodInfo method, IList<Expression> arguments, Type[]? typeArgs)
			{
				ParameterInfo[] parameters = method.GetParameters();
				if (parameters.Length != arguments.Count)
				{
					return false;
				}
				if (!method.IsGenericMethod && typeArgs != null && typeArgs.Length != 0)
				{
					return false;
				}
				if (method.IsGenericMethodDefinition)
				{
					if (typeArgs == null)
					{
						return false;
					}
					if (method.GetGenericArguments().Length != typeArgs.Length)
					{
						return false;
					}
					parameters = method.MakeGenericMethod(typeArgs).GetParameters();
				}
				int i = 0;
				for (int count = arguments.Count; i < count; i++)
				{
					Type parameterType = parameters[i].ParameterType;
					Expression expression = arguments[i];
					if (!parameterType.IsAssignableFrom(expression.Type))
					{
						expression = Unquote(expression);
						if (!parameterType.IsAssignableFrom(expression.Type))
						{
							return false;
						}
					}
				}
				return true;
			}

			private static Expression Unquote(Expression expression)
			{
				while (expression.NodeType == ExpressionType.Quote)
				{
					expression = ((UnaryExpression)expression).Operand;
				}
				return expression;
			}
		}

		public Type ElementType => typeof(TSource);

		public IQbservableProvider Provider => Qbservable.Provider;

		internal ObservableQuery(IObservable<TSource> source)
			: base(source)
		{
		}

		internal ObservableQuery(Expression expression)
			: base(expression)
		{
		}

		public IDisposable Subscribe(IObserver<TSource> observer)
		{
			if (_source == null)
			{
				Expression<Func<IObservable<TSource>>> expression = System.Linq.Expressions.Expression.Lambda<Func<IObservable<TSource>>>(new ObservableRewriter().Visit(_expression), Array.Empty<ParameterExpression>());
				_source = expression.Compile()();
			}
			return ((IObservable<TSource>)_source).Subscribe(observer);
		}

		public override string? ToString()
		{
			if (_expression is ConstantExpression constantExpression && constantExpression.Value == this)
			{
				if (_source != null)
				{
					return _source.ToString();
				}
				return "null";
			}
			return _expression.ToString();
		}
	}
	public static class Observer
	{
		private class AnonymousProgress<T> : IProgress<T>
		{
			private readonly Action<T> _progress;

			public AnonymousProgress(Action<T> progress)
			{
				_progress = progress;
			}

			public void Report(T value)
			{
				_progress(value);
			}
		}

		public static IObserver<T> ToObserver<T>(this Action<Notification<T>> handler)
		{
			Action<Notification<T>> handler2 = handler;
			if (handler2 == null)
			{
				throw new ArgumentNullException("handler");
			}
			return new AnonymousObserver<T>(delegate(T x)
			{
				handler2(Notification.CreateOnNext(x));
			}, delegate(Exception exception)
			{
				handler2(Notification.CreateOnError<T>(exception));
			}, delegate
			{
				handler2(Notification.CreateOnCompleted<T>());
			});
		}

		public static Action<Notification<T>> ToNotifier<T>(this IObserver<T> observer)
		{
			IObserver<T> observer2 = observer;
			if (observer2 == null)
			{
				throw new ArgumentNullException("observer");
			}
			return delegate(Notification<T> n)
			{
				n.Accept(observer2);
			};
		}

		public static IObserver<T> Create<T>(Action<T> onNext)
		{
			if (onNext == null)
			{
				throw new ArgumentNullException("onNext");
			}
			return new AnonymousObserver<T>(onNext);
		}

		public static IObserver<T> Create<T>(Action<T> onNext, Action<Exception> onError)
		{
			if (onNext == null)
			{
				throw new ArgumentNullException("onNext");
			}
			if (onError == null)
			{
				throw new ArgumentNullException("onError");
			}
			return new AnonymousObserver<T>(onNext, onError);
		}

		public static IObserver<T> Create<T>(Action<T> onNext, Action onCompleted)
		{
			if (onNext == null)
			{
				throw new ArgumentNullException("onNext");
			}
			if (onCompleted == null)
			{
				throw new ArgumentNullException("onCompleted");
			}
			return new AnonymousObserver<T>(onNext, onCompleted);
		}

		public static IObserver<T> Create<T>(Action<T> onNext, Action<Exception> onError, Action onCompleted)
		{
			if (onNext == null)
			{
				throw new ArgumentNullException("onNext");
			}
			if (onError == null)
			{
				throw new ArgumentNullException("onError");
			}
			if (onCompleted == null)
			{
				throw new ArgumentNullException("onCompleted");
			}
			return new AnonymousObserver<T>(onNext, onError, onCompleted);
		}

		public static IObserver<T> AsObserver<T>(this IObserver<T> observer)
		{
			if (observer == null)
			{
				throw new ArgumentNullException("observer");
			}
			return new AnonymousObserver<T>(observer.OnNext, observer.OnError, observer.OnCompleted);
		}

		public static IObserver<T> Checked<T>(this IObserver<T> observer)
		{
			if (observer == null)
			{
				throw new ArgumentNullException("observer");
			}
			return new CheckedObserver<T>(observer);
		}

		public static IObserver<T> Synchronize<T>(IObserver<T> observer)
		{
			if (observer == null)
			{
				throw new ArgumentNullException("observer");
			}
			return new SynchronizedObserver<T>(observer, new object());
		}

		public static IObserver<T> Synchronize<T>(IObserver<T> observer, bool preventReentrancy)
		{
			if (observer == null)
			{
				throw new ArgumentNullException("observer");
			}
			if (preventReentrancy)
			{
				return new AsyncLockObserver<T>(observer, new AsyncLock());
			}
			return new SynchronizedObserver<T>(observer, new object());
		}

		public static IObserver<T> Synchronize<T>(IObserve

Mods/RealRadio/System.Runtime.CompilerServices.Unsafe.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using Microsoft.CodeAnalysis;

[assembly: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: CLSCompliant(false)]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyDescription("System.Runtime.CompilerServices.Unsafe")]
[assembly: AssemblyFileVersion("6.0.21.52210")]
[assembly: AssemblyInformationalVersion("6.0.0")]
[assembly: AssemblyTitle("System.Runtime.CompilerServices.Unsafe")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyMetadata("IsTrimmable", "True")]
[assembly: AssemblyCopyright("© Microsoft Corporation.  All rights reserved.")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyVersion("6.0.0.0")]
namespace System.Runtime.CompilerServices
{
	public static class Unsafe
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static T Read<T>(void* source)
		{
			return Unsafe.Read<T>(source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static T ReadUnaligned<T>(void* source)
		{
			return Unsafe.ReadUnaligned<T>(source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static T ReadUnaligned<T>(ref byte source)
		{
			return Unsafe.ReadUnaligned<T>(ref source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void Write<T>(void* destination, T value)
		{
			Unsafe.Write(destination, value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void WriteUnaligned<T>(void* destination, T value)
		{
			Unsafe.WriteUnaligned(destination, value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void WriteUnaligned<T>(ref byte destination, T value)
		{
			Unsafe.WriteUnaligned(ref destination, value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void Copy<T>(void* destination, ref T source)
		{
			Unsafe.Write(destination, source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void Copy<T>(ref T destination, void* source)
		{
			destination = Unsafe.Read<T>(source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void* AsPointer<T>(ref T value)
		{
			return Unsafe.AsPointer(ref value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void SkipInit<T>(out T value)
		{
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static int SizeOf<T>()
		{
			return Unsafe.SizeOf<T>();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void CopyBlock(void* destination, void* source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlock(destination, source, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void CopyBlock(ref byte destination, ref byte source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlock(ref destination, ref source, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void CopyBlockUnaligned(void* destination, void* source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlockUnaligned(destination, source, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void CopyBlockUnaligned(ref byte destination, ref byte source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlockUnaligned(ref destination, ref source, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void InitBlock(void* startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlock(startAddress, value, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void InitBlock(ref byte startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlock(ref startAddress, value, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void InitBlockUnaligned(void* startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlockUnaligned(startAddress, value, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void InitBlockUnaligned(ref byte startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlockUnaligned(ref startAddress, value, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static T As<T>(object o) where T : class
		{
			return (T)o;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static ref T AsRef<T>(void* source)
		{
			return ref *(T*)source;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T AsRef<T>(in T source)
		{
			return ref source;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref TTo As<TFrom, TTo>(ref TFrom source)
		{
			return ref Unsafe.As<TFrom, TTo>(ref source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Unbox<T>(object box) where T : struct
		{
			return ref (T)box;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Add<T>(ref T source, int elementOffset)
		{
			return ref Unsafe.Add(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void* Add<T>(void* source, int elementOffset)
		{
			return (byte*)source + (nint)elementOffset * (nint)Unsafe.SizeOf<T>();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Add<T>(ref T source, IntPtr elementOffset)
		{
			return ref Unsafe.Add(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ref T Add<T>(ref T source, [System.Runtime.Versioning.NonVersionable] nuint elementOffset)
		{
			return ref Unsafe.Add(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T AddByteOffset<T>(ref T source, IntPtr byteOffset)
		{
			return ref Unsafe.AddByteOffset(ref source, byteOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ref T AddByteOffset<T>(ref T source, [System.Runtime.Versioning.NonVersionable] nuint byteOffset)
		{
			return ref Unsafe.AddByteOffset(ref source, byteOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Subtract<T>(ref T source, int elementOffset)
		{
			return ref Unsafe.Subtract(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void* Subtract<T>(void* source, int elementOffset)
		{
			return (byte*)source - (nint)elementOffset * (nint)Unsafe.SizeOf<T>();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Subtract<T>(ref T source, IntPtr elementOffset)
		{
			return ref Unsafe.Subtract(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ref T Subtract<T>(ref T source, [System.Runtime.Versioning.NonVersionable] nuint elementOffset)
		{
			return ref Unsafe.Subtract(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T SubtractByteOffset<T>(ref T source, IntPtr byteOffset)
		{
			return ref Unsafe.SubtractByteOffset(ref source, byteOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ref T SubtractByteOffset<T>(ref T source, [System.Runtime.Versioning.NonVersionable] nuint byteOffset)
		{
			return ref Unsafe.SubtractByteOffset(ref source, byteOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static IntPtr ByteOffset<T>(ref T origin, ref T target)
		{
			return Unsafe.ByteOffset(target: ref target, origin: ref origin);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static bool AreSame<T>(ref T left, ref T right)
		{
			return Unsafe.AreSame(ref left, ref right);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static bool IsAddressGreaterThan<T>(ref T left, ref T right)
		{
			return Unsafe.IsAddressGreaterThan(ref left, ref right);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static bool IsAddressLessThan<T>(ref T left, ref T right)
		{
			return Unsafe.IsAddressLessThan(ref left, ref right);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static bool IsNullRef<T>(ref T source)
		{
			return Unsafe.AsPointer(ref source) == null;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static ref T NullRef<T>()
		{
			return ref *(T*)null;
		}
	}
}
namespace System.Runtime.Versioning
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
	internal sealed class NonVersionableAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	[Microsoft.CodeAnalysis.Embedded]
	[CompilerGenerated]
	internal sealed class NativeIntegerAttribute : Attribute
	{
		public readonly bool[] TransformFlags;

		public NativeIntegerAttribute()
		{
			TransformFlags = new bool[1] { true };
		}

		public NativeIntegerAttribute(bool[] A_0)
		{
			TransformFlags = A_0;
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}

Mods/RealRadio/System.Text.Encoding.CodePages.dll

Decompiled a day ago
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using FxResources.System.Text.Encoding.CodePages;
using Microsoft.CodeAnalysis;
using Microsoft.Win32.SafeHandles;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: AssemblyDefaultAlias("System.Text.Encoding.CodePages")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata("IsTrimmable", "True")]
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyDescription("Provides support for code-page based encodings, including Windows-1252, Shift-JIS, and GB2312.\r\n\r\nCommonly Used Types:\r\nSystem.Text.CodePagesEncodingProvider")]
[assembly: AssemblyFileVersion("8.0.23.53103")]
[assembly: AssemblyInformationalVersion("8.0.0+5535e31a712343a63f5d7d796cd874e563e5ac14")]
[assembly: AssemblyProduct("Microsoft® .NET")]
[assembly: AssemblyTitle("System.Text.Encoding.CodePages")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/dotnet/runtime")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("8.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: System.Runtime.CompilerServices.NullablePublicOnly(false)]
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 NullablePublicOnlyAttribute : Attribute
	{
		public readonly bool IncludesInternals;

		public NullablePublicOnlyAttribute(bool P_0)
		{
			IncludesInternals = 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 FxResources.System.Text.Encoding.CodePages
{
	internal static class SR
	{
	}
}
namespace System
{
	internal static class SR
	{
		private static readonly bool s_usingResourceKeys = AppContext.TryGetSwitch("System.Resources.UseSystemResourceKeys", out var isEnabled) && isEnabled;

		private static ResourceManager s_resourceManager;

		internal static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(typeof(SR)));

		internal static string ArgumentOutOfRange_NeedNonNegNum => GetResourceString("ArgumentOutOfRange_NeedNonNegNum");

		internal static string ArgumentOutOfRange_IndexCount => GetResourceString("ArgumentOutOfRange_IndexCount");

		internal static string ArgumentOutOfRange_IndexCountBuffer => GetResourceString("ArgumentOutOfRange_IndexCountBuffer");

		internal static string NotSupported_NoCodepageData => GetResourceString("NotSupported_NoCodepageData");

		internal static string Argument_EncodingConversionOverflowBytes => GetResourceString("Argument_EncodingConversionOverflowBytes");

		internal static string Argument_InvalidCharSequenceNoIndex => GetResourceString("Argument_InvalidCharSequenceNoIndex");

		internal static string ArgumentOutOfRange_GetByteCountOverflow => GetResourceString("ArgumentOutOfRange_GetByteCountOverflow");

		internal static string Argument_EncodingConversionOverflowChars => GetResourceString("Argument_EncodingConversionOverflowChars");

		internal static string ArgumentOutOfRange_GetCharCountOverflow => GetResourceString("ArgumentOutOfRange_GetCharCountOverflow");

		internal static string Argument_EncoderFallbackNotEmpty => GetResourceString("Argument_EncoderFallbackNotEmpty");

		internal static string Argument_RecursiveFallback => GetResourceString("Argument_RecursiveFallback");

		internal static string Argument_RecursiveFallbackBytes => GetResourceString("Argument_RecursiveFallbackBytes");

		internal static string ArgumentOutOfRange_Range => GetResourceString("ArgumentOutOfRange_Range");

		internal static string Argument_CodepageNotSupported => GetResourceString("Argument_CodepageNotSupported");

		internal static string ArgumentOutOfRange_IndexMustBeLess => GetResourceString("ArgumentOutOfRange_IndexMustBeLess");

		internal static string ArgumentOutOfRange_IndexMustBeLessOrEqual => GetResourceString("ArgumentOutOfRange_IndexMustBeLessOrEqual");

		internal static string MissingEncodingNameResource => GetResourceString("MissingEncodingNameResource");

		internal static string Globalization_cp_37 => GetResourceString("Globalization_cp_37");

		internal static string Globalization_cp_437 => GetResourceString("Globalization_cp_437");

		internal static string Globalization_cp_500 => GetResourceString("Globalization_cp_500");

		internal static string Globalization_cp_708 => GetResourceString("Globalization_cp_708");

		internal static string Globalization_cp_720 => GetResourceString("Globalization_cp_720");

		internal static string Globalization_cp_737 => GetResourceString("Globalization_cp_737");

		internal static string Globalization_cp_775 => GetResourceString("Globalization_cp_775");

		internal static string Globalization_cp_850 => GetResourceString("Globalization_cp_850");

		internal static string Globalization_cp_852 => GetResourceString("Globalization_cp_852");

		internal static string Globalization_cp_855 => GetResourceString("Globalization_cp_855");

		internal static string Globalization_cp_857 => GetResourceString("Globalization_cp_857");

		internal static string Globalization_cp_858 => GetResourceString("Globalization_cp_858");

		internal static string Globalization_cp_860 => GetResourceString("Globalization_cp_860");

		internal static string Globalization_cp_861 => GetResourceString("Globalization_cp_861");

		internal static string Globalization_cp_862 => GetResourceString("Globalization_cp_862");

		internal static string Globalization_cp_863 => GetResourceString("Globalization_cp_863");

		internal static string Globalization_cp_864 => GetResourceString("Globalization_cp_864");

		internal static string Globalization_cp_865 => GetResourceString("Globalization_cp_865");

		internal static string Globalization_cp_866 => GetResourceString("Globalization_cp_866");

		internal static string Globalization_cp_869 => GetResourceString("Globalization_cp_869");

		internal static string Globalization_cp_870 => GetResourceString("Globalization_cp_870");

		internal static string Globalization_cp_874 => GetResourceString("Globalization_cp_874");

		internal static string Globalization_cp_875 => GetResourceString("Globalization_cp_875");

		internal static string Globalization_cp_932 => GetResourceString("Globalization_cp_932");

		internal static string Globalization_cp_936 => GetResourceString("Globalization_cp_936");

		internal static string Globalization_cp_949 => GetResourceString("Globalization_cp_949");

		internal static string Globalization_cp_950 => GetResourceString("Globalization_cp_950");

		internal static string Globalization_cp_1026 => GetResourceString("Globalization_cp_1026");

		internal static string Globalization_cp_1047 => GetResourceString("Globalization_cp_1047");

		internal static string Globalization_cp_1140 => GetResourceString("Globalization_cp_1140");

		internal static string Globalization_cp_1141 => GetResourceString("Globalization_cp_1141");

		internal static string Globalization_cp_1142 => GetResourceString("Globalization_cp_1142");

		internal static string Globalization_cp_1143 => GetResourceString("Globalization_cp_1143");

		internal static string Globalization_cp_1144 => GetResourceString("Globalization_cp_1144");

		internal static string Globalization_cp_1145 => GetResourceString("Globalization_cp_1145");

		internal static string Globalization_cp_1146 => GetResourceString("Globalization_cp_1146");

		internal static string Globalization_cp_1147 => GetResourceString("Globalization_cp_1147");

		internal static string Globalization_cp_1148 => GetResourceString("Globalization_cp_1148");

		internal static string Globalization_cp_1149 => GetResourceString("Globalization_cp_1149");

		internal static string Globalization_cp_1250 => GetResourceString("Globalization_cp_1250");

		internal static string Globalization_cp_1251 => GetResourceString("Globalization_cp_1251");

		internal static string Globalization_cp_1252 => GetResourceString("Globalization_cp_1252");

		internal static string Globalization_cp_1253 => GetResourceString("Globalization_cp_1253");

		internal static string Globalization_cp_1254 => GetResourceString("Globalization_cp_1254");

		internal static string Globalization_cp_1255 => GetResourceString("Globalization_cp_1255");

		internal static string Globalization_cp_1256 => GetResourceString("Globalization_cp_1256");

		internal static string Globalization_cp_1257 => GetResourceString("Globalization_cp_1257");

		internal static string Globalization_cp_1258 => GetResourceString("Globalization_cp_1258");

		internal static string Globalization_cp_1361 => GetResourceString("Globalization_cp_1361");

		internal static string Globalization_cp_10000 => GetResourceString("Globalization_cp_10000");

		internal static string Globalization_cp_10001 => GetResourceString("Globalization_cp_10001");

		internal static string Globalization_cp_10002 => GetResourceString("Globalization_cp_10002");

		internal static string Globalization_cp_10003 => GetResourceString("Globalization_cp_10003");

		internal static string Globalization_cp_10004 => GetResourceString("Globalization_cp_10004");

		internal static string Globalization_cp_10005 => GetResourceString("Globalization_cp_10005");

		internal static string Globalization_cp_10006 => GetResourceString("Globalization_cp_10006");

		internal static string Globalization_cp_10007 => GetResourceString("Globalization_cp_10007");

		internal static string Globalization_cp_10008 => GetResourceString("Globalization_cp_10008");

		internal static string Globalization_cp_10010 => GetResourceString("Globalization_cp_10010");

		internal static string Globalization_cp_10017 => GetResourceString("Globalization_cp_10017");

		internal static string Globalization_cp_10021 => GetResourceString("Globalization_cp_10021");

		internal static string Globalization_cp_10029 => GetResourceString("Globalization_cp_10029");

		internal static string Globalization_cp_10079 => GetResourceString("Globalization_cp_10079");

		internal static string Globalization_cp_10081 => GetResourceString("Globalization_cp_10081");

		internal static string Globalization_cp_10082 => GetResourceString("Globalization_cp_10082");

		internal static string Globalization_cp_20000 => GetResourceString("Globalization_cp_20000");

		internal static string Globalization_cp_20001 => GetResourceString("Globalization_cp_20001");

		internal static string Globalization_cp_20002 => GetResourceString("Globalization_cp_20002");

		internal static string Globalization_cp_20003 => GetResourceString("Globalization_cp_20003");

		internal static string Globalization_cp_20004 => GetResourceString("Globalization_cp_20004");

		internal static string Globalization_cp_20005 => GetResourceString("Globalization_cp_20005");

		internal static string Globalization_cp_20105 => GetResourceString("Globalization_cp_20105");

		internal static string Globalization_cp_20106 => GetResourceString("Globalization_cp_20106");

		internal static string Globalization_cp_20107 => GetResourceString("Globalization_cp_20107");

		internal static string Globalization_cp_20108 => GetResourceString("Globalization_cp_20108");

		internal static string Globalization_cp_20261 => GetResourceString("Globalization_cp_20261");

		internal static string Globalization_cp_20269 => GetResourceString("Globalization_cp_20269");

		internal static string Globalization_cp_20273 => GetResourceString("Globalization_cp_20273");

		internal static string Globalization_cp_20277 => GetResourceString("Globalization_cp_20277");

		internal static string Globalization_cp_20278 => GetResourceString("Globalization_cp_20278");

		internal static string Globalization_cp_20280 => GetResourceString("Globalization_cp_20280");

		internal static string Globalization_cp_20284 => GetResourceString("Globalization_cp_20284");

		internal static string Globalization_cp_20285 => GetResourceString("Globalization_cp_20285");

		internal static string Globalization_cp_20290 => GetResourceString("Globalization_cp_20290");

		internal static string Globalization_cp_20297 => GetResourceString("Globalization_cp_20297");

		internal static string Globalization_cp_20420 => GetResourceString("Globalization_cp_20420");

		internal static string Globalization_cp_20423 => GetResourceString("Globalization_cp_20423");

		internal static string Globalization_cp_20424 => GetResourceString("Globalization_cp_20424");

		internal static string Globalization_cp_20833 => GetResourceString("Globalization_cp_20833");

		internal static string Globalization_cp_20838 => GetResourceString("Globalization_cp_20838");

		internal static string Globalization_cp_20866 => GetResourceString("Globalization_cp_20866");

		internal static string Globalization_cp_20871 => GetResourceString("Globalization_cp_20871");

		internal static string Globalization_cp_20880 => GetResourceString("Globalization_cp_20880");

		internal static string Globalization_cp_20905 => GetResourceString("Globalization_cp_20905");

		internal static string Globalization_cp_20924 => GetResourceString("Globalization_cp_20924");

		internal static string Globalization_cp_20932 => GetResourceString("Globalization_cp_20932");

		internal static string Globalization_cp_20936 => GetResourceString("Globalization_cp_20936");

		internal static string Globalization_cp_20949 => GetResourceString("Globalization_cp_20949");

		internal static string Globalization_cp_21025 => GetResourceString("Globalization_cp_21025");

		internal static string Globalization_cp_21027 => GetResourceString("Globalization_cp_21027");

		internal static string Globalization_cp_21866 => GetResourceString("Globalization_cp_21866");

		internal static string Globalization_cp_28592 => GetResourceString("Globalization_cp_28592");

		internal static string Globalization_cp_28593 => GetResourceString("Globalization_cp_28593");

		internal static string Globalization_cp_28594 => GetResourceString("Globalization_cp_28594");

		internal static string Globalization_cp_28595 => GetResourceString("Globalization_cp_28595");

		internal static string Globalization_cp_28596 => GetResourceString("Globalization_cp_28596");

		internal static string Globalization_cp_28597 => GetResourceString("Globalization_cp_28597");

		internal static string Globalization_cp_28598 => GetResourceString("Globalization_cp_28598");

		internal static string Globalization_cp_28599 => GetResourceString("Globalization_cp_28599");

		internal static string Globalization_cp_28603 => GetResourceString("Globalization_cp_28603");

		internal static string Globalization_cp_28605 => GetResourceString("Globalization_cp_28605");

		internal static string Globalization_cp_29001 => GetResourceString("Globalization_cp_29001");

		internal static string Globalization_cp_38598 => GetResourceString("Globalization_cp_38598");

		internal static string Globalization_cp_50000 => GetResourceString("Globalization_cp_50000");

		internal static string Globalization_cp_50220 => GetResourceString("Globalization_cp_50220");

		internal static string Globalization_cp_50221 => GetResourceString("Globalization_cp_50221");

		internal static string Globalization_cp_50222 => GetResourceString("Globalization_cp_50222");

		internal static string Globalization_cp_50225 => GetResourceString("Globalization_cp_50225");

		internal static string Globalization_cp_50227 => GetResourceString("Globalization_cp_50227");

		internal static string Globalization_cp_50229 => GetResourceString("Globalization_cp_50229");

		internal static string Globalization_cp_50930 => GetResourceString("Globalization_cp_50930");

		internal static string Globalization_cp_50931 => GetResourceString("Globalization_cp_50931");

		internal static string Globalization_cp_50933 => GetResourceString("Globalization_cp_50933");

		internal static string Globalization_cp_50935 => GetResourceString("Globalization_cp_50935");

		internal static string Globalization_cp_50937 => GetResourceString("Globalization_cp_50937");

		internal static string Globalization_cp_50939 => GetResourceString("Globalization_cp_50939");

		internal static string Globalization_cp_51932 => GetResourceString("Globalization_cp_51932");

		internal static string Globalization_cp_51936 => GetResourceString("Globalization_cp_51936");

		internal static string Globalization_cp_51949 => GetResourceString("Globalization_cp_51949");

		internal static string Globalization_cp_52936 => GetResourceString("Globalization_cp_52936");

		internal static string Globalization_cp_54936 => GetResourceString("Globalization_cp_54936");

		internal static string Globalization_cp_57002 => GetResourceString("Globalization_cp_57002");

		internal static string Globalization_cp_57003 => GetResourceString("Globalization_cp_57003");

		internal static string Globalization_cp_57004 => GetResourceString("Globalization_cp_57004");

		internal static string Globalization_cp_57005 => GetResourceString("Globalization_cp_57005");

		internal static string Globalization_cp_57006 => GetResourceString("Globalization_cp_57006");

		internal static string Globalization_cp_57007 => GetResourceString("Globalization_cp_57007");

		internal static string Globalization_cp_57008 => GetResourceString("Globalization_cp_57008");

		internal static string Globalization_cp_57009 => GetResourceString("Globalization_cp_57009");

		internal static string Globalization_cp_57010 => GetResourceString("Globalization_cp_57010");

		internal static string Globalization_cp_57011 => GetResourceString("Globalization_cp_57011");

		internal static bool UsingResourceKeys()
		{
			return s_usingResourceKeys;
		}

		private static string GetResourceString(string resourceKey)
		{
			if (UsingResourceKeys())
			{
				return resourceKey;
			}
			string result = null;
			try
			{
				result = ResourceManager.GetString(resourceKey);
			}
			catch (MissingManifestResourceException)
			{
			}
			return result;
		}

		private static string GetResourceString(string resourceKey, string defaultString)
		{
			string resourceString = GetResourceString(resourceKey);
			if (!(resourceKey == resourceString) && resourceString != null)
			{
				return resourceString;
			}
			return defaultString;
		}

		internal static string Format(string resourceFormat, object p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(resourceFormat, p1);
		}

		internal static string Format(string resourceFormat, object p1, object p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(resourceFormat, p1, p2);
		}

		internal static string Format(string resourceFormat, object p1, object p2, object p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(resourceFormat, p1, p2, p3);
		}

		internal static string Format(string resourceFormat, params object[] args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + ", " + string.Join(", ", args);
				}
				return string.Format(resourceFormat, args);
			}
			return resourceFormat;
		}

		internal static string Format(IFormatProvider provider, string resourceFormat, object p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(provider, resourceFormat, p1);
		}

		internal static string Format(IFormatProvider provider, string resourceFormat, object p1, object p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(provider, resourceFormat, p1, p2);
		}

		internal static string Format(IFormatProvider provider, string resourceFormat, object p1, object p2, object p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(provider, resourceFormat, p1, p2, p3);
		}

		internal static string Format(IFormatProvider provider, string resourceFormat, params object[] args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + ", " + string.Join(", ", args);
				}
				return string.Format(provider, resourceFormat, args);
			}
			return resourceFormat;
		}
	}
}
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.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class MaybeNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class NotNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal sealed class MaybeNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

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

		public NotNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[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.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.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	internal sealed class MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	internal sealed class MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
}
namespace System.Runtime.Versioning
{
	internal abstract class OSPlatformAttribute : Attribute
	{
		public string PlatformName { get; }

		private protected OSPlatformAttribute(string platformName)
		{
			PlatformName = platformName;
		}
	}
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)]
	internal sealed class TargetPlatformAttribute : OSPlatformAttribute
	{
		public TargetPlatformAttribute(string platformName)
			: base(platformName)
		{
		}
	}
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface, AllowMultiple = true, Inherited = false)]
	internal sealed class SupportedOSPlatformAttribute : OSPlatformAttribute
	{
		public SupportedOSPlatformAttribute(string platformName)
			: base(platformName)
		{
		}
	}
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface, AllowMultiple = true, Inherited = false)]
	internal sealed class UnsupportedOSPlatformAttribute : OSPlatformAttribute
	{
		public string Message { get; }

		public UnsupportedOSPlatformAttribute(string platformName)
			: base(platformName)
		{
		}

		public UnsupportedOSPlatformAttribute(string platformName, string message)
			: base(platformName)
		{
			Message = message;
		}
	}
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface, AllowMultiple = true, Inherited = false)]
	internal sealed class ObsoletedOSPlatformAttribute : OSPlatformAttribute
	{
		public string Message { get; }

		public string Url { get; set; }

		public ObsoletedOSPlatformAttribute(string platformName)
			: base(platformName)
		{
		}

		public ObsoletedOSPlatformAttribute(string platformName, string message)
			: base(platformName)
		{
			Message = message;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true, Inherited = false)]
	internal sealed class SupportedOSPlatformGuardAttribute : OSPlatformAttribute
	{
		public SupportedOSPlatformGuardAttribute(string platformName)
			: base(platformName)
		{
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true, Inherited = false)]
	internal sealed class UnsupportedOSPlatformGuardAttribute : OSPlatformAttribute
	{
		public UnsupportedOSPlatformGuardAttribute(string platformName)
			: base(platformName)
		{
		}
	}
}
namespace System.Runtime.InteropServices
{
	[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
	internal sealed class LibraryImportAttribute : Attribute
	{
		public string LibraryName { get; }

		public string EntryPoint { get; set; }

		public StringMarshalling StringMarshalling { get; set; }

		public Type StringMarshallingCustomType { get; set; }

		public bool SetLastError { get; set; }

		public LibraryImportAttribute(string libraryName)
		{
			LibraryName = libraryName;
		}
	}
	internal enum StringMarshalling
	{
		Custom,
		Utf8,
		Utf16
	}
}
namespace System.Text
{
	internal abstract class BaseCodePageEncoding : EncodingNLS, ISerializable
	{
		[StructLayout(LayoutKind.Explicit)]
		internal struct CodePageDataFileHeader
		{
			[FieldOffset(0)]
			internal char TableName;

			[FieldOffset(32)]
			internal ushort Version;

			[FieldOffset(40)]
			internal short CodePageCount;

			[FieldOffset(42)]
			internal short unused1;
		}

		[StructLayout(LayoutKind.Explicit, Pack = 2)]
		internal struct CodePageIndex
		{
			[FieldOffset(0)]
			internal char CodePageName;

			[FieldOffset(32)]
			internal short CodePage;

			[FieldOffset(34)]
			internal short ByteCount;

			[FieldOffset(36)]
			internal int Offset;
		}

		[StructLayout(LayoutKind.Explicit)]
		internal struct CodePageHeader
		{
			[FieldOffset(0)]
			internal char CodePageName;

			[FieldOffset(32)]
			internal ushort VersionMajor;

			[FieldOffset(34)]
			internal ushort VersionMinor;

			[FieldOffset(36)]
			internal ushort VersionRevision;

			[FieldOffset(38)]
			internal ushort VersionBuild;

			[FieldOffset(40)]
			internal short CodePage;

			[FieldOffset(42)]
			internal short ByteCount;

			[FieldOffset(44)]
			internal char UnicodeReplace;

			[FieldOffset(46)]
			internal ushort ByteReplace;
		}

		internal const string CODE_PAGE_DATA_FILE_NAME = "codepages.nlp";

		protected int dataTableCodePage;

		protected int iExtraBytes;

		protected char[] arrayUnicodeBestFit;

		protected char[] arrayBytesBestFit;

		private const int CODEPAGE_DATA_FILE_HEADER_SIZE = 44;

		private const int CODEPAGE_HEADER_SIZE = 48;

		private static readonly byte[] s_codePagesDataHeader = new byte[44];

		protected static Stream s_codePagesEncodingDataStream = GetEncodingDataStream("codepages.nlp");

		protected static readonly object s_streamLock = new object();

		protected byte[] m_codePageHeader = new byte[48];

		protected int m_firstDataWordOffset;

		protected int m_dataSize;

		protected SafeAllocHHandle safeNativeMemoryHandle;

		internal BaseCodePageEncoding(int codepage)
			: this(codepage, codepage)
		{
		}

		internal BaseCodePageEncoding(int codepage, int dataCodePage)
			: base(codepage, new InternalEncoderBestFitFallback(null), new InternalDecoderBestFitFallback(null))
		{
			((InternalEncoderBestFitFallback)base.EncoderFallback).encoding = this;
			((InternalDecoderBestFitFallback)base.DecoderFallback).encoding = this;
			dataTableCodePage = dataCodePage;
			LoadCodePageTables();
		}

		internal BaseCodePageEncoding(int codepage, int dataCodePage, EncoderFallback enc, DecoderFallback dec)
			: base(codepage, enc, dec)
		{
			dataTableCodePage = dataCodePage;
			LoadCodePageTables();
		}

		void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
		{
			throw new PlatformNotSupportedException();
		}

		private unsafe static void ReadCodePageDataFileHeader(Stream stream, byte[] codePageDataFileHeader)
		{
			int num = stream.Read(codePageDataFileHeader, 0, codePageDataFileHeader.Length);
			if (BitConverter.IsLittleEndian)
			{
				return;
			}
			fixed (byte* ptr = &codePageDataFileHeader[0])
			{
				CodePageDataFileHeader* ptr2 = (CodePageDataFileHeader*)ptr;
				char* ptr3 = &ptr2->TableName;
				for (int i = 0; i < 16; i++)
				{
					ptr3[i] = (char)BinaryPrimitives.ReverseEndianness(ptr3[i]);
				}
				ushort* ptr4 = &ptr2->Version;
				for (int j = 0; j < 4; j++)
				{
					ptr4[j] = BinaryPrimitives.ReverseEndianness(ptr4[j]);
				}
				ptr2->CodePageCount = BinaryPrimitives.ReverseEndianness(ptr2->CodePageCount);
			}
		}

		private unsafe static void ReadCodePageIndex(Stream stream, byte[] codePageIndex)
		{
			int num = stream.Read(codePageIndex, 0, codePageIndex.Length);
			if (BitConverter.IsLittleEndian)
			{
				return;
			}
			fixed (byte* ptr = &codePageIndex[0])
			{
				CodePageIndex* ptr2 = (CodePageIndex*)ptr;
				char* ptr3 = &ptr2->CodePageName;
				for (int i = 0; i < 16; i++)
				{
					ptr3[i] = (char)BinaryPrimitives.ReverseEndianness(ptr3[i]);
				}
				ptr2->CodePage = BinaryPrimitives.ReverseEndianness(ptr2->CodePage);
				ptr2->ByteCount = BinaryPrimitives.ReverseEndianness(ptr2->ByteCount);
				ptr2->Offset = BinaryPrimitives.ReverseEndianness(ptr2->Offset);
			}
		}

		private unsafe static void ReadCodePageHeader(Stream stream, byte[] codePageHeader)
		{
			int num = stream.Read(codePageHeader, 0, codePageHeader.Length);
			if (BitConverter.IsLittleEndian)
			{
				return;
			}
			fixed (byte* ptr = &codePageHeader[0])
			{
				CodePageHeader* ptr2 = (CodePageHeader*)ptr;
				char* ptr3 = &ptr2->CodePageName;
				for (int i = 0; i < 16; i++)
				{
					ptr3[i] = (char)BinaryPrimitives.ReverseEndianness(ptr3[i]);
				}
				ptr2->VersionMajor = BinaryPrimitives.ReverseEndianness(ptr2->VersionMajor);
				ptr2->VersionMinor = BinaryPrimitives.ReverseEndianness(ptr2->VersionMinor);
				ptr2->VersionRevision = BinaryPrimitives.ReverseEndianness(ptr2->VersionRevision);
				ptr2->VersionBuild = BinaryPrimitives.ReverseEndianness(ptr2->VersionBuild);
				ptr2->CodePage = BinaryPrimitives.ReverseEndianness(ptr2->CodePage);
				ptr2->ByteCount = BinaryPrimitives.ReverseEndianness(ptr2->ByteCount);
				ptr2->UnicodeReplace = (char)BinaryPrimitives.ReverseEndianness(ptr2->UnicodeReplace);
				ptr2->ByteReplace = BinaryPrimitives.ReverseEndianness(ptr2->ByteReplace);
			}
		}

		internal static Stream GetEncodingDataStream(string tableName)
		{
			Stream manifestResourceStream = typeof(CodePagesEncodingProvider).Assembly.GetManifestResourceStream(tableName);
			if (manifestResourceStream == null)
			{
				throw new InvalidOperationException();
			}
			ReadCodePageDataFileHeader(manifestResourceStream, s_codePagesDataHeader);
			return manifestResourceStream;
		}

		private void LoadCodePageTables()
		{
			if (!FindCodePage(dataTableCodePage))
			{
				throw new NotSupportedException(System.SR.Format(System.SR.NotSupported_NoCodepageData, CodePage));
			}
			LoadManagedCodePage();
		}

		private unsafe bool FindCodePage(int codePage)
		{
			byte[] array = new byte[sizeof(CodePageIndex)];
			lock (s_streamLock)
			{
				s_codePagesEncodingDataStream.Seek(44L, SeekOrigin.Begin);
				int codePageCount;
				fixed (byte* ptr = &s_codePagesDataHeader[0])
				{
					CodePageDataFileHeader* ptr2 = (CodePageDataFileHeader*)ptr;
					codePageCount = ptr2->CodePageCount;
				}
				fixed (byte* ptr3 = &array[0])
				{
					CodePageIndex* ptr4 = (CodePageIndex*)ptr3;
					for (int i = 0; i < codePageCount; i++)
					{
						ReadCodePageIndex(s_codePagesEncodingDataStream, array);
						if (ptr4->CodePage == codePage)
						{
							long position = s_codePagesEncodingDataStream.Position;
							s_codePagesEncodingDataStream.Seek(ptr4->Offset, SeekOrigin.Begin);
							ReadCodePageHeader(s_codePagesEncodingDataStream, m_codePageHeader);
							m_firstDataWordOffset = (int)s_codePagesEncodingDataStream.Position;
							if (i == codePageCount - 1)
							{
								m_dataSize = (int)(s_codePagesEncodingDataStream.Length - ptr4->Offset - m_codePageHeader.Length);
							}
							else
							{
								s_codePagesEncodingDataStream.Seek(position, SeekOrigin.Begin);
								int offset = ptr4->Offset;
								ReadCodePageIndex(s_codePagesEncodingDataStream, array);
								m_dataSize = ptr4->Offset - offset - m_codePageHeader.Length;
							}
							return true;
						}
					}
				}
			}
			return false;
		}

		internal unsafe static int GetCodePageByteSize(int codePage)
		{
			byte[] array = new byte[sizeof(CodePageIndex)];
			lock (s_streamLock)
			{
				s_codePagesEncodingDataStream.Seek(44L, SeekOrigin.Begin);
				int codePageCount;
				fixed (byte* ptr = &s_codePagesDataHeader[0])
				{
					CodePageDataFileHeader* ptr2 = (CodePageDataFileHeader*)ptr;
					codePageCount = ptr2->CodePageCount;
				}
				fixed (byte* ptr3 = &array[0])
				{
					CodePageIndex* ptr4 = (CodePageIndex*)ptr3;
					for (int i = 0; i < codePageCount; i++)
					{
						ReadCodePageIndex(s_codePagesEncodingDataStream, array);
						if (ptr4->CodePage == codePage)
						{
							return ptr4->ByteCount;
						}
					}
				}
			}
			return 0;
		}

		protected abstract void LoadManagedCodePage();

		protected unsafe byte* GetNativeMemory(int iSize)
		{
			if (safeNativeMemoryHandle == null)
			{
				byte* ptr = (byte*)(void*)Marshal.AllocHGlobal(iSize);
				safeNativeMemoryHandle = new SafeAllocHHandle((IntPtr)ptr);
			}
			return (byte*)(void*)safeNativeMemoryHandle.DangerousGetHandle();
		}

		protected abstract void ReadBestFitTable();

		internal char[] GetBestFitUnicodeToBytesData()
		{
			if (arrayUnicodeBestFit == null)
			{
				ReadBestFitTable();
			}
			return arrayUnicodeBestFit;
		}

		internal char[] GetBestFitBytesToUnicodeData()
		{
			if (arrayBytesBestFit == null)
			{
				ReadBestFitTable();
			}
			return arrayBytesBestFit;
		}

		internal void CheckMemorySection()
		{
			if (safeNativeMemoryHandle != null && safeNativeMemoryHandle.DangerousGetHandle() == IntPtr.Zero)
			{
				LoadManagedCodePage();
			}
		}
	}
	public sealed class CodePagesEncodingProvider : EncodingProvider
	{
		private static readonly EncodingProvider s_singleton = new CodePagesEncodingProvider();

		private readonly Dictionary<int, Encoding> _encodings = new Dictionary<int, Encoding>();

		private readonly ReaderWriterLockSlim _cacheLock = new ReaderWriterLockSlim();

		private const int ISCIIAssemese = 57006;

		private const int ISCIIBengali = 57003;

		private const int ISCIIDevanagari = 57002;

		private const int ISCIIGujarathi = 57010;

		private const int ISCIIKannada = 57008;

		private const int ISCIIMalayalam = 57009;

		private const int ISCIIOriya = 57007;

		private const int ISCIIPanjabi = 57011;

		private const int ISCIITamil = 57004;

		private const int ISCIITelugu = 57005;

		private const int ISOKorean = 50225;

		private const int ChineseHZ = 52936;

		private const int ISO2022JP = 50220;

		private const int ISO2022JPESC = 50221;

		private const int ISO2022JPSISO = 50222;

		private const int ISOSimplifiedCN = 50227;

		private const int EUCJP = 51932;

		private const int CodePageMacGB2312 = 10008;

		private const int CodePageMacKorean = 10003;

		private const int CodePageGB2312 = 20936;

		private const int CodePageDLLKorean = 20949;

		private const int GB18030 = 54936;

		private const int DuplicateEUCCN = 51936;

		private const int EUCKR = 51949;

		private const int EUCCN = 936;

		private const int ISO_8859_8I = 38598;

		private const int ISO_8859_8_Visual = 28598;

		public static EncodingProvider Instance => s_singleton;

		private static int SystemDefaultCodePage => 0;

		internal CodePagesEncodingProvider()
		{
		}

		public override Encoding? GetEncoding(int codepage)
		{
			if (codepage < 0 || codepage > 65535)
			{
				return null;
			}
			if (codepage == 0)
			{
				int systemDefaultCodePage = SystemDefaultCodePage;
				if (systemDefaultCodePage == 0)
				{
					return null;
				}
				return GetEncoding(systemDefaultCodePage);
			}
			Encoding value = null;
			_cacheLock.EnterUpgradeableReadLock();
			try
			{
				if (_encodings.TryGetValue(codepage, out value))
				{
					return value;
				}
				switch (BaseCodePageEncoding.GetCodePageByteSize(codepage))
				{
				case 1:
					value = new SBCSCodePageEncoding(codepage);
					break;
				case 2:
					value = new DBCSCodePageEncoding(codepage);
					break;
				default:
					value = GetEncodingRare(codepage);
					if (value == null)
					{
						return null;
					}
					break;
				}
				_cacheLock.EnterWriteLock();
				try
				{
					if (_encodings.TryGetValue(codepage, out var value2))
					{
						return value2;
					}
					_encodings.Add(codepage, value);
					return value;
				}
				finally
				{
					_cacheLock.ExitWriteLock();
				}
			}
			finally
			{
				_cacheLock.ExitUpgradeableReadLock();
			}
		}

		public override Encoding? GetEncoding(string name)
		{
			int codePageFromName = System.Text.EncodingTable.GetCodePageFromName(name);
			if (codePageFromName == 0)
			{
				return null;
			}
			return GetEncoding(codePageFromName);
		}

		private static Encoding GetEncodingRare(int codepage)
		{
			Encoding result = null;
			switch (codepage)
			{
			case 57002:
			case 57003:
			case 57004:
			case 57005:
			case 57006:
			case 57007:
			case 57008:
			case 57009:
			case 57010:
			case 57011:
				result = new ISCIIEncoding(codepage);
				break;
			case 10008:
				result = new DBCSCodePageEncoding(10008, 20936);
				break;
			case 10003:
				result = new DBCSCodePageEncoding(10003, 20949);
				break;
			case 54936:
				result = new GB18030Encoding();
				break;
			case 50220:
			case 50221:
			case 50222:
			case 50225:
			case 52936:
				result = new ISO2022Encoding(codepage);
				break;
			case 50227:
			case 51936:
				result = new DBCSCodePageEncoding(codepage, 936);
				break;
			case 51932:
				result = new EUCJPEncoding();
				break;
			case 51949:
				result = new DBCSCodePageEncoding(codepage, 20949);
				break;
			case 38598:
				result = new SBCSCodePageEncoding(codepage, 28598);
				break;
			}
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal unsafe static ref T GetNonNullPinnableReference<T>(T[] array) where T : struct
		{
			if (array.Length == 0)
			{
				return ref Unsafe.AsRef<T>((void*)1);
			}
			return ref array[0];
		}
	}
	internal class DBCSCodePageEncoding : BaseCodePageEncoding
	{
		internal sealed class DBCSDecoder : System.Text.DecoderNLS
		{
			internal byte bLeftOver;

			internal override bool HasState => bLeftOver != 0;

			public DBCSDecoder(DBCSCodePageEncoding encoding)
				: base(encoding)
			{
			}

			public override void Reset()
			{
				bLeftOver = 0;
				m_fallbackBuffer?.Reset();
			}
		}

		protected unsafe char* mapBytesToUnicode = null;

		protected unsafe ushort* mapUnicodeToBytes = null;

		protected const char UNKNOWN_CHAR_FLAG = '\0';

		protected const char UNICODE_REPLACEMENT_CHAR = '\ufffd';

		protected const char LEAD_BYTE_CHAR = '\ufffe';

		private ushort _bytesUnknown;

		private int _byteCountUnknown;

		protected char charUnknown;

		private static object s_InternalSyncObject;

		private static object InternalSyncObject
		{
			get
			{
				if (s_InternalSyncObject == null)
				{
					object value = new object();
					Interlocked.CompareExchange<object>(ref s_InternalSyncObject, value, (object)null);
				}
				return s_InternalSyncObject;
			}
		}

		public DBCSCodePageEncoding(int codePage)
			: this(codePage, codePage)
		{
		}

		internal unsafe DBCSCodePageEncoding(int codePage, int dataCodePage)
			: base(codePage, dataCodePage)
		{
		}

		internal unsafe DBCSCodePageEncoding(int codePage, int dataCodePage, EncoderFallback enc, DecoderFallback dec)
			: base(codePage, dataCodePage, enc, dec)
		{
		}

		internal unsafe static char ReadChar(char* pChar)
		{
			if (BitConverter.IsLittleEndian)
			{
				return *pChar;
			}
			return (char)BinaryPrimitives.ReverseEndianness(*pChar);
		}

		protected unsafe override void LoadManagedCodePage()
		{
			fixed (byte* ptr = &m_codePageHeader[0])
			{
				CodePageHeader* ptr2 = (CodePageHeader*)ptr;
				if (ptr2->ByteCount != 2)
				{
					throw new NotSupportedException(System.SR.Format(System.SR.NotSupported_NoCodepageData, CodePage));
				}
				_bytesUnknown = ptr2->ByteReplace;
				charUnknown = ptr2->UnicodeReplace;
				if (base.DecoderFallback is InternalDecoderBestFitFallback)
				{
					((InternalDecoderBestFitFallback)base.DecoderFallback).cReplacement = charUnknown;
				}
				_byteCountUnknown = 1;
				if (_bytesUnknown > 255)
				{
					_byteCountUnknown++;
				}
				int num = 262148 + iExtraBytes;
				byte* nativeMemory = GetNativeMemory(num);
				Unsafe.InitBlockUnaligned(nativeMemory, 0, (uint)num);
				mapBytesToUnicode = (char*)nativeMemory;
				mapUnicodeToBytes = (ushort*)(nativeMemory + 131072);
				byte[] array = new byte[m_dataSize];
				lock (BaseCodePageEncoding.s_streamLock)
				{
					BaseCodePageEncoding.s_codePagesEncodingDataStream.Seek(m_firstDataWordOffset, SeekOrigin.Begin);
					int num2 = BaseCodePageEncoding.s_codePagesEncodingDataStream.Read(array, 0, m_dataSize);
				}
				fixed (byte* ptr3 = array)
				{
					char* ptr4 = (char*)ptr3;
					int num3 = 0;
					int num4 = 0;
					while (num3 < 65536)
					{
						char c = ReadChar(ptr4);
						ptr4++;
						switch (c)
						{
						case '\u0001':
							num3 = ReadChar(ptr4);
							ptr4++;
							continue;
						case '\u0002':
						case '\u0003':
						case '\u0004':
						case '\u0005':
						case '\u0006':
						case '\a':
						case '\b':
						case '\t':
						case '\n':
						case '\v':
						case '\f':
						case '\r':
						case '\u000e':
						case '\u000f':
						case '\u0010':
						case '\u0011':
						case '\u0012':
						case '\u0013':
						case '\u0014':
						case '\u0015':
						case '\u0016':
						case '\u0017':
						case '\u0018':
						case '\u0019':
						case '\u001a':
						case '\u001b':
						case '\u001c':
						case '\u001d':
						case '\u001e':
						case '\u001f':
							num3 += c;
							continue;
						}
						switch (c)
						{
						case '\uffff':
							num4 = num3;
							c = (char)num3;
							break;
						case '\ufffe':
							num4 = num3;
							break;
						case '\ufffd':
							num3++;
							continue;
						default:
							num4 = num3;
							break;
						}
						if (CleanUpBytes(ref num4))
						{
							if (c != '\ufffe')
							{
								mapUnicodeToBytes[(int)c] = (ushort)num4;
							}
							mapBytesToUnicode[num4] = c;
						}
						num3++;
					}
				}
				CleanUpEndBytes(mapBytesToUnicode);
			}
		}

		protected virtual bool CleanUpBytes(ref int bytes)
		{
			return true;
		}

		protected unsafe virtual void CleanUpEndBytes(char* chars)
		{
		}

		protected unsafe override void ReadBestFitTable()
		{
			lock (InternalSyncObject)
			{
				if (arrayUnicodeBestFit != null)
				{
					return;
				}
				byte[] array = new byte[m_dataSize];
				lock (BaseCodePageEncoding.s_streamLock)
				{
					BaseCodePageEncoding.s_codePagesEncodingDataStream.Seek(m_firstDataWordOffset, SeekOrigin.Begin);
					int num = BaseCodePageEncoding.s_codePagesEncodingDataStream.Read(array, 0, m_dataSize);
				}
				fixed (byte* ptr = array)
				{
					char* ptr2 = (char*)ptr;
					int num2 = 0;
					while (num2 < 65536)
					{
						char c = ReadChar(ptr2);
						ptr2++;
						switch (c)
						{
						case '\u0001':
							num2 = ReadChar(ptr2);
							ptr2++;
							break;
						case '\u0002':
						case '\u0003':
						case '\u0004':
						case '\u0005':
						case '\u0006':
						case '\a':
						case '\b':
						case '\t':
						case '\n':
						case '\v':
						case '\f':
						case '\r':
						case '\u000e':
						case '\u000f':
						case '\u0010':
						case '\u0011':
						case '\u0012':
						case '\u0013':
						case '\u0014':
						case '\u0015':
						case '\u0016':
						case '\u0017':
						case '\u0018':
						case '\u0019':
						case '\u001a':
						case '\u001b':
						case '\u001c':
						case '\u001d':
						case '\u001e':
						case '\u001f':
							num2 += c;
							break;
						default:
							num2++;
							break;
						}
					}
					char* ptr3 = ptr2;
					int num3 = 0;
					num2 = ReadChar(ptr2);
					ptr2++;
					while (num2 < 65536)
					{
						char c2 = ReadChar(ptr2);
						ptr2++;
						switch (c2)
						{
						case '\u0001':
							num2 = ReadChar(ptr2);
							ptr2++;
							continue;
						case '\u0002':
						case '\u0003':
						case '\u0004':
						case '\u0005':
						case '\u0006':
						case '\a':
						case '\b':
						case '\t':
						case '\n':
						case '\v':
						case '\f':
						case '\r':
						case '\u000e':
						case '\u000f':
						case '\u0010':
						case '\u0011':
						case '\u0012':
						case '\u0013':
						case '\u0014':
						case '\u0015':
						case '\u0016':
						case '\u0017':
						case '\u0018':
						case '\u0019':
						case '\u001a':
						case '\u001b':
						case '\u001c':
						case '\u001d':
						case '\u001e':
						case '\u001f':
							num2 += c2;
							continue;
						}
						if (c2 != '\ufffd')
						{
							int bytes = num2;
							if (CleanUpBytes(ref bytes) && mapBytesToUnicode[bytes] != c2)
							{
								num3++;
							}
						}
						num2++;
					}
					char[] array2 = new char[num3 * 2];
					num3 = 0;
					ptr2 = ptr3;
					num2 = ReadChar(ptr2);
					ptr2++;
					bool flag = false;
					while (num2 < 65536)
					{
						char c3 = ReadChar(ptr2);
						ptr2++;
						switch (c3)
						{
						case '\u0001':
							num2 = ReadChar(ptr2);
							ptr2++;
							continue;
						case '\u0002':
						case '\u0003':
						case '\u0004':
						case '\u0005':
						case '\u0006':
						case '\a':
						case '\b':
						case '\t':
						case '\n':
						case '\v':
						case '\f':
						case '\r':
						case '\u000e':
						case '\u000f':
						case '\u0010':
						case '\u0011':
						case '\u0012':
						case '\u0013':
						case '\u0014':
						case '\u0015':
						case '\u0016':
						case '\u0017':
						case '\u0018':
						case '\u0019':
						case '\u001a':
						case '\u001b':
						case '\u001c':
						case '\u001d':
						case '\u001e':
						case '\u001f':
							num2 += c3;
							continue;
						}
						if (c3 != '\ufffd')
						{
							int bytes2 = num2;
							if (CleanUpBytes(ref bytes2) && mapBytesToUnicode[bytes2] != c3)
							{
								if (bytes2 != num2)
								{
									flag = true;
								}
								array2[num3++] = (char)bytes2;
								array2[num3++] = c3;
							}
						}
						num2++;
					}
					if (flag)
					{
						for (int i = 0; i < array2.Length - 2; i += 2)
						{
							int num4 = i;
							char c4 = array2[i];
							for (int j = i + 2; j < array2.Length; j += 2)
							{
								if (c4 > array2[j])
								{
									c4 = array2[j];
									num4 = j;
								}
							}
							if (num4 != i)
							{
								char c5 = array2[num4];
								array2[num4] = array2[i];
								array2[i] = c5;
								c5 = array2[num4 + 1];
								array2[num4 + 1] = array2[i + 1];
								array2[i + 1] = c5;
							}
						}
					}
					arrayBytesBestFit = array2;
					char* ptr4 = ptr2;
					int num5 = ReadChar(ptr2++);
					num3 = 0;
					while (num5 < 65536)
					{
						char c6 = ReadChar(ptr2);
						ptr2++;
						switch (c6)
						{
						case '\u0001':
							num5 = ReadChar(ptr2);
							ptr2++;
							continue;
						case '\u0002':
						case '\u0003':
						case '\u0004':
						case '\u0005':
						case '\u0006':
						case '\a':
						case '\b':
						case '\t':
						case '\n':
						case '\v':
						case '\f':
						case '\r':
						case '\u000e':
						case '\u000f':
						case '\u0010':
						case '\u0011':
						case '\u0012':
						case '\u0013':
						case '\u0014':
						case '\u0015':
						case '\u0016':
						case '\u0017':
						case '\u0018':
						case '\u0019':
						case '\u001a':
						case '\u001b':
						case '\u001c':
						case '\u001d':
						case '\u001e':
						case '\u001f':
							num5 += c6;
							continue;
						}
						if (c6 > '\0')
						{
							num3++;
						}
						num5++;
					}
					array2 = new char[num3 * 2];
					ptr2 = ptr4;
					num5 = ReadChar(ptr2++);
					num3 = 0;
					while (num5 < 65536)
					{
						char c7 = ReadChar(ptr2);
						ptr2++;
						switch (c7)
						{
						case '\u0001':
							num5 = ReadChar(ptr2);
							ptr2++;
							continue;
						case '\u0002':
						case '\u0003':
						case '\u0004':
						case '\u0005':
						case '\u0006':
						case '\a':
						case '\b':
						case '\t':
						case '\n':
						case '\v':
						case '\f':
						case '\r':
						case '\u000e':
						case '\u000f':
						case '\u0010':
						case '\u0011':
						case '\u0012':
						case '\u0013':
						case '\u0014':
						case '\u0015':
						case '\u0016':
						case '\u0017':
						case '\u0018':
						case '\u0019':
						case '\u001a':
						case '\u001b':
						case '\u001c':
						case '\u001d':
						case '\u001e':
						case '\u001f':
							num5 += c7;
							continue;
						}
						if (c7 > '\0')
						{
							int bytes3 = c7;
							if (CleanUpBytes(ref bytes3))
							{
								array2[num3++] = (char)num5;
								array2[num3++] = mapBytesToUnicode[bytes3];
							}
						}
						num5++;
					}
					arrayUnicodeBestFit = array2;
				}
			}
		}

		public unsafe override int GetByteCount(char* chars, int count, System.Text.EncoderNLS encoder)
		{
			CheckMemorySection();
			char c = '\0';
			if (encoder != null)
			{
				c = encoder.charLeftOver;
				if (encoder.InternalHasFallbackBuffer && encoder.FallbackBuffer.Remaining > 0)
				{
					throw new ArgumentException(System.SR.Format(System.SR.Argument_EncoderFallbackNotEmpty, EncodingName, encoder.Fallback.GetType()));
				}
			}
			int num = 0;
			char* ptr = chars + count;
			EncoderFallbackBuffer encoderFallbackBuffer = null;
			EncoderFallbackBufferHelper encoderFallbackBufferHelper = new EncoderFallbackBufferHelper(encoderFallbackBuffer);
			if (c > '\0')
			{
				encoderFallbackBuffer = encoder.FallbackBuffer;
				encoderFallbackBufferHelper = new EncoderFallbackBufferHelper(encoderFallbackBuffer);
				encoderFallbackBufferHelper.InternalInitialize(chars, ptr, encoder, _setEncoder: false);
				encoderFallbackBufferHelper.InternalFallback(c, ref chars);
			}
			char c2;
			while ((c2 = ((encoderFallbackBuffer != null) ? encoderFallbackBufferHelper.InternalGetNextChar() : '\0')) != 0 || chars < ptr)
			{
				if (c2 == '\0')
				{
					c2 = *chars;
					chars++;
				}
				ushort num2 = mapUnicodeToBytes[(int)c2];
				if (num2 == 0 && c2 != 0)
				{
					if (encoderFallbackBuffer == null)
					{
						encoderFallbackBuffer = ((encoder != null) ? encoder.FallbackBuffer : base.EncoderFallback.CreateFallbackBuffer());
						encoderFallbackBufferHelper = new EncoderFallbackBufferHelper(encoderFallbackBuffer);
						encoderFallbackBufferHelper.InternalInitialize(ptr - count, ptr, encoder, _setEncoder: false);
					}
					encoderFallbackBufferHelper.InternalFallback(c2, ref chars);
				}
				else
				{
					num++;
					if (num2 >= 256)
					{
						num++;
					}
				}
			}
			return num;
		}

		public unsafe override int GetBytes(char* chars, int charCount, byte* bytes, int byteCount, System.Text.EncoderNLS encoder)
		{
			CheckMemorySection();
			EncoderFallbackBuffer encoderFallbackBuffer = null;
			char* ptr = chars + charCount;
			char* ptr2 = chars;
			byte* ptr3 = bytes;
			byte* ptr4 = bytes + byteCount;
			EncoderFallbackBufferHelper encoderFallbackBufferHelper = new EncoderFallbackBufferHelper(encoderFallbackBuffer);
			char c = '\0';
			if (encoder != null)
			{
				c = encoder.charLeftOver;
				encoderFallbackBuffer = encoder.FallbackBuffer;
				encoderFallbackBufferHelper = new EncoderFallbackBufferHelper(encoderFallbackBuffer);
				encoderFallbackBufferHelper.InternalInitialize(chars, ptr, encoder, _setEncoder: true);
				if (encoder.m_throwOnOverflow && encoderFallbackBuffer.Remaining > 0)
				{
					throw new ArgumentException(System.SR.Format(System.SR.Argument_EncoderFallbackNotEmpty, EncodingName, encoder.Fallback.GetType()));
				}
				if (c > '\0')
				{
					encoderFallbackBufferHelper.InternalFallback(c, ref chars);
				}
			}
			char c2;
			while ((c2 = ((encoderFallbackBuffer != null) ? encoderFallbackBufferHelper.InternalGetNextChar() : '\0')) != 0 || chars < ptr)
			{
				if (c2 == '\0')
				{
					c2 = *chars;
					chars++;
				}
				ushort num = mapUnicodeToBytes[(int)c2];
				if (num == 0 && c2 != 0)
				{
					if (encoderFallbackBuffer == null)
					{
						encoderFallbackBuffer = base.EncoderFallback.CreateFallbackBuffer();
						encoderFallbackBufferHelper = new EncoderFallbackBufferHelper(encoderFallbackBuffer);
						encoderFallbackBufferHelper.InternalInitialize(ptr - charCount, ptr, encoder, _setEncoder: true);
					}
					encoderFallbackBufferHelper.InternalFallback(c2, ref chars);
					continue;
				}
				if (num >= 256)
				{
					if (bytes + 1 >= ptr4)
					{
						if (encoderFallbackBuffer == null || !encoderFallbackBufferHelper.bFallingBack)
						{
							chars--;
						}
						else
						{
							encoderFallbackBuffer.MovePrevious();
						}
						ThrowBytesOverflow(encoder, chars == ptr2);
						break;
					}
					*bytes = (byte)(num >> 8);
					bytes++;
				}
				else if (bytes >= ptr4)
				{
					if (encoderFallbackBuffer == null || !encoderFallbackBufferHelper.bFallingBack)
					{
						chars--;
					}
					else
					{
						encoderFallbackBuffer.MovePrevious();
					}
					ThrowBytesOverflow(encoder, chars == ptr2);
					break;
				}
				*bytes = (byte)(num & 0xFFu);
				bytes++;
			}
			if (encoder != null)
			{
				if (encoderFallbackBuffer != null && !encoderFallbackBufferHelper.bUsedEncoder)
				{
					encoder.charLeftOver = '\0';
				}
				encoder.m_charsUsed = (int)(chars - ptr2);
			}
			return (int)(bytes - ptr3);
		}

		public unsafe override int GetCharCount(byte* bytes, int count, System.Text.DecoderNLS baseDecoder)
		{
			CheckMemorySection();
			DBCSDecoder dBCSDecoder = (DBCSDecoder)baseDecoder;
			DecoderFallbackBuffer decoderFallbackBuffer = null;
			byte* ptr = bytes + count;
			int num = count;
			DecoderFallbackBufferHelper decoderFallbackBufferHelper = new DecoderFallbackBufferHelper(decoderFallbackBuffer);
			if (dBCSDecoder != null && dBCSDecoder.bLeftOver > 0)
			{
				if (count == 0)
				{
					if (!dBCSDecoder.MustFlush)
					{
						return 0;
					}
					decoderFallbackBuffer = dBCSDecoder.FallbackBuffer;
					decoderFallbackBufferHelper = new DecoderFallbackBufferHelper(decoderFallbackBuffer);
					decoderFallbackBufferHelper.InternalInitialize(bytes, null);
					byte[] bytes2 = new byte[1] { dBCSDecoder.bLeftOver };
					return decoderFallbackBufferHelper.InternalFallback(bytes2, bytes);
				}
				int num2 = dBCSDecoder.bLeftOver << 8;
				num2 |= *bytes;
				bytes++;
				if (mapBytesToUnicode[num2] == '\0' && num2 != 0)
				{
					num--;
					decoderFallbackBuffer = dBCSDecoder.FallbackBuffer;
					decoderFallbackBufferHelper = new DecoderFallbackBufferHelper(decoderFallbackBuffer);
					decoderFallbackBufferHelper.InternalInitialize(ptr - count, null);
					byte[] bytes3 = new byte[2]
					{
						(byte)(num2 >> 8),
						(byte)num2
					};
					num += decoderFallbackBufferHelper.InternalFallback(bytes3, bytes);
				}
			}
			while (bytes < ptr)
			{
				int num3 = *bytes;
				bytes++;
				char c = mapBytesToUnicode[num3];
				if (c == '\ufffe')
				{
					num--;
					if (bytes < ptr)
					{
						num3 <<= 8;
						num3 |= *bytes;
						bytes++;
						c = mapBytesToUnicode[num3];
					}
					else
					{
						if (dBCSDecoder != null && !dBCSDecoder.MustFlush)
						{
							break;
						}
						num++;
						c = '\0';
					}
				}
				if (c == '\0' && num3 != 0)
				{
					if (decoderFallbackBuffer == null)
					{
						decoderFallbackBuffer = ((dBCSDecoder != null) ? dBCSDecoder.FallbackBuffer : base.DecoderFallback.CreateFallbackBuffer());
						decoderFallbackBufferHelper = new DecoderFallbackBufferHelper(decoderFallbackBuffer);
						decoderFallbackBufferHelper.InternalInitialize(ptr - count, null);
					}
					num--;
					byte[] bytes4 = ((num3 >= 256) ? new byte[2]
					{
						(byte)(num3 >> 8),
						(byte)num3
					} : new byte[1] { (byte)num3 });
					num += decoderFallbackBufferHelper.InternalFallback(bytes4, bytes);
				}
			}
			return num;
		}

		public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount, System.Text.DecoderNLS baseDecoder)
		{
			CheckMemorySection();
			DBCSDecoder dBCSDecoder = (DBCSDecoder)baseDecoder;
			byte* ptr = bytes;
			byte* ptr2 = bytes + byteCount;
			char* ptr3 = chars;
			char* ptr4 = chars + charCount;
			bool flag = false;
			DecoderFallbackBuffer decoderFallbackBuffer = null;
			DecoderFallbackBufferHelper decoderFallbackBufferHelper = new DecoderFallbackBufferHelper(decoderFallbackBuffer);
			if (dBCSDecoder != null && dBCSDecoder.bLeftOver > 0)
			{
				if (byteCount == 0)
				{
					if (!dBCSDecoder.MustFlush)
					{
						return 0;
					}
					decoderFallbackBuffer = dBCSDecoder.FallbackBuffer;
					decoderFallbackBufferHelper = new DecoderFallbackBufferHelper(decoderFallbackBuffer);
					decoderFallbackBufferHelper.InternalInitialize(bytes, ptr4);
					byte[] bytes2 = new byte[1] { dBCSDecoder.bLeftOver };
					if (!decoderFallbackBufferHelper.InternalFallback(bytes2, bytes, ref chars))
					{
						ThrowCharsOverflow(dBCSDecoder, nothingDecoded: true);
					}
					dBCSDecoder.bLeftOver = 0;
					return (int)(chars - ptr3);
				}
				int num = dBCSDecoder.bLeftOver << 8;
				num |= *bytes;
				bytes++;
				char c = mapBytesToUnicode[num];
				if (c == '\0' && num != 0)
				{
					decoderFallbackBuffer = dBCSDecoder.FallbackBuffer;
					decoderFallbackBufferHelper = new DecoderFallbackBufferHelper(decoderFallbackBuffer);
					decoderFallbackBufferHelper.InternalInitialize(ptr2 - byteCount, ptr4);
					byte[] bytes3 = new byte[2]
					{
						(byte)(num >> 8),
						(byte)num
					};
					if (!decoderFallbackBufferHelper.InternalFallback(bytes3, bytes, ref chars))
					{
						ThrowCharsOverflow(dBCSDecoder, nothingDecoded: true);
					}
				}
				else
				{
					if (chars >= ptr4)
					{
						ThrowCharsOverflow(dBCSDecoder, nothingDecoded: true);
					}
					*(chars++) = c;
				}
			}
			while (bytes < ptr2)
			{
				int num2 = *bytes;
				bytes++;
				char c2 = mapBytesToUnicode[num2];
				if (c2 == '\ufffe')
				{
					if (bytes < ptr2)
					{
						num2 <<= 8;
						num2 |= *bytes;
						bytes++;
						c2 = mapBytesToUnicode[num2];
					}
					else
					{
						if (dBCSDecoder != null && !dBCSDecoder.MustFlush)
						{
							flag = true;
							dBCSDecoder.bLeftOver = (byte)num2;
							break;
						}
						c2 = '\0';
					}
				}
				if (c2 == '\0' && num2 != 0)
				{
					if (decoderFallbackBuffer == null)
					{
						decoderFallbackBuffer = ((dBCSDecoder != null) ? dBCSDecoder.FallbackBuffer : base.DecoderFallback.CreateFallbackBuffer());
						decoderFallbackBufferHelper = new DecoderFallbackBufferHelper(decoderFallbackBuffer);
						decoderFallbackBufferHelper.InternalInitialize(ptr2 - byteCount, ptr4);
					}
					byte[] array = ((num2 >= 256) ? new byte[2]
					{
						(byte)(num2 >> 8),
						(byte)num2
					} : new byte[1] { (byte)num2 });
					if (!decoderFallbackBufferHelper.InternalFallback(array, bytes, ref chars))
					{
						bytes -= array.Length;
						decoderFallbackBufferHelper.InternalReset();
						ThrowCharsOverflow(dBCSDecoder, bytes == ptr);
						break;
					}
					continue;
				}
				if (chars >= ptr4)
				{
					bytes--;
					if (num2 >= 256)
					{
						bytes--;
					}
					ThrowCharsOverflow(dBCSDecoder, bytes == ptr);
					break;
				}
				*(chars++) = c2;
			}
			if (dBCSDecoder != null)
			{
				if (!flag)
				{
					dBCSDecoder.bLeftOver = 0;
				}
				dBCSDecoder.m_bytesUsed = (int)(bytes - ptr);
			}
			return (int)(chars - ptr3);
		}

		public override int GetMaxByteCount(int charCount)
		{
			if (charCount < 0)
			{
				throw new ArgumentOutOfRangeException("charCount", System.SR.ArgumentOutOfRange_NeedNonNegNum);
			}
			long num = (long)charCount + 1L;
			if (base.EncoderFallback.MaxCharCount > 1)
			{
				num *= base.EncoderFallback.MaxCharCount;
			}
			num *= 2;
			if (num > int.MaxValue)
			{
				throw new ArgumentOutOfRangeException("charCount", System.SR.ArgumentOutOfRange_GetByteCountOverflow);
			}
			return (int)num;
		}

		public override int GetMaxCharCount(int byteCount)
		{
			if (byteCount < 0)
			{
				throw new ArgumentOutOfRangeException("byteCount", System.SR.ArgumentOutOfRange_NeedNonNegNum);
			}
			long num = (long)byteCount + 1L;
			if (base.DecoderFallback.MaxCharCount > 1)
			{
				num *= base.DecoderFallback.MaxCharCount;
			}
			if (num > int.MaxValue)
			{
				throw new ArgumentOutOfRangeException("byteCount", System.SR.ArgumentOutOfRange_GetCharCountOverflow);
			}
			return (int)num;
		}

		public override Decoder GetDecoder()
		{
			return new DBCSDecoder(this);
		}
	}
	internal sealed class InternalDecoderBestFitFallback : DecoderFallback
	{
		internal BaseCodePageEncoding encoding;

		internal char[] arrayBestFit;

		internal char cReplacement = '?';

		public override int MaxCharCount => 1;

		internal InternalDecoderBestFitFallback(BaseCodePageEncoding _encoding)
		{
			encoding = _encoding;
		}

		public override DecoderFallbackBuffer CreateFallbackBuffer()
		{
			return new InternalDecoderBestFitFallbackBuffer(this);
		}

		public override bool Equals([NotNullWhen(true)] object value)
		{
			if (value is InternalDecoderBestFitFallback internalDecoderBestFitFallback)
			{
				return encoding.CodePage == internalDecoderBestFitFallback.encoding.CodePage;
			}
			return false;
		}

		public override int GetHashCode()
		{
			return encoding.CodePage;
		}
	}
	internal sealed class InternalDecoderBestFitFallbackBuffer : DecoderFallbackBuffer
	{
		internal char cBestFit;

		internal int iCount = -1;

		internal int iSize;

		private readonly InternalDecoderBestFitFallback _oFallback;

		private static object s_InternalSyncObject;

		private static object InternalSyncObject
		{
			get
			{
				if (s_InternalSyncObject == null)
				{
					object value = new object();
					Interlocked.CompareExchange<object>(ref s_InternalSyncObject, value, (object)null);
				}
				return s_InternalSyncObject;
			}
		}

		public override int Remaining
		{
			get
			{
				if (iCount <= 0)
				{
					return 0;
				}
				return iCount;
			}
		}

		public InternalDecoderBestFitFallbackBuffer(InternalDecoderBestFitFallback fallback)
		{
			_oFallback = fallback;
			if (_oFallback.arrayBestFit != null)
			{
				return;
			}
			lock (InternalSyncObject)
			{
				InternalDecoderBestFitFallback oFallback = _oFallback;
				if (oFallback.arrayBestFit == null)
				{
					oFallback.arrayBestFit = fallback.encoding.GetBestFitBytesToUnicodeData();
				}
			}
		}

		public override bool Fallback(byte[] bytesUnknown, int index)
		{
			cBestFit = TryBestFit(bytesUnknown);
			if (cBestFit == '\0')
			{
				cBestFit = _oFallback.cReplacement;
			}
			iCount = (iSize = 1);
			return true;
		}

		public override char GetNextChar()
		{
			iCount--;
			if (iCount < 0)
			{
				return '\0';
			}
			if (iCount == int.MaxValue)
			{
				iCount = -1;
				return '\0';
			}
			return cBestFit;
		}

		public override bool MovePrevious()
		{
			if (iCount >= 0)
			{
				iCount++;
			}
			if (iCount >= 0)
			{
				return iCount <= iSize;
			}
			return false;
		}

		public override void Reset()
		{
			iCount = -1;
		}

		private char TryBestFit(byte[] bytesCheck)
		{
			int num = 0;
			int num2 = _oFallback.arrayBestFit.Length;
			if (num2 == 0)
			{
				return '\0';
			}
			if (bytesCheck.Length == 0 || bytesCheck.Length > 2)
			{
				return '\0';
			}
			char c = ((bytesCheck.Length != 1) ? ((char)((bytesCheck[0] << 8) + bytesCheck[1])) : ((char)bytesCheck[0]));
			if (c < _oFallback.arrayBestFit[0] || c > _oFallback.arrayBestFit[num2 - 2])
			{
				return '\0';
			}
			int num3;
			while ((num3 = num2 - num) > 6)
			{
				int num4 = (num3 / 2 + num) & 0xFFFE;
				char c2 = _oFallback.arrayBestFit[num4];
				if (c2 == c)
				{
					return _oFallback.arrayBestFit[num4 + 1];
				}
				if (c2 < c)
				{
					num = num4;
				}
				else
				{
					num2 = num4;
				}
			}
			for (int num4 = num; num4 < num2; num4 += 2)
			{
				if (_oFallback.arrayBestFit[num4] == c)
				{
					return _oFallback.arrayBestFit[num4 + 1];
				}
			}
			return '\0';
		}
	}
	internal struct DecoderFallbackBufferHelper
	{
		internal unsafe byte* byteStart;

		internal unsafe char* charEnd;

		private readonly DecoderFallbackBuffer _fallbackBuffer;

		public unsafe DecoderFallbackBufferHelper(DecoderFallbackBuffer fallbackBuffer)
		{
			_fallbackBuffer = fallbackBuffer;
			byteStart = null;
			charEnd = null;
		}

		internal unsafe void InternalReset()
		{
			byteStart = null;
			_fallbackBuffer.Reset();
		}

		internal unsafe void InternalInitialize(byte* _byteStart, char* _charEnd)
		{
			byteStart = _byteStart;
			charEnd = _charEnd;
		}

		internal unsafe bool InternalFallback(byte[] bytes, byte* pBytes, ref char* chars)
		{
			if (_fallbackBuffer.Fallback(bytes, (int)(pBytes - byteStart - bytes.Length)))
			{
				char* ptr = chars;
				bool flag = false;
				char nextChar;
				while ((nextChar = _fallbackBuffer.GetNextChar()) != 0)
				{
					if (char.IsSurrogate(nextChar))
					{
						if (char.IsHighSurrogate(nextChar))
						{
							if (flag)
							{
								throw new ArgumentException(System.SR.Argument_InvalidCharSequenceNoIndex);
							}
							flag = true;
						}
						else
						{
							if (!flag)
							{
								throw new ArgumentException(System.SR.Argument_InvalidCharSequenceNoIndex);
							}
							flag = false;
						}
					}
					if (ptr >= charEnd)
					{
						return false;
					}
					*(ptr++) = nextChar;
				}
				if (flag)
				{
					throw new ArgumentException(System.SR.Argument_InvalidCharSequenceNoIndex);
				}
				chars = ptr;
			}
			return true;
		}

		internal unsafe int InternalFallback(byte[] bytes, byte* pBytes)
		{
			if (_fallbackBuffer.Fallback(bytes, (int)(pBytes - byteStart - bytes.Length)))
			{
				int num = 0;
				bool flag = false;
				char nextChar;
				while ((nextChar = _fallbackBuffer.GetNextChar()) != 0)
				{
					if (char.IsSurrogate(nextChar))
					{
						if (char.IsHighSurrogate(nextChar))
						{
							if (flag)
							{
								throw new ArgumentException(System.SR.Argument_InvalidCharSequenceNoIndex);
							}
							flag = true;
						}
						else
						{
							if (!flag)
							{
								throw new ArgumentException(System.SR.Argument_InvalidCharSequenceNoIndex);
							}
							flag = false;
						}
					}
					num++;
				}
				if (flag)
				{
					throw new ArgumentException(System.SR.Argument_InvalidCharSequenceNoIndex);
				}
				return num;
			}
			return 0;
		}
	}
	internal class DecoderNLS : Decoder, ISerializable
	{
		protected EncodingNLS m_encoding;

		protected bool m_mustFlush;

		internal bool m_throwOnOverflow;

		internal int m_bytesUsed;

		internal DecoderFallback m_fallback;

		internal DecoderFallbackBuffer m_fallbackBuffer;

		internal new DecoderFallback Fallback => m_fallback;

		internal bool InternalHasFallbackBuffer => m_fallbackBuffer != null;

		public new DecoderFallbackBuffer FallbackBuffer
		{
			get
			{
				if (m_fallbackBuffer == null)
				{
					m_fallbackBuffer = ((m_fallback != null) ? m_fallback.CreateFallbackBuffer() : DecoderFallback.ReplacementFallback.CreateFallbackBuffer());
				}
				return m_fallbackBuffer;
			}
		}

		public bool MustFlush => m_mustFlush;

		internal virtual bool HasState => false;

		internal DecoderNLS(EncodingNLS encoding)
		{
			m_encoding = encoding;
			m_fallback = m_encoding.DecoderFallback;
			Reset();
		}

		void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
		{
			throw new PlatformNotSupportedException();
		}

		public override void Reset()
		{
			m_fallbackBuffer?.Reset();
		}

		public override int GetCharCount(byte[] bytes, int index, int count)
		{
			return GetCharCount(bytes, index, count, flush: false);
		}

		public unsafe override int GetCharCount(byte[] bytes, int index, int count, bool flush)
		{
			if (bytes == null)
			{
				throw new ArgumentNullException("bytes");
			}
			if (index < 0 || count < 0)
			{
				throw new ArgumentOutOfRangeException((index < 0) ? "index" : "count", System.SR.ArgumentOutOfRange_NeedNonNegNum);
			}
			if (bytes.Length - index < count)
			{
				throw new ArgumentOutOfRangeException("bytes", System.SR.ArgumentOutOfRange_IndexCountBuffer);
			}
			fixed (byte* ptr = &CodePagesEncodingProvider.GetNonNullPinnableReference(bytes))
			{
				return GetCharCount(ptr + index, count, flush);
			}
		}

		public unsafe override int GetCharCount(byte* bytes, int count, bool flush)
		{
			if (bytes == null)
			{
				throw new ArgumentNullException("bytes");
			}
			if (count < 0)
			{
				throw new ArgumentOutOfRangeException("count", System.SR.ArgumentOutOfRange_NeedNonNegNum);
			}
			m_mustFlush = flush;
			m_throwOnOverflow = true;
			return m_encoding.GetCharCount(bytes, count, this);
		}

		public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
		{
			return GetChars(bytes, byteIndex, byteCount, chars, charIndex, flush: false);
		}

		public unsafe override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex, bool flush)
		{
			if (bytes == null)
			{
				throw new ArgumentNullException("bytes");
			}
			if (chars == null)
			{
				throw new ArgumentNullException("chars");
			}
			if (byteIndex < 0 || byteCount < 0)
			{
				throw new ArgumentOutOfRangeException((byteIndex < 0) ? "byteIndex" : "byteCount", System.SR.ArgumentOutOfRange_NeedNonNegNum);
			}
			if (bytes.Length - byteIndex < byteCount)
			{
				throw new ArgumentOutOfRangeException("bytes", System.SR.ArgumentOutOfRange_IndexCountBuffer);
			}
			if (charIndex < 0 || charIndex > chars.Length)
			{
				throw new ArgumentOutOfRangeException("charIndex", System.SR.ArgumentOutOfRange_IndexMustBeLessOrEqual);
			}
			int charCount = chars.Length - charIndex;
			fixed (byte* ptr = &CodePagesEncodingProvider.GetNonNullPinnableReference(bytes))
			{
				fixed (char* ptr2 = &CodePagesEncodingProvider.GetNonNullPinnableReference(chars))
				{
					return GetChars(ptr + byteIndex, byteCount, ptr2 + charIndex, charCount, flush);
				}
			}
		}

		public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount, bool flush)
		{
			if (bytes == null)
			{
				throw new ArgumentNullException("bytes");
			}
			if (chars == null)
			{
				throw new ArgumentNullException("chars");
			}
			if (byteCount < 0 || charCount < 0)
			{
				throw new ArgumentOutOfRangeException((byteCount < 0) ? "byteCount" : "charCount", System.SR.ArgumentOutOfRange_NeedNonNegNum);
			}
			m_mustFlush = flush;
			m_throwOnOverflow = true;
			return m_encoding.GetChars(bytes, byteCount, chars, charCount, this);
		}

		public unsafe override void Convert(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex, int charCount, bool flush, out int bytesUsed, out int charsUsed, out bool completed)
		{
			if (bytes == null)
			{
				throw new ArgumentNullException("bytes");
			}
			if (chars == null)
			{
				throw new ArgumentNullException("chars");
			}
			if (byteIndex < 0 || byteCount < 0)
			{
				throw new ArgumentOutOfRangeException((byteIndex < 0) ? "byteIndex" : "byteCount", System.SR.ArgumentOutOfRange_NeedNonNegNum);
			}
			if (charIndex < 0 || charCount < 0)
			{
				throw new ArgumentOutOfRangeException((charIndex < 0) ? "charIndex" : "charCount", System.SR.ArgumentOutOfRange_NeedNonNegNum);
			}
			if (bytes.Length - byteIndex < byteCount)
			{
				throw new ArgumentOutOfRangeException("bytes", System.SR.ArgumentOutOfRange_IndexCountBuffer);
			}
			if (chars.Length - charIndex < charCount)
			{
				throw new ArgumentOutOfRangeException("chars", System.SR.ArgumentOutOfRange_IndexCountBuffer);
			}
			fixed (byte* ptr = &CodePagesEncodingProvider.GetNonNullPinnableReference(bytes))
			{
				fixed (char* ptr2 = &CodePagesEncodingProvider.GetNonNullPinnableReference(chars))
				{
					Convert(ptr + byteIndex, byteCount, ptr2 + charIndex, charCount, flush, out bytesUsed, out charsUsed, out completed);
				}
			}
		}

		public unsafe override void Convert(byte* bytes, int byteCount, char* chars, int charCount, bool flush, out int bytesUsed, out int charsUsed, out bool completed)
		{
			if (bytes == null)
			{
				throw new ArgumentNullException("bytes");
			}
			if (chars == null)
			{
				throw new ArgumentNullException("chars");
			}
			if (byteCount < 0 || charCount < 0)
			{
				throw new ArgumentOutOfRangeException((byteCount < 0) ? "byteCount" : "charCount", System.SR.ArgumentOutOfRange_NeedNonNegNum);
			}
			m_mustFlush = flush;
			m_throwOnOverflow = false;
			m_bytesUsed = 0;
			charsUsed = m_encoding.GetChars(bytes, byteCount, chars, charCount, this);
			bytesUsed = m_bytesUsed;
			completed = bytesUsed == byteCount && (!flush || !HasState) && (m_fallbackBuffer == null || m_fallbackBuffer.Remaining == 0);
		}

		internal void ClearMustFlush()
		{
			m_mustFlush = false;
		}
	}
	internal sealed class InternalEncoderBestFitFallback : EncoderFallback
	{
		internal BaseCodePageEncoding encoding;

		internal char[] arrayBestFit;

		public override int MaxCharCount => 1;

		internal InternalEncoderBestFitFallback(BaseCodePageEncoding _encoding)
		{
			encoding = _encoding;
		}

		public override EncoderFallbackBuffer CreateFallbackBuffer()
		{
			return new InternalEncoderBestFitFallbackBuffer(this);
		}

		public override bool Equals([NotNullWhen(true)] object value)
		{
			if (value is InternalEncoderBestFitFallback internalEncoderBestFitFallback)
			{
				return encoding.CodePage == internalEncoderBestFitFallback.encoding.CodePage;
			}
			return false;
		}

		public override int GetHashCode()
		{
			return encoding.CodePage;
		}
	}
	internal sealed class InternalEncoderBestFitFallbackBuffer : EncoderFallbackBuffer
	{
		private char _cBestFit;

		private readonly InternalEncoderBestFitFallback _oFallback;

		private int _iCount = -1;

		private int _iSize;

		private static object s_InternalSyncObject;

		private static object InternalSyncObject
		{
			get
			{
				if (s_InternalSyncObject == null)
				{
					object value = new object();
					Interlocked.CompareExchange<object>(ref s_InternalSyncObject, value, (object)null);
				}
				return s_InternalSyncObject;
			}
		}

		public override int Remaining
		{
			get
			{
				if (_iCount <= 0)
				{
					return 0;
				}
				return _iCount;
			}
		}

		public InternalEncoderBestFitFallbackBuffer(InternalEncoderBestFitFallback fallback)
		{
			_oFallback = fallback;
			if (_oFallback.arrayBestFit != null)
			{
				return;
			}
			lock (InternalSyncObject)
			{
				InternalEncoderBestFitFallback oFallback = _oFallback;
				if (oFallback.arrayBestFit == null)
				{
					oFallback.arrayBestFit = fallback.encoding.GetBestFitUnicodeToBytesData();
				}
			}
		}

		public override bool Fallback(char charUnknown, int index)
		{
			_iCount = (_iSize = 1);
			_cBestFit = TryBestFit(charUnknown);
			if (_cBestFit == '\0')
			{
				_cBestFit = '?';
			}
			return true;
		}

		public override bool Fallback(char charUnknownHigh, char charUnknownLow, int index)
		{
			if (!char.IsHighSurrogate(charUnknownHigh))
			{
				throw new ArgumentOutOfRangeException("charUnknownHigh", System.SR.Format(System.SR.ArgumentOutOfRange_Range, 55296, 56319));
			}
			if (!char.IsLowSurrogate(charUnknownLow))
			{
				throw new ArgumentOutOfRangeException("charUnknownLow", System.SR.Format(System.SR.ArgumentOutOfRange_Range, 56320, 57343));
			}
			_cBestFit = '?';
			_iCount = (_iSize = 2);
			return true;
		}

		public override char GetNextChar()
		{
			_iCount--;
			if (_iCount < 0)
			{
				return '\0';
			}
			if (_iCount == int.MaxValue)
			{
				_iCount = -1;
				return '\0';
			}
			return _cBestFit;
		}

		public override bool MovePrevious()
		{
			if (_iCount >= 0)
			{
				_iCount++;
			}
			if (_iCount >= 0)
			{
				return _iCount <= _iSize;
			}
			return false;
		}

		public override void Reset()
		{
			_iCount = -1;
		}

		private char TryBestFit(char cUnknown)
		{
			int num = 0;
			int num2 = _oFallback.arrayBestFit.Length;
			int num3;
			while ((num3 = num2 - num) > 6)
			{
				int num4 = (num3 / 2 + num) & 0xFFFE;
				char c = _oFallback.arrayBestFit[num4];
				if (c == cUnknown)
				{
					return _oFallback.arrayBestFit[num4 + 1];
				}
				if (c < cUnknown)
				{
					num = num4;
				}
				else
				{
					num2 = num4;
				}
			}
			for (int num4 = num; num4 < num2; num4 += 2)
			{
				if (_oFallback.arrayBestFit[num4] == cUnknown)
				{
					return _oFallback.arrayBestFit[num4 + 1];
				}
			}
			return '\0';
		}
	}
	internal struct EncoderFallbackBufferHelper
	{
		internal unsafe char* charStart;

		internal unsafe char* charEnd;

		internal System.Text.EncoderNLS encoder;

		internal bool setEncoder;

		internal bool bUsedEncoder;

		internal bool bFallingBack;

		internal int iRecursionCount;

		private const int iMaxRecursion = 250;

		private readonly EncoderFallbackBuffer _fallbackBuffer;

		public unsafe EncoderFallbackBufferHelper(EncoderFallbackBuffer fallbackBuffer)
		{
			_fallbackBuffer = fallbackBuffer;
			bFallingBack = (bUsedEncoder = (setEncoder = false));
			iRecursionCount = 0;
			charEnd = (charStart = null);
			encoder = null;
		}

		internal unsafe void InternalReset()
		{
			charStart = null;
			bFallingBack = false;
			iRecursionCount = 0;
			_fallbackBuffer.Reset();
		}

		internal unsafe void InternalInitialize(char* _charStart, char* _charEnd, System.Text.EncoderNLS _encoder, bool _setEncoder)
		{
			charStart = _charStart;
			charEnd = _charEnd;
			encoder = _encoder;
			setEncoder = _setEncoder;
			bUsedEncoder = false;
			bFallingBack = false;
			iRecursionCount = 0;
		}

		internal char InternalGetNextChar()
		{
			char nextChar = _fallbackBuffer.GetNextChar();
			bFallingBack = nextChar != '\0';
			if (nextChar == '\0')
			{
				iRecursionCount = 0;
			}
			return nextChar;
		}

		internal unsafe bool InternalFallback(char ch, ref char* chars)
		{
			int index = (int)(chars - charStart) - 1;
			if (char.IsHighSurrogate(ch))
			{
				if (chars >= charEnd)
				{
					if (encoder != null && !encoder.MustFlush)
					{
						if (setEncoder)
						{
							bUsedEncoder = true;
							encoder.charLeftOver = ch;
						}
						bFallingBack = false;
						return false;
					}
				}
				else
				{
					char c = *chars;
					if (char.IsLowSurrogate(c))
					{
						if (bFallingBack && iRecursionCount++ > 250)
						{
							ThrowLastCharRecursive(char.ConvertToUtf32(ch, c));
						}
						chars++;
						bFallingBack = _fallbackBuffer.Fallback(ch, c, index);
						return bFallingBack;
					}
				}
			}
			if (bFallingBack && iRecursionCount++ > 250)
			{
				ThrowLastCharRecursive(ch);
			}
			bFallingBack = _fallbackBuffer.Fallback(ch, index);
			return bFallingBack;
		}

		internal static void ThrowLastCharRecursive(int charRecursive)
		{
			throw new ArgumentException(System.SR.Format(System.SR.Argument_RecursiveFallback, charRecursive), "chars");
		}
	}
	internal class EncoderNLS : Encoder, ISerializable
	{
		internal char charLeftOver;

		protected EncodingNLS m_encoding;

		protected bool m_mustFlush;

		internal bool m_throwOnOverflow;

		internal int m_charsUsed;

		internal EncoderFallback m_fallback;

		internal EncoderFallbackBuffer m_fallbackBuffer;

		internal new EncoderFallback Fallback => m_fallback;

		internal bool InternalHasFallbackBuffer => m_fallbackBuffer != null;

		public new EncoderFallbackBuffer FallbackBuffer
		{
			get
			{
				if (m_fallbackBuffer == null)
				{
					m_fallbackBuffer = ((m_fallback != null) ? m_fallback.CreateFallbackBuffer() : EncoderFallback.ReplacementFallback.CreateFallbackBuffer());
				}
				return m_fallbackBuffer;
			}
		}

		public Encoding Encoding => m_encoding;

		public bool MustFlush => m_mustFlush;

		internal virtual bool HasState => charLeftOver != '\0';

		internal EncoderNLS(EncodingNLS encoding)
		{
			m_encoding = encoding;
			m_fallback = m_encoding.EncoderFallback;
			Reset();
		}

		void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
		{
			throw new PlatformNotSupportedException();
		}

		public override void Reset()
		{
			charLeftOver = '\0';
			m_fallbackBuffer?.Reset();
		}

		public unsafe override int GetByteCount(char[] chars, int index, int count, bool flush)
		{
			if (chars == null)
			{
				throw new ArgumentNullException("chars");
			}
			if (index < 0 || count < 0)
			{
				throw new ArgumentOutOfRangeException((index < 0) ? "index" : "count", System.SR.ArgumentOutOfRange_NeedNonNegNum);
			}
			if (chars.Length - index < count)
			{
				throw new ArgumentOutOfRangeException("chars", System.SR.ArgumentOutOfRange_IndexCountBuffer);
			}
			fixed (char* ptr = &CodePagesEncodingProvider.GetNonNullPinnableReference(chars))
			{
				return GetByteCount(ptr + index, count, flush);
			}
		}

		public unsafe override int GetByteCount(char* chars, int count, bool flush)
		{
			if (chars == null)
			{
				throw new ArgumentNullException("chars");
			}
			if (count < 0)
			{
				throw new ArgumentOutOfRangeException("count", System.SR.ArgumentOutOfRange_NeedNonNegNum);
			}
			m_mustFlush = flush;
			m_throwOnOverflow = true;
			return m_encoding.GetByteCount(chars, count, this);
		}

		public unsafe override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex, bool flush)
		{
			if (chars == null)
			{
				throw new ArgumentNullException("chars");
			}
			if (bytes == null)
			{
				throw new ArgumentNullException("bytes");
			}
			if (charIndex < 0 || charCount < 0)
			{
				throw new ArgumentOutOfRangeException((charIndex < 0) ? "charIndex" : "charCount", System.SR.ArgumentOutOfRange_NeedNonNegNum);
			}
			if (chars.Length - charIndex < charCount)
			{
				throw new ArgumentOutOfRangeException("chars", System.SR.ArgumentOutOfRange_IndexCountBuffer);
			}
			if (byteIndex < 0 || byteIndex > bytes.Length)
			{
				throw new ArgumentOutOfRangeException("byteIndex", System.SR.ArgumentOutOfRange_IndexMustBeLessOrEqual);
			}
			int byteCount = bytes.Length - byteIndex;
			fixed (char* ptr = &CodePagesEncodingProvider.GetNonNullPinnableReference(chars))
			{
				fixed (byte* ptr2 = &CodePagesEncodingProvider.GetNonNullPinnableReference(bytes))
				{
					return GetBytes(ptr + charIndex, charCount, ptr2 + byteIndex, byteCount, flush);
				}
			}
		}

		public unsafe override int GetBytes(char* chars, int charCount, byte* bytes, int byteCount, bool flush)
		{
			if (chars == null)
			{
				throw new ArgumentNullException("chars");
			}
			if (bytes == null)
			{
				throw new ArgumentNullException("bytes");
			}
			if (byteCount < 0 || charCount < 0)
			{
				throw new ArgumentOutOfRangeException((byteCount < 0) ? "byteCount" : "charCount", System.SR.ArgumentOutOfRange_NeedNonNegNum);
			}
			m_mustFlush = flush;
			m_throwOnOverflow = true;
			return m_encoding.GetBytes(chars, charCount, bytes, byteCount, this);
		}

		public unsafe override void Convert(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex, int byteCount, bool flush, out int charsUsed, out int bytesUsed, out bool completed)
		{
			if (chars == null)
			{
				throw new ArgumentNullException("chars");
			}
			if (bytes == null)
			{
				throw new ArgumentNullException("bytes");
			}
			if (charIndex < 0 || charCount < 0)
			{
				throw new ArgumentOutOfRangeException((charIndex < 0) ? "charIndex" : "charCount", System.SR.ArgumentOutOfRange_NeedNonNegNum);
			}
			if (byteIndex < 0 || byteCount < 0)
			{
				throw new ArgumentOutOfRangeException((byteIndex < 0) ? "byteIndex" : "byteCount", System.SR.ArgumentOutOfRange_NeedNonNegNum);
			}
			if (chars.Length - charIndex < charCount)
			{
				throw new ArgumentOutOfRangeException("chars", System.SR.ArgumentOutOfRange_IndexCountBuffer);
			}
			if (bytes.Length - byteIndex < byteCount)
			{
				throw new ArgumentOutOfRangeException("bytes", System.SR.ArgumentOutOfRange_IndexCountBuffer);
			}
			fixed (char* ptr = &CodePagesEncodingProvider.GetNonNullPinnableReference(chars))
			{
				fixed (byte* ptr2 = &CodePagesEncodingProvider.GetNonNullPinnableReference(bytes))
				{
					Convert(ptr + charIndex, charCount, ptr2 + byteIndex, byteCount, flush, out charsUsed, out bytesUsed, out completed);
				}
			}
		}

		public unsafe override void Convert(char* chars, int charCount, byte* bytes, int byteCount, bool flush, out int charsUsed, out int bytesUsed, out bool completed)
		{
			if (chars == null)
			{
				throw new ArgumentNullException("chars");
			}
			if (bytes == null)
			{
				throw new ArgumentNullException("bytes");
			}
			if (charCount < 0 || byteCount < 0)
			{
				throw new ArgumentOutOfRangeException((charCount < 0) ? "charCount" : "byteCount", System.SR.ArgumentOutOfRange_NeedNonNegNum);
			}
			m_mustFlush = flush;
			m_throwOnOverflow = false;
			m_charsUsed = 0;
			bytesUsed = m_encoding.GetBytes(chars, charCount, bytes, byteCount, this);
			charsUsed = m_charsUsed;
			completed = charsUsed == charCount && (!flush || !HasState) && (m_fallbackBuffer == null || m_fallbackBuffer.Remaining == 0);
		}

		internal void ClearMustFlush()
		{
			m_mustFlush = false;
		}
	}
	internal sealed class EncodingByteBuffer
	{
		private unsafe byte* _bytes;

		private unsafe readonly byte* _byteStart;

		private unsafe readonly byte* _byteEnd;

		private unsafe char* _chars;

		private unsafe readonly char* _charStart;

		private unsafe readonly char* _charEnd;

		private int _byteCountResult;

		private readonly EncodingNLS _enc;

		private readonly System.Text.EncoderNLS _encoder;

		internal EncoderFallbackBuffer fallbackBuffer;

		internal EncoderFallbackBufferHelper fallbackBufferHelper;

		internal unsafe bool MoreData
		{
			get
			{
				if (fallbackBuffer.Remaining <= 0)
				{
					return _chars < _charEnd;
				}
				return true;
			}
		}

		internal unsafe int CharsUsed => (int)(_chars - _charStart);

		internal int Count => _byteCountResult;

		internal unsafe EncodingByteBuffer(EncodingNLS inEncoding, System.Text.EncoderNLS inEncoder, byte* inByteStart, int inByteCount, char* inCharStart, int inCharCount)
		{
			_enc = inEncoding;
			_encoder = inEncoder;
			_charStart = inCharStart;
			_chars = inCharStart;
			_charEnd = inCharStart + inCharCount;
			_bytes = inByteStart;
			_byteStart = inByteStart;
			_byteEnd = inByteStart + inByteCount;
			if (_encoder == null)
			{
				fallbackBuffer = _enc.EncoderFallback.CreateFallbackBuffer();
			}
			else
			{
				fallbackBuffer = _encoder.FallbackBuffer;
				if (_encoder.m_throwOnOverflow && _encoder.InternalHasFallbackBuffer && fallbackBuffer.Remaining > 0)
				{
					throw new ArgumentException(System.SR.Format(System.SR.Argument_EncoderFallbackNotEmpty, _encoder.Encoding.EncodingName, _encoder.Fallback.GetType()));
				}
			}
			fallbackBufferHelper = new EncoderFallbackBufferHelper(fallbackBuffer);
			fallbackBufferHelper.InternalInitialize(_chars, _charEnd, _encoder, _bytes != null);
		}

		internal unsafe bool AddByte(byte b, int moreBytesExpected)
		{
			if (_bytes != null)
			{
				if (_bytes >= _byteEnd - moreBytesExpected)
				{
					MovePrevious(bThrow: true);
					return false;
				}
				*(_bytes++) = b;
			}
			_byteCountResult++;
			return true;
		}

		internal bool AddByte(byte b1)
		{
			return AddByte(b1, 0);
		}

		internal bool AddByte(byte b1, byte b2)
		{
			return AddByte(b1, b2, 0);
		}

		internal bool AddByte(byte b1, byte b2, int moreBytesExpected)
		{
			if (AddByte(b1, 1 + moreBytesExpected))
			{
				return AddByte(b2, moreBytesExpected);
			}
			return false;
		}

		internal bool AddByte(byte b1, byte b2, byte b3)
		{
			return AddByte(b1, b2, b3, 0);
		}

		internal bool AddByte(byte b1, byte b2, byte b3, int moreBytesExpected)
		{
			if (AddByte(b1, 2 + moreBytesExpected) && AddByte(b2, 1 + moreBytesExpected))
			{
				return AddByte(b3, moreBytesExpected);
			}
			return false;
		}

		internal bool AddByte(byte b1, byte b2, byte b3, byte b4)
		{
			if (AddByte(b1, 3) && AddByte(b2, 2) && AddByte(b3, 1))
			{
				return AddByte(b4, 0);
			}
			return false;
		}

		internal unsafe void MovePrevious(bool bThrow)
		{
			if (fallbackBufferHelper.bFallingBack)
			{
				fallbackBuffer.MovePrevious();
			}
			else if (_chars > _charStart)
			{
				_chars--;
			}
			if (bThrow)
			{
				_enc.ThrowBytesOverflow(_encoder, _bytes == _byteStart);
			}
		}

		internal unsafe bool Fallback(char charFallback)
		{
			return fallbackBufferHelper.InternalFallback(charFallback, ref _chars);
		}

		internal unsafe char GetNextChar()
		{
			char c = fallbackBufferHelper.InternalGetNextChar();
			if (c == '\0' && _chars < _charEnd)
			{
				c = *(_chars++);
			}
			return c;
		}
	}
	internal sealed class EncodingCharBuffer
	{
		private unsafe char* _chars;

		private unsafe readonly char* _charStart;

		private unsafe readonly char* _charEnd;

		private int _charCountResult;

		private readonly EncodingNLS _enc;

		private readonly System.Text.DecoderNLS _decoder;

		private unsafe readonly byte* _byteStart;

		private unsafe readonly byte* _byteEnd;

		private unsafe byte* _bytes;

		private readonly DecoderFallbackBuffer _fallbackBuffer;

		private DecoderFallbackBufferHelper _fallbackBufferHelper;

		internal unsafe bool MoreData => _bytes < _byteEnd;

		internal unsafe int BytesUsed => (int)(_bytes - _byteStart);

		internal int Count => _charCountResult;

		internal unsafe EncodingCharBuffer(EncodingNLS enc, System.Text.DecoderNLS decoder, char* charStart, int charCount, byte* byteStart, int byteCount)
		{
			_enc = enc;
			_decoder = decoder;
			_chars = charStart;
			_charStart = charStart;
			_charEnd = charStart + charCount;
			_byteStart = byteStart;
			_bytes = byteStart;
			_byteEnd = byteStart + byteCount;
			if (_decoder == null)
			{
				_fallbackBuffer = enc.DecoderFallback.CreateFallbackBuffer();
			}
			else
			{
				_fallbackBuffer = _decoder.FallbackBuffer;
			}
			_fallbackBufferHelper = new DecoderFallbackBufferHelper(_fallbackBuffer);
			_fallbackBufferHelper.InternalInitialize(_bytes, _charEnd);
		}

		internal unsafe bool AddChar(char ch, int numBytes)
		{
			if (_chars != null)
			{
				if (_chars >= _charEnd)
				{
					_bytes -= numBytes;
					_enc.ThrowCharsOverflow(_decoder, _bytes <= _byteStart);
					return false;
				}
				*(_chars++) = ch;
			}
			_charCountResult++;
			return true;
		}

		internal bool AddChar(char ch)
		{
			return AddChar(ch, 1);
		}

		internal unsafe bool AddChar(char ch1, char ch2, int numBytes)
		{
			if (_chars >= _charEnd - 1)
			{
				_bytes -= numBytes;
				_enc.ThrowCharsOverflow(_decoder, _bytes <= _byteStart);
				return false;
			}
			if (AddChar(ch1, numBytes))
			{
				return AddChar(ch2, numBytes);
			}
			return false;
		}

		internal unsafe void AdjustBytes(int count)
		{
			_bytes += count;
		}

		internal unsafe bool EvenMoreData(int count)
		{
			return _bytes <= _byteEnd - count;
		}

		internal unsafe byte GetNextByte()
		{
			if (_bytes >= _byteEnd)
			{
				return 0;
			}
			return *(_bytes++);
		}

		internal bool Fallback(byte fallbackByte)
		{
			byte[] byteBuffer = new byte[1] { fallbackByte };
			return Fallback(byteBuffer);
		}

		internal bool Fallback(byte byte1, byte byte2)
		{
			byte[] byteBuffer = new byte[2] { byte1, byte2 };
			return Fallback(byteBuffer);
		}

		internal bool Fallback(byte byte1, byte byte2, byte byte3, byte byte4)
		{
			byte[] byteBuffer = new byte[4] { byte1, byte2, byte3, byte4 };
			return Fallback(byteBuffer);
		}

		internal unsafe bool Fallback(byte[] byteBuffer)
		{
			if (_chars != null)
			{
				char* chars = _chars;
				if (!_fallbackBufferHelper.InternalFallback(byteBuffer, _bytes, ref _chars))
				{
					_bytes -= byteBuffer.Length;
					_fallbackBufferHelper.InternalReset();
					_enc.ThrowCharsOverflow(_decoder, _chars == _charStart);
					return false;
				}
				_charCountResult += (int)(_chars - chars);
			}
			else
			{
				_charCountResult += _fallbackBufferHelper.InternalFallback(byteBuffer, _bytes);
			}
			return true;
		}
	}
	internal abstract class EncodingNLS : Encoding
	{
		private string _encodingName;

		private string _webName;

		public override string EncodingName
		{
			get
			{
				if (_encodingName == null)
				{
					_encodingName = GetLocalizedEncodingNameResource(CodePage);
					if (_encodingName == null)
					{
						throw new NotSupportedException(System.SR.Format(System.SR.MissingEncodingNameResource, WebName, CodePage));
					}
					if (_encodingName.StartsWith("Globalization_cp_", StringComparison.OrdinalIgnoreCase))
					{
						_encodingName = System.Text.EncodingTable.GetEnglishNameFromCodePage(CodePage);
						if (_encodingName == null)
						{
							throw new NotSupportedException(System.SR.Format(System.SR.MissingEncodingNameResource, WebName, CodePage));
						}
					}
				}
				return _encodingName;
			}
		}

		public override string WebName
		{
			get
			{
				if (_webName == null)
				{
					_webName = System.Text.EncodingTable.GetWebNameFromCodePage(CodePage);
					if (_webName == null)
					{
						throw new NotSupportedException(System.SR.Format(System.SR.NotSupported_NoCodepageData, CodePage));
					}
				}
				return _webName;
			}
		}

		public override string HeaderName => CodePage switch
		{
			932 => "iso-2022-jp", 
			50221 => "iso-2022-jp", 
			50225 => "euc-kr", 
			_ => WebName, 
		};

		public override string BodyName => CodePage switch
		{
			932 => "iso-2022-jp", 
			1250 => "iso-8859-2", 
			1251 => "koi8-r", 
			1252 => "iso-8859-1", 
			1253 => "iso-8859-7", 
			1254 => "iso-8859-9", 
			50221 => "iso-2022-jp", 
			50225 => "iso-2022-kr", 
			_ => WebName, 
		};

		protected EncodingNLS(int codePage)
			: base(codePage)
		{
		}

		protected EncodingNLS(int codePage, EncoderFallback enc, DecoderFallback dec)
			: base(codePage, enc, dec)
		{
		}

		public unsafe abstract int GetByteCount(char* chars, int count, System.Text.EncoderNLS encoder);

		public unsafe abstract int GetBytes(char* chars, int charCount, byte* bytes, int byteCount, System.Text.EncoderNLS encoder);

		public unsafe abstract int GetCharCount(byte* bytes, int count, System.Text.DecoderNLS decoder);

		public unsafe abstract int GetChars(byte* bytes, int byteCount, char* chars, int charCount, System.Text.DecoderNLS decoder);

		public unsafe override int GetByteCount(char[] chars, int index, int count)
		{
			if (chars == null)
			{
				throw new ArgumentNullException("chars");
			}
			if (index < 0 || count < 0)
			{
				throw new ArgumentOutOfRangeException((index < 0) ? "index" : "count", System.SR.ArgumentOutOfRange_NeedNonNegNum);
			}
			if (chars.Length - index < count)
			{
				throw new ArgumentOutOfRangeException("chars", System.SR.ArgumentOutOfRange_IndexCountBuffer);
			}
			if (chars.Length == 0)
			{
				return 0;
			}
			fixed (char* ptr = &chars[0])
			{
				return GetByteCount(ptr + index, count, null);
			}
		}

		public unsafe override int GetByteCount(string s)
		{
			if (s == null)
			{
				throw new ArgumentNullException("s");
			}
			fixed (char* chars = s)
			{
				return GetByteCount(chars, s.Length, null);
			}
		}

		public unsafe override int GetByteCount(char* chars, int count)
		{
			if (chars == null)
			{
				throw new ArgumentNullException("chars");
			}
			if (count < 0)
			{
				throw new ArgumentOutOfRangeException("count", System.SR.ArgumentOutOfRange_NeedNonNegNum);
			}
			return GetByteCount(chars, count, null);
		}

		public unsafe override int GetBytes(string s, int charIndex, int charCount, byte[] bytes, int byteIndex)
		{
			if (s == null)
			{
				throw new ArgumentNullException("s");
			}
			if (bytes == null)
			{
				throw new ArgumentNullException("bytes");
			}
			if (charIndex < 0 || charCount < 0)
			{
				throw new ArgumentOutOfRangeException((charIndex < 0) ? "charIndex" : "charCount", System.SR.ArgumentOutOfRange_NeedNonNegNum);
			}
			if (s.Length - charIndex < charCount)
			{
				throw new ArgumentOutOfRangeException("s", System.SR.ArgumentOutOfRange_IndexCount);
			}
			if (byteIndex < 0 || byteIndex > bytes.Length)
			{
				throw new ArgumentOutOfRangeException("byteIndex", System.SR.ArgumentOutOfRange_IndexMustBeLessOrEqual);
			}
			int byteCount = bytes.Length - byteIndex;
			fixed (char* ptr = s)
			{
				fixed (byte* ptr2 = &CodePagesEncodingProvider.GetNonNullPinnableReference(bytes))
				{
					return GetBytes(ptr + charIndex, charCount, ptr2 + byteIndex, byteCount, null);
				}
			}
		}

		public unsafe override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
		{
			if (chars == null)
			{
				throw new ArgumentNullException("chars");
			}
			if (bytes == null)
			{
				throw new ArgumentNullException("bytes");
			}
			if (charIndex < 0 || charCount < 0)
			{
				throw new ArgumentOutOfRangeException((charIndex < 0) ? "charIndex" : "charCount", System.SR.ArgumentOutOfRange_NeedNonNegNum);
			}
			if (chars.Length - charIndex < charCount)
			{
				throw new ArgumentOutOfRangeException("chars", System.SR.ArgumentOutOfRange_IndexCountBuffer);
			}
			if (byteIndex < 0 || byteIndex > bytes.Length)
			{
				throw new ArgumentOutOfRangeException("byteIndex", System.SR.ArgumentOutOfRange_IndexMustBeLessOrEqual);
			}
			if (chars.Length == 0)
			{
				return 0;
			}
			int byteCount = bytes.Length - byteIndex;
			fixed (char* ptr = &chars[0])
			{
				fixed (byte* ptr2 = &CodePagesEncodingProvider.GetNonNullPinnableReference(bytes))
				{
					return GetBytes(

Mods/RealRadio/System.Text.Encodings.Web.dll

Decompiled a day ago
using System;
using System.Buffers;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Numerics;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.Encodings.Web;
using System.Text.Unicode;
using System.Threading;
using FxResources.System.Text.Encodings.Web;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: AssemblyDefaultAlias("System.Text.Encodings.Web")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata("IsTrimmable", "True")]
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyDescription("Provides types for encoding and escaping strings for use in JavaScript, HyperText Markup Language (HTML), and uniform resource locators (URL).\r\n\r\nCommonly Used Types:\r\nSystem.Text.Encodings.Web.HtmlEncoder\r\nSystem.Text.Encodings.Web.UrlEncoder\r\nSystem.Text.Encodings.Web.JavaScriptEncoder")]
[assembly: AssemblyFileVersion("8.0.23.53103")]
[assembly: AssemblyInformationalVersion("8.0.0+5535e31a712343a63f5d7d796cd874e563e5ac14")]
[assembly: AssemblyProduct("Microsoft® .NET")]
[assembly: AssemblyTitle("System.Text.Encodings.Web")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/dotnet/runtime")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("8.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: System.Runtime.CompilerServices.NullablePublicOnly(false)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsByRefLikeAttribute : Attribute
	{
	}
	[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 NullablePublicOnlyAttribute : Attribute
	{
		public readonly bool IncludesInternals;

		public NullablePublicOnlyAttribute(bool P_0)
		{
			IncludesInternals = P_0;
		}
	}
	[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 NativeIntegerAttribute : Attribute
	{
		public readonly bool[] TransformFlags;

		public NativeIntegerAttribute()
		{
			TransformFlags = new bool[1] { true };
		}

		public NativeIntegerAttribute(bool[] P_0)
		{
			TransformFlags = 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 FxResources.System.Text.Encodings.Web
{
	internal static class SR
	{
	}
}
namespace System
{
	internal static class HexConverter
	{
		public enum Casing : uint
		{
			Upper = 0u,
			Lower = 8224u
		}

		public static ReadOnlySpan<byte> CharToHexLookup => new byte[256]
		{
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 0, 1,
			2, 3, 4, 5, 6, 7, 8, 9, 255, 255,
			255, 255, 255, 255, 255, 10, 11, 12, 13, 14,
			15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 10, 11, 12,
			13, 14, 15, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255
		};

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void ToBytesBuffer(byte value, Span<byte> buffer, int startingIndex = 0, Casing casing = Casing.Upper)
		{
			uint num = (uint)(((value & 0xF0) << 4) + (value & 0xF) - 35209);
			uint num2 = ((((0 - num) & 0x7070) >> 4) + num + 47545) | (uint)casing;
			buffer[startingIndex + 1] = (byte)num2;
			buffer[startingIndex] = (byte)(num2 >> 8);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void ToCharsBuffer(byte value, Span<char> buffer, int startingIndex = 0, Casing casing = Casing.Upper)
		{
			uint num = (uint)(((value & 0xF0) << 4) + (value & 0xF) - 35209);
			uint num2 = ((((0 - num) & 0x7070) >> 4) + num + 47545) | (uint)casing;
			buffer[startingIndex + 1] = (char)(num2 & 0xFFu);
			buffer[startingIndex] = (char)(num2 >> 8);
		}

		public static void EncodeToUtf16(ReadOnlySpan<byte> bytes, Span<char> chars, Casing casing = Casing.Upper)
		{
			for (int i = 0; i < bytes.Length; i++)
			{
				ToCharsBuffer(bytes[i], chars, i * 2, casing);
			}
		}

		public static string ToString(ReadOnlySpan<byte> bytes, Casing casing = Casing.Upper)
		{
			Span<char> span = ((bytes.Length <= 16) ? stackalloc char[bytes.Length * 2] : new char[bytes.Length * 2].AsSpan());
			Span<char> buffer = span;
			int num = 0;
			ReadOnlySpan<byte> readOnlySpan = bytes;
			for (int i = 0; i < readOnlySpan.Length; i++)
			{
				byte value = readOnlySpan[i];
				ToCharsBuffer(value, buffer, num, casing);
				num += 2;
			}
			return buffer.ToString();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static char ToCharUpper(int value)
		{
			value &= 0xF;
			value += 48;
			if (value > 57)
			{
				value += 7;
			}
			return (char)value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static char ToCharLower(int value)
		{
			value &= 0xF;
			value += 48;
			if (value > 57)
			{
				value += 39;
			}
			return (char)value;
		}

		public static bool TryDecodeFromUtf16(ReadOnlySpan<char> chars, Span<byte> bytes)
		{
			int charsProcessed;
			return TryDecodeFromUtf16(chars, bytes, out charsProcessed);
		}

		public static bool TryDecodeFromUtf16(ReadOnlySpan<char> chars, Span<byte> bytes, out int charsProcessed)
		{
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			while (num2 < bytes.Length)
			{
				num3 = FromChar(chars[num + 1]);
				num4 = FromChar(chars[num]);
				if ((num3 | num4) == 255)
				{
					break;
				}
				bytes[num2++] = (byte)((num4 << 4) | num3);
				num += 2;
			}
			if (num3 == 255)
			{
				num++;
			}
			charsProcessed = num;
			return (num3 | num4) != 255;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int FromChar(int c)
		{
			if (c < CharToHexLookup.Length)
			{
				return CharToHexLookup[c];
			}
			return 255;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int FromUpperChar(int c)
		{
			if (c <= 71)
			{
				return CharToHexLookup[c];
			}
			return 255;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int FromLowerChar(int c)
		{
			switch (c)
			{
			case 48:
			case 49:
			case 50:
			case 51:
			case 52:
			case 53:
			case 54:
			case 55:
			case 56:
			case 57:
				return c - 48;
			case 97:
			case 98:
			case 99:
			case 100:
			case 101:
			case 102:
				return c - 97 + 10;
			default:
				return 255;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsHexChar(int c)
		{
			if (IntPtr.Size == 8)
			{
				ulong num = (uint)(c - 48);
				ulong num2 = (ulong)(-17875860044349952L << (int)num);
				ulong num3 = num - 64;
				return (long)(num2 & num3) < 0L;
			}
			return FromChar(c) != 255;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsHexUpperChar(int c)
		{
			if ((uint)(c - 48) > 9u)
			{
				return (uint)(c - 65) <= 5u;
			}
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsHexLowerChar(int c)
		{
			if ((uint)(c - 48) > 9u)
			{
				return (uint)(c - 97) <= 5u;
			}
			return true;
		}
	}
	internal static class SR
	{
		private static readonly bool s_usingResourceKeys = AppContext.TryGetSwitch("System.Resources.UseSystemResourceKeys", out var isEnabled) && isEnabled;

		private static ResourceManager s_resourceManager;

		internal static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(typeof(SR)));

		internal static string TextEncoderDoesNotImplementMaxOutputCharsPerInputChar => GetResourceString("TextEncoderDoesNotImplementMaxOutputCharsPerInputChar");

		internal static bool UsingResourceKeys()
		{
			return s_usingResourceKeys;
		}

		private static string GetResourceString(string resourceKey)
		{
			if (UsingResourceKeys())
			{
				return resourceKey;
			}
			string result = null;
			try
			{
				result = ResourceManager.GetString(resourceKey);
			}
			catch (MissingManifestResourceException)
			{
			}
			return result;
		}

		private static string GetResourceString(string resourceKey, string defaultString)
		{
			string resourceString = GetResourceString(resourceKey);
			if (!(resourceKey == resourceString) && resourceString != null)
			{
				return resourceString;
			}
			return defaultString;
		}

		internal static string Format(string resourceFormat, object p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(resourceFormat, p1);
		}

		internal static string Format(string resourceFormat, object p1, object p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(resourceFormat, p1, p2);
		}

		internal static string Format(string resourceFormat, object p1, object p2, object p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(resourceFormat, p1, p2, p3);
		}

		internal static string Format(string resourceFormat, params object[] args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + ", " + string.Join(", ", args);
				}
				return string.Format(resourceFormat, args);
			}
			return resourceFormat;
		}

		internal static string Format(IFormatProvider provider, string resourceFormat, object p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(provider, resourceFormat, p1);
		}

		internal static string Format(IFormatProvider provider, string resourceFormat, object p1, object p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(provider, resourceFormat, p1, p2);
		}

		internal static string Format(IFormatProvider provider, string resourceFormat, object p1, object p2, object p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(provider, resourceFormat, p1, p2, p3);
		}

		internal static string Format(IFormatProvider provider, string resourceFormat, params object[] args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + ", " + string.Join(", ", args);
				}
				return string.Format(provider, resourceFormat, args);
			}
			return resourceFormat;
		}
	}
}
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.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class MaybeNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class NotNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal sealed class MaybeNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

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

		public NotNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[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.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.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	internal sealed class MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	internal sealed class MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
}
namespace System.Runtime.InteropServices
{
	[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
	internal sealed class LibraryImportAttribute : Attribute
	{
		public string LibraryName { get; }

		public string EntryPoint { get; set; }

		public StringMarshalling StringMarshalling { get; set; }

		public Type StringMarshallingCustomType { get; set; }

		public bool SetLastError { get; set; }

		public LibraryImportAttribute(string libraryName)
		{
			LibraryName = libraryName;
		}
	}
	internal enum StringMarshalling
	{
		Custom,
		Utf8,
		Utf16
	}
}
namespace System.Numerics
{
	internal static class BitOperations
	{
		private static ReadOnlySpan<byte> Log2DeBruijn => new byte[32]
		{
			0, 9, 1, 10, 13, 21, 2, 29, 11, 14,
			16, 18, 22, 25, 3, 30, 8, 12, 20, 28,
			15, 17, 24, 7, 19, 27, 23, 6, 26, 5,
			4, 31
		};

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int Log2(uint value)
		{
			return Log2SoftwareFallback(value | 1u);
		}

		private static int Log2SoftwareFallback(uint value)
		{
			value |= value >> 1;
			value |= value >> 2;
			value |= value >> 4;
			value |= value >> 8;
			value |= value >> 16;
			return Unsafe.AddByteOffset(ref MemoryMarshal.GetReference(Log2DeBruijn), (nint)(value * 130329821 >> 27));
		}
	}
}
namespace System.Text
{
	internal static class UnicodeDebug
	{
		[Conditional("DEBUG")]
		internal static void AssertIsBmpCodePoint(uint codePoint)
		{
			System.Text.UnicodeUtility.IsBmpCodePoint(codePoint);
		}

		[Conditional("DEBUG")]
		internal static void AssertIsHighSurrogateCodePoint(uint codePoint)
		{
			System.Text.UnicodeUtility.IsHighSurrogateCodePoint(codePoint);
		}

		[Conditional("DEBUG")]
		internal static void AssertIsLowSurrogateCodePoint(uint codePoint)
		{
			System.Text.UnicodeUtility.IsLowSurrogateCodePoint(codePoint);
		}

		[Conditional("DEBUG")]
		internal static void AssertIsValidCodePoint(uint codePoint)
		{
			System.Text.UnicodeUtility.IsValidCodePoint(codePoint);
		}

		[Conditional("DEBUG")]
		internal static void AssertIsValidScalar(uint scalarValue)
		{
			System.Text.UnicodeUtility.IsValidUnicodeScalar(scalarValue);
		}

		[Conditional("DEBUG")]
		internal static void AssertIsValidSupplementaryPlaneScalar(uint scalarValue)
		{
			if (System.Text.UnicodeUtility.IsValidUnicodeScalar(scalarValue))
			{
				System.Text.UnicodeUtility.IsBmpCodePoint(scalarValue);
			}
		}

		private static string ToHexString(uint codePoint)
		{
			return FormattableString.Invariant($"U+{codePoint:X4}");
		}
	}
	internal static class UnicodeUtility
	{
		public const uint ReplacementChar = 65533u;

		public static int GetPlane(uint codePoint)
		{
			return (int)(codePoint >> 16);
		}

		public static uint GetScalarFromUtf16SurrogatePair(uint highSurrogateCodePoint, uint lowSurrogateCodePoint)
		{
			return (highSurrogateCodePoint << 10) + lowSurrogateCodePoint - 56613888;
		}

		public static int GetUtf16SequenceLength(uint value)
		{
			value -= 65536;
			value += 33554432;
			value >>= 24;
			return (int)value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void GetUtf16SurrogatesFromSupplementaryPlaneScalar(uint value, out char highSurrogateCodePoint, out char lowSurrogateCodePoint)
		{
			highSurrogateCodePoint = (char)(value + 56557568 >> 10);
			lowSurrogateCodePoint = (char)((value & 0x3FF) + 56320);
		}

		public static int GetUtf8SequenceLength(uint value)
		{
			int num = (int)(value - 2048) >> 31;
			value ^= 0xF800u;
			value -= 63616;
			value += 67108864;
			value >>= 24;
			return (int)value + num * 2;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsAsciiCodePoint(uint value)
		{
			return value <= 127;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsBmpCodePoint(uint value)
		{
			return value <= 65535;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsHighSurrogateCodePoint(uint value)
		{
			return IsInRangeInclusive(value, 55296u, 56319u);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsInRangeInclusive(uint value, uint lowerBound, uint upperBound)
		{
			return value - lowerBound <= upperBound - lowerBound;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsLowSurrogateCodePoint(uint value)
		{
			return IsInRangeInclusive(value, 56320u, 57343u);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsSurrogateCodePoint(uint value)
		{
			return IsInRangeInclusive(value, 55296u, 57343u);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsValidCodePoint(uint codePoint)
		{
			return codePoint <= 1114111;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsValidUnicodeScalar(uint value)
		{
			return ((value - 1114112) ^ 0xD800) >= 4293855232u;
		}
	}
	internal ref struct ValueStringBuilder
	{
		private char[] _arrayToReturnToPool;

		private Span<char> _chars;

		private int _pos;

		public int Length
		{
			get
			{
				return _pos;
			}
			set
			{
				_pos = value;
			}
		}

		public int Capacity => _chars.Length;

		public ref char this[int index] => ref _chars[index];

		public Span<char> RawChars => _chars;

		public ValueStringBuilder(Span<char> initialBuffer)
		{
			_arrayToReturnToPool = null;
			_chars = initialBuffer;
			_pos = 0;
		}

		public ValueStringBuilder(int initialCapacity)
		{
			_arrayToReturnToPool = ArrayPool<char>.Shared.Rent(initialCapacity);
			_chars = _arrayToReturnToPool;
			_pos = 0;
		}

		public void EnsureCapacity(int capacity)
		{
			if ((uint)capacity > (uint)_chars.Length)
			{
				Grow(capacity - _pos);
			}
		}

		public ref char GetPinnableReference()
		{
			return ref MemoryMarshal.GetReference(_chars);
		}

		public ref char GetPinnableReference(bool terminate)
		{
			if (terminate)
			{
				EnsureCapacity(Length + 1);
				_chars[Length] = '\0';
			}
			return ref MemoryMarshal.GetReference(_chars);
		}

		public override string ToString()
		{
			string result = _chars.Slice(0, _pos).ToString();
			Dispose();
			return result;
		}

		public ReadOnlySpan<char> AsSpan(bool terminate)
		{
			if (terminate)
			{
				EnsureCapacity(Length + 1);
				_chars[Length] = '\0';
			}
			return _chars.Slice(0, _pos);
		}

		public ReadOnlySpan<char> AsSpan()
		{
			return _chars.Slice(0, _pos);
		}

		public ReadOnlySpan<char> AsSpan(int start)
		{
			return _chars.Slice(start, _pos - start);
		}

		public ReadOnlySpan<char> AsSpan(int start, int length)
		{
			return _chars.Slice(start, length);
		}

		public bool TryCopyTo(Span<char> destination, out int charsWritten)
		{
			if (_chars.Slice(0, _pos).TryCopyTo(destination))
			{
				charsWritten = _pos;
				Dispose();
				return true;
			}
			charsWritten = 0;
			Dispose();
			return false;
		}

		public void Insert(int index, char value, int count)
		{
			if (_pos > _chars.Length - count)
			{
				Grow(count);
			}
			int length = _pos - index;
			_chars.Slice(index, length).CopyTo(_chars.Slice(index + count));
			_chars.Slice(index, count).Fill(value);
			_pos += count;
		}

		public void Insert(int index, string s)
		{
			if (s != null)
			{
				int length = s.Length;
				if (_pos > _chars.Length - length)
				{
					Grow(length);
				}
				int length2 = _pos - index;
				_chars.Slice(index, length2).CopyTo(_chars.Slice(index + length));
				s.AsSpan().CopyTo(_chars.Slice(index));
				_pos += length;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Append(char c)
		{
			int pos = _pos;
			Span<char> chars = _chars;
			if ((uint)pos < (uint)chars.Length)
			{
				chars[pos] = c;
				_pos = pos + 1;
			}
			else
			{
				GrowAndAppend(c);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Append(string s)
		{
			if (s != null)
			{
				int pos = _pos;
				if (s.Length == 1 && (uint)pos < (uint)_chars.Length)
				{
					_chars[pos] = s[0];
					_pos = pos + 1;
				}
				else
				{
					AppendSlow(s);
				}
			}
		}

		private void AppendSlow(string s)
		{
			int pos = _pos;
			if (pos > _chars.Length - s.Length)
			{
				Grow(s.Length);
			}
			s.AsSpan().CopyTo(_chars.Slice(pos));
			_pos += s.Length;
		}

		public void Append(char c, int count)
		{
			if (_pos > _chars.Length - count)
			{
				Grow(count);
			}
			Span<char> span = _chars.Slice(_pos, count);
			for (int i = 0; i < span.Length; i++)
			{
				span[i] = c;
			}
			_pos += count;
		}

		public unsafe void Append(char* value, int length)
		{
			int pos = _pos;
			if (pos > _chars.Length - length)
			{
				Grow(length);
			}
			Span<char> span = _chars.Slice(_pos, length);
			for (int i = 0; i < span.Length; i++)
			{
				span[i] = *(value++);
			}
			_pos += length;
		}

		public void Append(ReadOnlySpan<char> value)
		{
			int pos = _pos;
			if (pos > _chars.Length - value.Length)
			{
				Grow(value.Length);
			}
			value.CopyTo(_chars.Slice(_pos));
			_pos += value.Length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span<char> AppendSpan(int length)
		{
			int pos = _pos;
			if (pos > _chars.Length - length)
			{
				Grow(length);
			}
			_pos = pos + length;
			return _chars.Slice(pos, length);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private void GrowAndAppend(char c)
		{
			Grow(1);
			Append(c);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private void Grow(int additionalCapacityBeyondPos)
		{
			int minimumLength = (int)Math.Max((uint)(_pos + additionalCapacityBeyondPos), Math.Min((uint)(_chars.Length * 2), 2147483591u));
			char[] array = ArrayPool<char>.Shared.Rent(minimumLength);
			_chars.Slice(0, _pos).CopyTo(array);
			char[] arrayToReturnToPool = _arrayToReturnToPool;
			_chars = (_arrayToReturnToPool = array);
			if (arrayToReturnToPool != null)
			{
				ArrayPool<char>.Shared.Return(arrayToReturnToPool);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void Dispose()
		{
			char[] arrayToReturnToPool = _arrayToReturnToPool;
			this = default(System.Text.ValueStringBuilder);
			if (arrayToReturnToPool != null)
			{
				ArrayPool<char>.Shared.Return(arrayToReturnToPool);
			}
		}
	}
	internal readonly struct Rune : IEquatable<Rune>
	{
		private const int MaxUtf16CharsPerRune = 2;

		private const char HighSurrogateStart = '\ud800';

		private const char LowSurrogateStart = '\udc00';

		private const int HighSurrogateRange = 1023;

		private readonly uint _value;

		public bool IsAscii => System.Text.UnicodeUtility.IsAsciiCodePoint(_value);

		public bool IsBmp => System.Text.UnicodeUtility.IsBmpCodePoint(_value);

		public static Rune ReplacementChar => UnsafeCreate(65533u);

		public int Utf16SequenceLength => System.Text.UnicodeUtility.GetUtf16SequenceLength(_value);

		public int Value => (int)_value;

		public Rune(uint value)
		{
			if (!System.Text.UnicodeUtility.IsValidUnicodeScalar(value))
			{
				ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.value);
			}
			_value = value;
		}

		public Rune(int value)
			: this((uint)value)
		{
		}

		private Rune(uint scalarValue, bool _)
		{
			_value = scalarValue;
		}

		public static bool operator ==(Rune left, Rune right)
		{
			return left._value == right._value;
		}

		public static bool operator !=(Rune left, Rune right)
		{
			return left._value != right._value;
		}

		public static bool IsControl(Rune value)
		{
			return ((value._value + 1) & 0xFFFFFF7Fu) <= 32;
		}

		public static OperationStatus DecodeFromUtf16(ReadOnlySpan<char> source, out Rune result, out int charsConsumed)
		{
			if (!source.IsEmpty)
			{
				char c = source[0];
				if (TryCreate(c, out result))
				{
					charsConsumed = 1;
					return OperationStatus.Done;
				}
				if (1u < (uint)source.Length)
				{
					char lowSurrogate = source[1];
					if (TryCreate(c, lowSurrogate, out result))
					{
						charsConsumed = 2;
						return OperationStatus.Done;
					}
				}
				else if (char.IsHighSurrogate(c))
				{
					goto IL_004c;
				}
				charsConsumed = 1;
				result = ReplacementChar;
				return OperationStatus.InvalidData;
			}
			goto IL_004c;
			IL_004c:
			charsConsumed = source.Length;
			result = ReplacementChar;
			return OperationStatus.NeedMoreData;
		}

		public static OperationStatus DecodeFromUtf8(ReadOnlySpan<byte> source, out Rune result, out int bytesConsumed)
		{
			int num = 0;
			uint num2;
			if ((uint)num < (uint)source.Length)
			{
				num2 = source[num];
				if (System.Text.UnicodeUtility.IsAsciiCodePoint(num2))
				{
					goto IL_0021;
				}
				if (System.Text.UnicodeUtility.IsInRangeInclusive(num2, 194u, 244u))
				{
					num2 = num2 - 194 << 6;
					num++;
					if ((uint)num >= (uint)source.Length)
					{
						goto IL_0163;
					}
					int num3 = (sbyte)source[num];
					if (num3 < -64)
					{
						num2 += (uint)num3;
						num2 += 128;
						num2 += 128;
						if (num2 < 2048)
						{
							goto IL_0021;
						}
						if (System.Text.UnicodeUtility.IsInRangeInclusive(num2, 2080u, 3343u) && !System.Text.UnicodeUtility.IsInRangeInclusive(num2, 2912u, 2943u) && !System.Text.UnicodeUtility.IsInRangeInclusive(num2, 3072u, 3087u))
						{
							num++;
							if ((uint)num >= (uint)source.Length)
							{
								goto IL_0163;
							}
							num3 = (sbyte)source[num];
							if (num3 < -64)
							{
								num2 <<= 6;
								num2 += (uint)num3;
								num2 += 128;
								num2 -= 131072;
								if (num2 > 65535)
								{
									num++;
									if ((uint)num >= (uint)source.Length)
									{
										goto IL_0163;
									}
									num3 = (sbyte)source[num];
									if (num3 >= -64)
									{
										goto IL_0153;
									}
									num2 <<= 6;
									num2 += (uint)num3;
									num2 += 128;
									num2 -= 4194304;
								}
								goto IL_0021;
							}
						}
					}
				}
				else
				{
					num = 1;
				}
				goto IL_0153;
			}
			goto IL_0163;
			IL_0021:
			bytesConsumed = num + 1;
			result = UnsafeCreate(num2);
			return OperationStatus.Done;
			IL_0153:
			bytesConsumed = num;
			result = ReplacementChar;
			return OperationStatus.InvalidData;
			IL_0163:
			bytesConsumed = num;
			result = ReplacementChar;
			return OperationStatus.NeedMoreData;
		}

		public override bool Equals([NotNullWhen(true)] object obj)
		{
			if (obj is Rune other)
			{
				return Equals(other);
			}
			return false;
		}

		public bool Equals(Rune other)
		{
			return this == other;
		}

		public override int GetHashCode()
		{
			return Value;
		}

		public static bool TryCreate(char ch, out Rune result)
		{
			if (!System.Text.UnicodeUtility.IsSurrogateCodePoint(ch))
			{
				result = UnsafeCreate(ch);
				return true;
			}
			result = default(Rune);
			return false;
		}

		public static bool TryCreate(char highSurrogate, char lowSurrogate, out Rune result)
		{
			uint num = (uint)(highSurrogate - 55296);
			uint num2 = (uint)(lowSurrogate - 56320);
			if ((num | num2) <= 1023)
			{
				result = UnsafeCreate((uint)((int)(num << 10) + (lowSurrogate - 56320) + 65536));
				return true;
			}
			result = default(Rune);
			return false;
		}

		public bool TryEncodeToUtf16(Span<char> destination, out int charsWritten)
		{
			if (destination.Length >= 1)
			{
				if (IsBmp)
				{
					destination[0] = (char)_value;
					charsWritten = 1;
					return true;
				}
				if (destination.Length >= 2)
				{
					System.Text.UnicodeUtility.GetUtf16SurrogatesFromSupplementaryPlaneScalar(_value, out destination[0], out destination[1]);
					charsWritten = 2;
					return true;
				}
			}
			charsWritten = 0;
			return false;
		}

		public bool TryEncodeToUtf8(Span<byte> destination, out int bytesWritten)
		{
			if (destination.Length >= 1)
			{
				if (IsAscii)
				{
					destination[0] = (byte)_value;
					bytesWritten = 1;
					return true;
				}
				if (destination.Length >= 2)
				{
					if (_value <= 2047)
					{
						destination[0] = (byte)(_value + 12288 >> 6);
						destination[1] = (byte)((_value & 0x3F) + 128);
						bytesWritten = 2;
						return true;
					}
					if (destination.Length >= 3)
					{
						if (_value <= 65535)
						{
							destination[0] = (byte)(_value + 917504 >> 12);
							destination[1] = (byte)(((_value & 0xFC0) >> 6) + 128);
							destination[2] = (byte)((_value & 0x3F) + 128);
							bytesWritten = 3;
							return true;
						}
						if (destination.Length >= 4)
						{
							destination[0] = (byte)(_value + 62914560 >> 18);
							destination[1] = (byte)(((_value & 0x3F000) >> 12) + 128);
							destination[2] = (byte)(((_value & 0xFC0) >> 6) + 128);
							destination[3] = (byte)((_value & 0x3F) + 128);
							bytesWritten = 4;
							return true;
						}
					}
				}
			}
			bytesWritten = 0;
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static Rune UnsafeCreate(uint scalarValue)
		{
			return new Rune(scalarValue, _: false);
		}
	}
}
namespace System.Text.Unicode
{
	internal static class UnicodeHelpers
	{
		internal const int UNICODE_LAST_CODEPOINT = 1114111;

		private static ReadOnlySpan<byte> DefinedCharsBitmapSpan => new byte[8192]
		{
			0, 0, 0, 0, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 127, 0, 0, 0, 0,
			254, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 252, 240, 215, 255, 255, 251, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 254, 255, 255, 255,
			127, 254, 255, 255, 255, 255, 255, 231, 254, 255,
			255, 255, 255, 255, 255, 0, 255, 255, 255, 135,
			31, 0, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 191, 255, 255, 255, 255,
			255, 255, 255, 231, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 3, 0, 255, 255,
			255, 255, 255, 255, 255, 231, 255, 255, 255, 255,
			255, 63, 255, 127, 255, 255, 255, 79, 255, 7,
			255, 255, 255, 127, 3, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 239, 159, 249, 255, 255, 253,
			197, 243, 159, 121, 128, 176, 207, 255, 255, 127,
			238, 135, 249, 255, 255, 253, 109, 211, 135, 57,
			2, 94, 192, 255, 127, 0, 238, 191, 251, 255,
			255, 253, 237, 243, 191, 59, 1, 0, 207, 255,
			3, 254, 238, 159, 249, 255, 255, 253, 237, 243,
			159, 57, 224, 176, 207, 255, 255, 0, 236, 199,
			61, 214, 24, 199, 255, 195, 199, 61, 129, 0,
			192, 255, 255, 7, 255, 223, 253, 255, 255, 253,
			255, 243, 223, 61, 96, 39, 207, 255, 128, 255,
			255, 223, 253, 255, 255, 253, 239, 243, 223, 61,
			96, 96, 207, 255, 14, 0, 255, 223, 253, 255,
			255, 255, 255, 255, 223, 253, 240, 255, 207, 255,
			255, 255, 238, 255, 127, 252, 255, 255, 251, 47,
			127, 132, 95, 255, 192, 255, 28, 0, 254, 255,
			255, 255, 255, 255, 255, 135, 255, 255, 255, 15,
			0, 0, 0, 0, 214, 247, 255, 255, 175, 255,
			255, 63, 95, 127, 255, 243, 0, 0, 0, 0,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 254,
			255, 255, 255, 31, 254, 255, 255, 255, 255, 254,
			255, 255, 255, 223, 255, 223, 255, 7, 0, 0,
			0, 0, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 191, 32, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 61, 127, 61, 255, 255,
			255, 255, 255, 61, 255, 255, 255, 255, 61, 127,
			61, 255, 127, 255, 255, 255, 255, 255, 255, 255,
			61, 255, 255, 255, 255, 255, 255, 255, 255, 231,
			255, 255, 255, 31, 255, 255, 255, 3, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 63, 63,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			254, 255, 255, 31, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 1, 255, 255, 63, 128,
			255, 255, 127, 0, 255, 255, 15, 0, 255, 223,
			13, 0, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 63, 255, 3, 255, 3, 255, 255,
			255, 3, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 1, 255, 255, 255, 255, 255, 7,
			255, 255, 255, 255, 255, 255, 255, 255, 63, 0,
			255, 255, 255, 127, 255, 15, 255, 15, 241, 255,
			255, 255, 255, 63, 31, 0, 255, 255, 255, 255,
			255, 15, 255, 255, 255, 3, 255, 199, 255, 255,
			255, 255, 255, 255, 255, 207, 255, 255, 255, 255,
			255, 255, 255, 127, 255, 255, 255, 159, 255, 3,
			255, 3, 255, 63, 255, 255, 255, 127, 0, 0,
			0, 0, 0, 0, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 31, 255, 255, 255, 255, 255, 127,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 15, 240, 255, 255, 255, 255,
			255, 255, 255, 248, 255, 227, 255, 255, 255, 255,
			255, 255, 255, 1, 255, 255, 255, 255, 255, 231,
			255, 0, 255, 255, 255, 255, 255, 7, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 63, 63, 255, 255, 255, 255,
			63, 63, 255, 170, 255, 255, 255, 63, 255, 255,
			255, 255, 255, 255, 223, 255, 223, 255, 207, 239,
			255, 255, 220, 127, 0, 248, 255, 255, 255, 124,
			255, 255, 255, 255, 255, 127, 223, 255, 243, 255,
			255, 127, 255, 31, 255, 255, 255, 255, 1, 0,
			255, 255, 255, 255, 1, 0, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 15, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 127, 0, 0, 0,
			255, 7, 0, 0, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			207, 255, 255, 255, 191, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 15, 254,
			255, 255, 255, 255, 191, 32, 255, 255, 255, 255,
			255, 255, 255, 128, 1, 128, 255, 255, 127, 0,
			127, 127, 127, 127, 127, 127, 127, 127, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 63, 0, 0, 0, 0, 255, 255,
			255, 251, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 15, 0, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			63, 0, 0, 0, 255, 15, 254, 255, 255, 255,
			255, 255, 255, 255, 254, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 127, 254, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 224, 255,
			255, 255, 255, 255, 254, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 127, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 15, 0, 255, 255,
			255, 255, 255, 127, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 31, 255, 255, 255, 255,
			255, 255, 127, 0, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 15, 0, 0,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 0, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 7,
			235, 3, 0, 0, 252, 255, 255, 255, 255, 255,
			255, 31, 255, 3, 255, 255, 255, 255, 255, 255,
			255, 0, 255, 255, 255, 255, 255, 255, 255, 255,
			63, 192, 255, 3, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 15, 128,
			255, 255, 255, 31, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 191, 255, 195, 255, 255, 255, 127,
			255, 255, 255, 255, 255, 255, 127, 0, 255, 63,
			255, 243, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 7, 0, 0, 248, 255, 255,
			127, 0, 126, 126, 126, 0, 127, 127, 255, 255,
			255, 255, 255, 255, 255, 15, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 63, 255, 3, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			15, 0, 255, 255, 127, 248, 255, 255, 255, 255,
			255, 15, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 63, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 3, 0, 0,
			0, 0, 127, 0, 248, 224, 255, 255, 127, 95,
			219, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 7, 0, 248, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 252, 255, 255, 255, 255, 255,
			255, 128, 0, 0, 0, 0, 255, 255, 255, 255,
			255, 3, 255, 255, 255, 255, 255, 255, 247, 255,
			127, 15, 223, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 31,
			254, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 127, 252, 252, 252, 28, 127, 127,
			0, 62
		};

		internal static ReadOnlySpan<byte> GetDefinedBmpCodePointsBitmapLittleEndian()
		{
			return DefinedCharsBitmapSpan;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void GetUtf16SurrogatePairFromAstralScalarValue(uint scalar, out char highSurrogate, out char lowSurrogate)
		{
			highSurrogate = (char)(scalar + 56557568 >> 10);
			lowSurrogate = (char)((scalar & 0x3FF) + 56320);
		}

		internal static int GetUtf8RepresentationForScalarValue(uint scalar)
		{
			if (scalar <= 127)
			{
				return (byte)scalar;
			}
			if (scalar <= 2047)
			{
				byte b = (byte)(0xC0u | (scalar >> 6));
				byte b2 = (byte)(0x80u | (scalar & 0x3Fu));
				return (b2 << 8) | b;
			}
			if (scalar <= 65535)
			{
				byte b3 = (byte)(0xE0u | (scalar >> 12));
				byte b4 = (byte)(0x80u | ((scalar >> 6) & 0x3Fu));
				byte b5 = (byte)(0x80u | (scalar & 0x3Fu));
				return (((b5 << 8) | b4) << 8) | b3;
			}
			byte b6 = (byte)(0xF0u | (scalar >> 18));
			byte b7 = (byte)(0x80u | ((scalar >> 12) & 0x3Fu));
			byte b8 = (byte)(0x80u | ((scalar >> 6) & 0x3Fu));
			byte b9 = (byte)(0x80u | (scalar & 0x3Fu));
			return (((((b9 << 8) | b8) << 8) | b7) << 8) | b6;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static bool IsSupplementaryCodePoint(int scalar)
		{
			return (scalar & -65536) != 0;
		}
	}
	public sealed class UnicodeRange
	{
		public int FirstCodePoint { get; private set; }

		public int Length { get; private set; }

		public UnicodeRange(int firstCodePoint, int length)
		{
			if (firstCodePoint < 0 || firstCodePoint > 65535)
			{
				throw new ArgumentOutOfRangeException("firstCodePoint");
			}
			if (length < 0 || (long)firstCodePoint + (long)length > 65536)
			{
				throw new ArgumentOutOfRangeException("length");
			}
			FirstCodePoint = firstCodePoint;
			Length = length;
		}

		public static UnicodeRange Create(char firstCharacter, char lastCharacter)
		{
			if (lastCharacter < firstCharacter)
			{
				throw new ArgumentOutOfRangeException("lastCharacter");
			}
			return new UnicodeRange(firstCharacter, 1 + (lastCharacter - firstCharacter));
		}
	}
	public static class UnicodeRanges
	{
		private static UnicodeRange _none;

		private static UnicodeRange _all;

		private static UnicodeRange _u0000;

		private static UnicodeRange _u0080;

		private static UnicodeRange _u0100;

		private static UnicodeRange _u0180;

		private static UnicodeRange _u0250;

		private static UnicodeRange _u02B0;

		private static UnicodeRange _u0300;

		private static UnicodeRange _u0370;

		private static UnicodeRange _u0400;

		private static UnicodeRange _u0500;

		private static UnicodeRange _u0530;

		private static UnicodeRange _u0590;

		private static UnicodeRange _u0600;

		private static UnicodeRange _u0700;

		private static UnicodeRange _u0750;

		private static UnicodeRange _u0780;

		private static UnicodeRange _u07C0;

		private static UnicodeRange _u0800;

		private static UnicodeRange _u0840;

		private static UnicodeRange _u0860;

		private static UnicodeRange _u0870;

		private static UnicodeRange _u08A0;

		private static UnicodeRange _u0900;

		private static UnicodeRange _u0980;

		private static UnicodeRange _u0A00;

		private static UnicodeRange _u0A80;

		private static UnicodeRange _u0B00;

		private static UnicodeRange _u0B80;

		private static UnicodeRange _u0C00;

		private static UnicodeRange _u0C80;

		private static UnicodeRange _u0D00;

		private static UnicodeRange _u0D80;

		private static UnicodeRange _u0E00;

		private static UnicodeRange _u0E80;

		private static UnicodeRange _u0F00;

		private static UnicodeRange _u1000;

		private static UnicodeRange _u10A0;

		private static UnicodeRange _u1100;

		private static UnicodeRange _u1200;

		private static UnicodeRange _u1380;

		private static UnicodeRange _u13A0;

		private static UnicodeRange _u1400;

		private static UnicodeRange _u1680;

		private static UnicodeRange _u16A0;

		private static UnicodeRange _u1700;

		private static UnicodeRange _u1720;

		private static UnicodeRange _u1740;

		private static UnicodeRange _u1760;

		private static UnicodeRange _u1780;

		private static UnicodeRange _u1800;

		private static UnicodeRange _u18B0;

		private static UnicodeRange _u1900;

		private static UnicodeRange _u1950;

		private static UnicodeRange _u1980;

		private static UnicodeRange _u19E0;

		private static UnicodeRange _u1A00;

		private static UnicodeRange _u1A20;

		private static UnicodeRange _u1AB0;

		private static UnicodeRange _u1B00;

		private static UnicodeRange _u1B80;

		private static UnicodeRange _u1BC0;

		private static UnicodeRange _u1C00;

		private static UnicodeRange _u1C50;

		private static UnicodeRange _u1C80;

		private static UnicodeRange _u1C90;

		private static UnicodeRange _u1CC0;

		private static UnicodeRange _u1CD0;

		private static UnicodeRange _u1D00;

		private static UnicodeRange _u1D80;

		private static UnicodeRange _u1DC0;

		private static UnicodeRange _u1E00;

		private static UnicodeRange _u1F00;

		private static UnicodeRange _u2000;

		private static UnicodeRange _u2070;

		private static UnicodeRange _u20A0;

		private static UnicodeRange _u20D0;

		private static UnicodeRange _u2100;

		private static UnicodeRange _u2150;

		private static UnicodeRange _u2190;

		private static UnicodeRange _u2200;

		private static UnicodeRange _u2300;

		private static UnicodeRange _u2400;

		private static UnicodeRange _u2440;

		private static UnicodeRange _u2460;

		private static UnicodeRange _u2500;

		private static UnicodeRange _u2580;

		private static UnicodeRange _u25A0;

		private static UnicodeRange _u2600;

		private static UnicodeRange _u2700;

		private static UnicodeRange _u27C0;

		private static UnicodeRange _u27F0;

		private static UnicodeRange _u2800;

		private static UnicodeRange _u2900;

		private static UnicodeRange _u2980;

		private static UnicodeRange _u2A00;

		private static UnicodeRange _u2B00;

		private static UnicodeRange _u2C00;

		private static UnicodeRange _u2C60;

		private static UnicodeRange _u2C80;

		private static UnicodeRange _u2D00;

		private static UnicodeRange _u2D30;

		private static UnicodeRange _u2D80;

		private static UnicodeRange _u2DE0;

		private static UnicodeRange _u2E00;

		private static UnicodeRange _u2E80;

		private static UnicodeRange _u2F00;

		private static UnicodeRange _u2FF0;

		private static UnicodeRange _u3000;

		private static UnicodeRange _u3040;

		private static UnicodeRange _u30A0;

		private static UnicodeRange _u3100;

		private static UnicodeRange _u3130;

		private static UnicodeRange _u3190;

		private static UnicodeRange _u31A0;

		private static UnicodeRange _u31C0;

		private static UnicodeRange _u31F0;

		private static UnicodeRange _u3200;

		private static UnicodeRange _u3300;

		private static UnicodeRange _u3400;

		private static UnicodeRange _u4DC0;

		private static UnicodeRange _u4E00;

		private static UnicodeRange _uA000;

		private static UnicodeRange _uA490;

		private static UnicodeRange _uA4D0;

		private static UnicodeRange _uA500;

		private static UnicodeRange _uA640;

		private static UnicodeRange _uA6A0;

		private static UnicodeRange _uA700;

		private static UnicodeRange _uA720;

		private static UnicodeRange _uA800;

		private static UnicodeRange _uA830;

		private static UnicodeRange _uA840;

		private static UnicodeRange _uA880;

		private static UnicodeRange _uA8E0;

		private static UnicodeRange _uA900;

		private static UnicodeRange _uA930;

		private static UnicodeRange _uA960;

		private static UnicodeRange _uA980;

		private static UnicodeRange _uA9E0;

		private static UnicodeRange _uAA00;

		private static UnicodeRange _uAA60;

		private static UnicodeRange _uAA80;

		private static UnicodeRange _uAAE0;

		private static UnicodeRange _uAB00;

		private static UnicodeRange _uAB30;

		private static UnicodeRange _uAB70;

		private static UnicodeRange _uABC0;

		private static UnicodeRange _uAC00;

		private static UnicodeRange _uD7B0;

		private static UnicodeRange _uF900;

		private static UnicodeRange _uFB00;

		private static UnicodeRange _uFB50;

		private static UnicodeRange _uFE00;

		private static UnicodeRange _uFE10;

		private static UnicodeRange _uFE20;

		private static UnicodeRange _uFE30;

		private static UnicodeRange _uFE50;

		private static UnicodeRange _uFE70;

		private static UnicodeRange _uFF00;

		private static UnicodeRange _uFFF0;

		public static UnicodeRange None => _none ?? CreateEmptyRange(ref _none);

		public static UnicodeRange All => _all ?? CreateRange(ref _all, '\0', '\uffff');

		public static UnicodeRange BasicLatin => _u0000 ?? CreateRange(ref _u0000, '\0', '\u007f');

		public static UnicodeRange Latin1Supplement => _u0080 ?? CreateRange(ref _u0080, '\u0080', 'ÿ');

		public static UnicodeRange LatinExtendedA => _u0100 ?? CreateRange(ref _u0100, 'Ā', 'ſ');

		public static UnicodeRange LatinExtendedB => _u0180 ?? CreateRange(ref _u0180, 'ƀ', 'ɏ');

		public static UnicodeRange IpaExtensions => _u0250 ?? CreateRange(ref _u0250, 'ɐ', 'ʯ');

		public static UnicodeRange SpacingModifierLetters => _u02B0 ?? CreateRange(ref _u02B0, 'ʰ', '\u02ff');

		public static UnicodeRange CombiningDiacriticalMarks => _u0300 ?? CreateRange(ref _u0300, '\u0300', '\u036f');

		public static UnicodeRange GreekandCoptic => _u0370 ?? CreateRange(ref _u0370, 'Ͱ', 'Ͽ');

		public static UnicodeRange Cyrillic => _u0400 ?? CreateRange(ref _u0400, 'Ѐ', 'ӿ');

		public static UnicodeRange CyrillicSupplement => _u0500 ?? CreateRange(ref _u0500, 'Ԁ', 'ԯ');

		public static UnicodeRange Armenian => _u0530 ?? CreateRange(ref _u0530, '\u0530', '֏');

		public static UnicodeRange Hebrew => _u0590 ?? CreateRange(ref _u0590, '\u0590', '\u05ff');

		public static UnicodeRange Arabic => _u0600 ?? CreateRange(ref _u0600, '\u0600', 'ۿ');

		public static UnicodeRange Syriac => _u0700 ?? CreateRange(ref _u0700, '܀', 'ݏ');

		public static UnicodeRange ArabicSupplement => _u0750 ?? CreateRange(ref _u0750, 'ݐ', 'ݿ');

		public static UnicodeRange Thaana => _u0780 ?? CreateRange(ref _u0780, 'ހ', '\u07bf');

		public static UnicodeRange NKo => _u07C0 ?? CreateRange(ref _u07C0, '߀', '߿');

		public static UnicodeRange Samaritan => _u0800 ?? CreateRange(ref _u0800, 'ࠀ', '\u083f');

		public static UnicodeRange Mandaic => _u0840 ?? CreateRange(ref _u0840, 'ࡀ', '\u085f');

		public static UnicodeRange SyriacSupplement => _u0860 ?? CreateRange(ref _u0860, 'ࡠ', '\u086f');

		public static UnicodeRange ArabicExtendedB => _u0870 ?? CreateRange(ref _u0870, '\u0870', '\u089f');

		public static UnicodeRange ArabicExtendedA => _u08A0 ?? CreateRange(ref _u08A0, 'ࢠ', '\u08ff');

		public static UnicodeRange Devanagari => _u0900 ?? CreateRange(ref _u0900, '\u0900', 'ॿ');

		public static UnicodeRange Bengali => _u0980 ?? CreateRange(ref _u0980, 'ঀ', '\u09ff');

		public static UnicodeRange Gurmukhi => _u0A00 ?? CreateRange(ref _u0A00, '\u0a00', '\u0a7f');

		public static UnicodeRange Gujarati => _u0A80 ?? CreateRange(ref _u0A80, '\u0a80', '\u0aff');

		public static UnicodeRange Oriya => _u0B00 ?? CreateRange(ref _u0B00, '\u0b00', '\u0b7f');

		public static UnicodeRange Tamil => _u0B80 ?? CreateRange(ref _u0B80, '\u0b80', '\u0bff');

		public static UnicodeRange Telugu => _u0C00 ?? CreateRange(ref _u0C00, '\u0c00', '౿');

		public static UnicodeRange Kannada => _u0C80 ?? CreateRange(ref _u0C80, 'ಀ', '\u0cff');

		public static UnicodeRange Malayalam => _u0D00 ?? CreateRange(ref _u0D00, '\u0d00', 'ൿ');

		public static UnicodeRange Sinhala => _u0D80 ?? CreateRange(ref _u0D80, '\u0d80', '\u0dff');

		public static UnicodeRange Thai => _u0E00 ?? CreateRange(ref _u0E00, '\u0e00', '\u0e7f');

		public static UnicodeRange Lao => _u0E80 ?? CreateRange(ref _u0E80, '\u0e80', '\u0eff');

		public static UnicodeRange Tibetan => _u0F00 ?? CreateRange(ref _u0F00, 'ༀ', '\u0fff');

		public static UnicodeRange Myanmar => _u1000 ?? CreateRange(ref _u1000, 'က', '႟');

		public static UnicodeRange Georgian => _u10A0 ?? CreateRange(ref _u10A0, 'Ⴀ', 'ჿ');

		public static UnicodeRange HangulJamo => _u1100 ?? CreateRange(ref _u1100, 'ᄀ', 'ᇿ');

		public static UnicodeRange Ethiopic => _u1200 ?? CreateRange(ref _u1200, 'ሀ', '\u137f');

		public static UnicodeRange EthiopicSupplement => _u1380 ?? CreateRange(ref _u1380, 'ᎀ', '\u139f');

		public static UnicodeRange Cherokee => _u13A0 ?? CreateRange(ref _u13A0, 'Ꭰ', '\u13ff');

		public static UnicodeRange UnifiedCanadianAboriginalSyllabics => _u1400 ?? CreateRange(ref _u1400, '᐀', 'ᙿ');

		public static UnicodeRange Ogham => _u1680 ?? CreateRange(ref _u1680, '\u1680', '\u169f');

		public static UnicodeRange Runic => _u16A0 ?? CreateRange(ref _u16A0, 'ᚠ', '\u16ff');

		public static UnicodeRange Tagalog => _u1700 ?? CreateRange(ref _u1700, 'ᜀ', '\u171f');

		public static UnicodeRange Hanunoo => _u1720 ?? CreateRange(ref _u1720, 'ᜠ', '\u173f');

		public static UnicodeRange Buhid => _u1740 ?? CreateRange(ref _u1740, 'ᝀ', '\u175f');

		public static UnicodeRange Tagbanwa => _u1760 ?? CreateRange(ref _u1760, 'ᝠ', '\u177f');

		public static UnicodeRange Khmer => _u1780 ?? CreateRange(ref _u1780, 'ក', '\u17ff');

		public static UnicodeRange Mongolian => _u1800 ?? CreateRange(ref _u1800, '᠀', '\u18af');

		public static UnicodeRange UnifiedCanadianAboriginalSyllabicsExtended => _u18B0 ?? CreateRange(ref _u18B0, 'ᢰ', '\u18ff');

		public static UnicodeRange Limbu => _u1900 ?? CreateRange(ref _u1900, 'ᤀ', '᥏');

		public static UnicodeRange TaiLe => _u1950 ?? CreateRange(ref _u1950, 'ᥐ', '\u197f');

		public static UnicodeRange NewTaiLue => _u1980 ?? CreateRange(ref _u1980, 'ᦀ', '᧟');

		public static UnicodeRange KhmerSymbols => _u19E0 ?? CreateRange(ref _u19E0, '᧠', '᧿');

		public static UnicodeRange Buginese => _u1A00 ?? CreateRange(ref _u1A00, 'ᨀ', '᨟');

		public static UnicodeRange TaiTham => _u1A20 ?? CreateRange(ref _u1A20, 'ᨠ', '\u1aaf');

		public static UnicodeRange CombiningDiacriticalMarksExtended => _u1AB0 ?? CreateRange(ref _u1AB0, '\u1ab0', '\u1aff');

		public static UnicodeRange Balinese => _u1B00 ?? CreateRange(ref _u1B00, '\u1b00', '\u1b7f');

		public static UnicodeRange Sundanese => _u1B80 ?? CreateRange(ref _u1B80, '\u1b80', 'ᮿ');

		public static UnicodeRange Batak => _u1BC0 ?? CreateRange(ref _u1BC0, 'ᯀ', '᯿');

		public static UnicodeRange Lepcha => _u1C00 ?? CreateRange(ref _u1C00, 'ᰀ', 'ᱏ');

		public static UnicodeRange OlChiki => _u1C50 ?? CreateRange(ref _u1C50, '᱐', '᱿');

		public static UnicodeRange CyrillicExtendedC => _u1C80 ?? CreateRange(ref _u1C80, 'ᲀ', '\u1c8f');

		public static UnicodeRange GeorgianExtended => _u1C90 ?? CreateRange(ref _u1C90, 'Ა', 'Ჿ');

		public static UnicodeRange SundaneseSupplement => _u1CC0 ?? CreateRange(ref _u1CC0, '᳀', '\u1ccf');

		public static UnicodeRange VedicExtensions => _u1CD0 ?? CreateRange(ref _u1CD0, '\u1cd0', '\u1cff');

		public static UnicodeRange PhoneticExtensions => _u1D00 ?? CreateRange(ref _u1D00, 'ᴀ', 'ᵿ');

		public static UnicodeRange PhoneticExtensionsSupplement => _u1D80 ?? CreateRange(ref _u1D80, 'ᶀ', 'ᶿ');

		public static UnicodeRange CombiningDiacriticalMarksSupplement => _u1DC0 ?? CreateRange(ref _u1DC0, '\u1dc0', '\u1dff');

		public static UnicodeRange LatinExtendedAdditional => _u1E00 ?? CreateRange(ref _u1E00, 'Ḁ', 'ỿ');

		public static UnicodeRange GreekExtended => _u1F00 ?? CreateRange(ref _u1F00, 'ἀ', '\u1fff');

		public static UnicodeRange GeneralPunctuation => _u2000 ?? CreateRange(ref _u2000, '\u2000', '\u206f');

		public static UnicodeRange SuperscriptsandSubscripts => _u2070 ?? CreateRange(ref _u2070, '⁰', '\u209f');

		public static UnicodeRange CurrencySymbols => _u20A0 ?? CreateRange(ref _u20A0, '₠', '\u20cf');

		public static UnicodeRange CombiningDiacriticalMarksforSymbols => _u20D0 ?? CreateRange(ref _u20D0, '\u20d0', '\u20ff');

		public static UnicodeRange LetterlikeSymbols => _u2100 ?? CreateRange(ref _u2100, '℀', '⅏');

		public static UnicodeRange NumberForms => _u2150 ?? CreateRange(ref _u2150, '⅐', '\u218f');

		public static UnicodeRange Arrows => _u2190 ?? CreateRange(ref _u2190, '←', '⇿');

		public static UnicodeRange MathematicalOperators => _u2200 ?? CreateRange(ref _u2200, '∀', '⋿');

		public static UnicodeRange MiscellaneousTechnical => _u2300 ?? CreateRange(ref _u2300, '⌀', '⏿');

		public static UnicodeRange ControlPictures => _u2400 ?? CreateRange(ref _u2400, '␀', '\u243f');

		public static UnicodeRange OpticalCharacterRecognition => _u2440 ?? CreateRange(ref _u2440, '⑀', '\u245f');

		public static UnicodeRange EnclosedAlphanumerics => _u2460 ?? CreateRange(ref _u2460, '①', '⓿');

		public static UnicodeRange BoxDrawing => _u2500 ?? CreateRange(ref _u2500, '─', '╿');

		public static UnicodeRange BlockElements => _u2580 ?? CreateRange(ref _u2580, '▀', '▟');

		public static UnicodeRange GeometricShapes => _u25A0 ?? CreateRange(ref _u25A0, '■', '◿');

		public static UnicodeRange MiscellaneousSymbols => _u2600 ?? CreateRange(ref _u2600, '☀', '⛿');

		public static UnicodeRange Dingbats => _u2700 ?? CreateRange(ref _u2700, '✀', '➿');

		public static UnicodeRange MiscellaneousMathematicalSymbolsA => _u27C0 ?? CreateRange(ref _u27C0, '⟀', '⟯');

		public static UnicodeRange SupplementalArrowsA => _u27F0 ?? CreateRange(ref _u27F0, '⟰', '⟿');

		public static UnicodeRange BraillePatterns => _u2800 ?? CreateRange(ref _u2800, '⠀', '⣿');

		public static UnicodeRange SupplementalArrowsB => _u2900 ?? CreateRange(ref _u2900, '⤀', '⥿');

		public static UnicodeRange MiscellaneousMathematicalSymbolsB => _u2980 ?? CreateRange(ref _u2980, '⦀', '⧿');

		public static UnicodeRange SupplementalMathematicalOperators => _u2A00 ?? CreateRange(ref _u2A00, '⨀', '⫿');

		public static UnicodeRange MiscellaneousSymbolsandArrows => _u2B00 ?? CreateRange(ref _u2B00, '⬀', '⯿');

		public static UnicodeRange Glagolitic => _u2C00 ?? CreateRange(ref _u2C00, 'Ⰰ', '\u2c5f');

		public static UnicodeRange LatinExtendedC => _u2C60 ?? CreateRange(ref _u2C60, 'Ⱡ', 'Ɀ');

		public static UnicodeRange Coptic => _u2C80 ?? CreateRange(ref _u2C80, 'Ⲁ', '⳿');

		public static UnicodeRange GeorgianSupplement => _u2D00 ?? CreateRange(ref _u2D00, 'ⴀ', '\u2d2f');

		public static UnicodeRange Tifinagh => _u2D30 ?? CreateRange(ref _u2D30, 'ⴰ', '\u2d7f');

		public static UnicodeRange EthiopicExtended => _u2D80 ?? CreateRange(ref _u2D80, 'ⶀ', '\u2ddf');

		public static UnicodeRange CyrillicExtendedA => _u2DE0 ?? CreateRange(ref _u2DE0, '\u2de0', '\u2dff');

		public static UnicodeRange SupplementalPunctuation => _u2E00 ?? CreateRange(ref _u2E00, '⸀', '\u2e7f');

		public static UnicodeRange CjkRadicalsSupplement => _u2E80 ?? CreateRange(ref _u2E80, '⺀', '\u2eff');

		public static UnicodeRange KangxiRadicals => _u2F00 ?? CreateRange(ref _u2F00, '⼀', '\u2fdf');

		public static UnicodeRange IdeographicDescriptionCharacters => _u2FF0 ?? CreateRange(ref _u2FF0, '⿰', '\u2fff');

		public static UnicodeRange CjkSymbolsandPunctuation => _u3000 ?? CreateRange(ref _u3000, '\u3000', '〿');

		public static UnicodeRange Hiragana => _u3040 ?? CreateRange(ref _u3040, '\u3040', 'ゟ');

		public static UnicodeRange Katakana => _u30A0 ?? CreateRange(ref _u30A0, '゠', 'ヿ');

		public static UnicodeRange Bopomofo => _u3100 ?? CreateRange(ref _u3100, '\u3100', 'ㄯ');

		public static UnicodeRange HangulCompatibilityJamo => _u3130 ?? CreateRange(ref _u3130, '\u3130', '\u318f');

		public static UnicodeRange Kanbun => _u3190 ?? CreateRange(ref _u3190, '㆐', '㆟');

		public static UnicodeRange BopomofoExtended => _u31A0 ?? CreateRange(ref _u31A0, 'ㆠ', 'ㆿ');

		public static UnicodeRange CjkStrokes => _u31C0 ?? CreateRange(ref _u31C0, '㇀', '\u31ef');

		public static UnicodeRange KatakanaPhoneticExtensions => _u31F0 ?? CreateRange(ref _u31F0, 'ㇰ', 'ㇿ');

		public static UnicodeRange EnclosedCjkLettersandMonths => _u3200 ?? CreateRange(ref _u3200, '㈀', '㋿');

		public static UnicodeRange CjkCompatibility => _u3300 ?? CreateRange(ref _u3300, '㌀', '㏿');

		public static UnicodeRange CjkUnifiedIdeographsExtensionA => _u3400 ?? CreateRange(ref _u3400, '㐀', '䶿');

		public static UnicodeRange YijingHexagramSymbols => _u4DC0 ?? CreateRange(ref _u4DC0, '䷀', '䷿');

		public static UnicodeRange CjkUnifiedIdeographs => _u4E00 ?? CreateRange(ref _u4E00, '一', '\u9fff');

		public static UnicodeRange YiSyllables => _uA000 ?? CreateRange(ref _uA000, 'ꀀ', '\ua48f');

		public static UnicodeRange YiRadicals => _uA490 ?? CreateRange(ref _uA490, '꒐', '\ua4cf');

		public static UnicodeRange Lisu => _uA4D0 ?? CreateRange(ref _uA4D0, 'ꓐ', '꓿');

		public static UnicodeRange Vai => _uA500 ?? CreateRange(ref _uA500, 'ꔀ', '\ua63f');

		public static UnicodeRange CyrillicExtendedB => _uA640 ?? CreateRange(ref _uA640, 'Ꙁ', '\ua69f');

		public static UnicodeRange Bamum => _uA6A0 ?? CreateRange(ref _uA6A0, 'ꚠ', '\ua6ff');

		public static UnicodeRange ModifierToneLetters => _uA700 ?? CreateRange(ref _uA700, '\ua700', 'ꜟ');

		public static UnicodeRange LatinExtendedD => _uA720 ?? CreateRange(ref _uA720, '\ua720', 'ꟿ');

		public static UnicodeRange SylotiNagri => _uA800 ?? CreateRange(ref _uA800, 'ꠀ', '\ua82f');

		public static UnicodeRange CommonIndicNumberForms => _uA830 ?? CreateRange(ref _uA830, '꠰', '\ua83f');

		public static UnicodeRange Phagspa => _uA840 ?? CreateRange(ref _uA840, 'ꡀ', '\ua87f');

		public static UnicodeRange Saurashtra => _uA880 ?? CreateRange(ref _uA880, '\ua880', '\ua8df');

		public static UnicodeRange DevanagariExtended => _uA8E0 ?? CreateRange(ref _uA8E0, '\ua8e0', '\ua8ff');

		public static UnicodeRange KayahLi => _uA900 ?? CreateRange(ref _uA900, '꤀', '꤯');

		public static UnicodeRange Rejang => _uA930 ?? CreateRange(ref _uA930, 'ꤰ', '꥟');

		public static UnicodeRange HangulJamoExtendedA => _uA960 ?? CreateRange(ref _uA960, 'ꥠ', '\ua97f');

		public static UnicodeRange Javanese => _uA980 ?? CreateRange(ref _uA980, '\ua980', '꧟');

		public static UnicodeRange MyanmarExtendedB => _uA9E0 ?? CreateRange(ref _uA9E0, 'ꧠ', '\ua9ff');

		public static UnicodeRange Cham => _uAA00 ?? CreateRange(ref _uAA00, 'ꨀ', '꩟');

		public static UnicodeRange MyanmarExtendedA => _uAA60 ?? CreateRange(ref _uAA60, 'ꩠ', 'ꩿ');

		public static UnicodeRange TaiViet => _uAA80 ?? CreateRange(ref _uAA80, 'ꪀ', '꫟');

		public static UnicodeRange MeeteiMayekExtensions => _uAAE0 ?? CreateRange(ref _uAAE0, 'ꫠ', '\uaaff');

		public static UnicodeRange EthiopicExtendedA => _uAB00 ?? CreateRange(ref _uAB00, '\uab00', '\uab2f');

		public static UnicodeRange LatinExtendedE => _uAB30 ?? CreateRange(ref _uAB30, 'ꬰ', '\uab6f');

		public static UnicodeRange CherokeeSupplement => _uAB70 ?? CreateRange(ref _uAB70, 'ꭰ', 'ꮿ');

		public static UnicodeRange MeeteiMayek => _uABC0 ?? CreateRange(ref _uABC0, 'ꯀ', '\uabff');

		public static UnicodeRange HangulSyllables => _uAC00 ?? CreateRange(ref _uAC00, '가', '\ud7af');

		public static UnicodeRange HangulJamoExtendedB => _uD7B0 ?? CreateRange(ref _uD7B0, 'ힰ', '\ud7ff');

		public static UnicodeRange CjkCompatibilityIdeographs => _uF900 ?? CreateRange(ref _uF900, '豈', '\ufaff');

		public static UnicodeRange AlphabeticPresentationForms => _uFB00 ?? CreateRange(ref _uFB00, 'ff', 'ﭏ');

		public static UnicodeRange ArabicPresentationFormsA => _uFB50 ?? CreateRange(ref _uFB50, 'ﭐ', '\ufdff');

		public static UnicodeRange VariationSelectors => _uFE00 ?? CreateRange(ref _uFE00, '\ufe00', '\ufe0f');

		public static UnicodeRange VerticalForms => _uFE10 ?? CreateRange(ref _uFE10, '︐', '\ufe1f');

		public static UnicodeRange CombiningHalfMarks => _uFE20 ?? CreateRange(ref _uFE20, '\ufe20', '\ufe2f');

		public static UnicodeRange CjkCompatibilityForms => _uFE30 ?? CreateRange(ref _uFE30, '︰', '\ufe4f');

		public static UnicodeRange SmallFormVariants => _uFE50 ?? CreateRange(ref _uFE50, '﹐', '\ufe6f');

		public static UnicodeRange ArabicPresentationFormsB => _uFE70 ?? CreateRange(ref _uFE70, 'ﹰ', '\ufeff');

		public static UnicodeRange HalfwidthandFullwidthForms => _uFF00 ?? CreateRange(ref _uFF00, '\uff00', '\uffef');

		public static UnicodeRange Specials => _uFFF0 ?? CreateRange(ref _uFFF0, '\ufff0', '\uffff');

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static UnicodeRange CreateEmptyRange([NotNull] ref UnicodeRange range)
		{
			Volatile.Write(ref range, new UnicodeRange(0, 0));
			return range;
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static UnicodeRange CreateRange([NotNull] ref UnicodeRange range, char first, char last)
		{
			Volatile.Write(ref range, UnicodeRange.Create(first, last));
			return range;
		}
	}
}
namespace System.Text.Encodings.Web
{
	internal struct AsciiByteMap
	{
		private const int BufferSize = 128;

		private unsafe fixed byte Buffer[128];

		internal unsafe void InsertAsciiChar(char key, byte value)
		{
			if (key < '\u0080')
			{
				Buffer[(uint)key] = value;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal unsafe readonly bool TryLookup(Rune key, out byte value)
		{
			if (key.IsAscii)
			{
				byte b = Buffer[(uint)key.Value];
				if (b != 0)
				{
					value = b;
					return true;
				}
			}
			value = 0;
			return false;
		}
	}
	internal struct AllowedBmpCodePointsBitmap
	{
		private const int BitmapLengthInDWords = 2048;

		private unsafe fixed uint Bitmap[2048];

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void AllowChar(char value)
		{
			_GetIndexAndOffset(value, out UIntPtr index, out int offset);
			ref uint reference = ref Bitmap[(ulong)index];
			reference |= (uint)(1 << offset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe void ForbidChar(char value)
		{
			_GetIndexAndOffset(value, out UIntPtr index, out int offset);
			ref uint reference = ref Bitmap[(ulong)index];
			reference &= (uint)(~(1 << offset));
		}

		public void ForbidHtmlCharacters()
		{
			ForbidChar('<');
			ForbidChar('>');
			ForbidChar('&');
			ForbidChar('\'');
			ForbidChar('"');
			ForbidChar('+');
		}

		public unsafe void ForbidUndefinedCharacters()
		{
			fixed (uint* pointer = Bitmap)
			{
				ReadOnlySpan<byte> definedBmpCodePointsBitmapLittleEndian = UnicodeHelpers.GetDefinedBmpCodePointsBitmapLittleEndian();
				Span<uint> span = new Span<uint>(pointer, 2048);
				for (int i = 0; i < span.Length; i++)
				{
					span[i] &= BinaryPrimitives.ReadUInt32LittleEndian(definedBmpCodePointsBitmapLittleEndian.Slice(i * 4));
				}
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe readonly bool IsCharAllowed(char value)
		{
			_GetIndexAndOffset(value, out UIntPtr index, out int offset);
			if ((Bitmap[(ulong)index] & (uint)(1 << offset)) != 0)
			{
				return true;
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe read

Mods/RealRadio/System.Text.Json.dll

Decompiled a day ago
using System;
using System.Buffers;
using System.Buffers.Text;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Numerics;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.Encodings.Web;
using System.Text.Json.Nodes;
using System.Text.Json.Reflection;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Converters;
using System.Text.Json.Serialization.Metadata;
using System.Threading;
using System.Threading.Tasks;
using FxResources.System.Text.Json;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: AssemblyDefaultAlias("System.Text.Json")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata("IsTrimmable", "True")]
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyDescription("Provides high-performance and low-allocating types that serialize objects to JavaScript Object Notation (JSON) text and deserialize JSON text to objects, with UTF-8 support built-in. Also provides types to read and write JSON text encoded as UTF-8, and to create an in-memory document object model (DOM), that is read-only, for random access of the JSON elements within a structured view of the data.\r\n\r\nThe System.Text.Json library is built-in as part of the shared framework in .NET Runtime. The package can be installed when you need to use it in other target frameworks.")]
[assembly: AssemblyFileVersion("8.0.724.31311")]
[assembly: AssemblyInformationalVersion("8.0.7+2aade6beb02ea367fd97c4070a4198802fe61c03")]
[assembly: AssemblyProduct("Microsoft® .NET")]
[assembly: AssemblyTitle("System.Text.Json")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/dotnet/runtime")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("8.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: System.Runtime.CompilerServices.NullablePublicOnly(false)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsUnmanagedAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsByRefLikeAttribute : Attribute
	{
	}
	[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 NullablePublicOnlyAttribute : Attribute
	{
		public readonly bool IncludesInternals;

		public NullablePublicOnlyAttribute(bool P_0)
		{
			IncludesInternals = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	internal sealed class ScopedRefAttribute : Attribute
	{
	}
	[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 FxResources.System.Text.Json
{
	internal static class SR
	{
	}
}
namespace System
{
	internal static class HexConverter
	{
		public enum Casing : uint
		{
			Upper = 0u,
			Lower = 8224u
		}

		public static ReadOnlySpan<byte> CharToHexLookup => new byte[256]
		{
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 0, 1,
			2, 3, 4, 5, 6, 7, 8, 9, 255, 255,
			255, 255, 255, 255, 255, 10, 11, 12, 13, 14,
			15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 10, 11, 12,
			13, 14, 15, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
			255, 255, 255, 255, 255, 255
		};

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void ToBytesBuffer(byte value, Span<byte> buffer, int startingIndex = 0, Casing casing = Casing.Upper)
		{
			uint num = (uint)(((value & 0xF0) << 4) + (value & 0xF) - 35209);
			uint num2 = ((((0 - num) & 0x7070) >> 4) + num + 47545) | (uint)casing;
			buffer[startingIndex + 1] = (byte)num2;
			buffer[startingIndex] = (byte)(num2 >> 8);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void ToCharsBuffer(byte value, Span<char> buffer, int startingIndex = 0, Casing casing = Casing.Upper)
		{
			uint num = (uint)(((value & 0xF0) << 4) + (value & 0xF) - 35209);
			uint num2 = ((((0 - num) & 0x7070) >> 4) + num + 47545) | (uint)casing;
			buffer[startingIndex + 1] = (char)(num2 & 0xFFu);
			buffer[startingIndex] = (char)(num2 >> 8);
		}

		public static void EncodeToUtf16(ReadOnlySpan<byte> bytes, Span<char> chars, Casing casing = Casing.Upper)
		{
			for (int i = 0; i < bytes.Length; i++)
			{
				ToCharsBuffer(bytes[i], chars, i * 2, casing);
			}
		}

		public static string ToString(ReadOnlySpan<byte> bytes, Casing casing = Casing.Upper)
		{
			Span<char> span = ((bytes.Length <= 16) ? stackalloc char[bytes.Length * 2] : new char[bytes.Length * 2].AsSpan());
			Span<char> buffer = span;
			int num = 0;
			ReadOnlySpan<byte> readOnlySpan = bytes;
			for (int i = 0; i < readOnlySpan.Length; i++)
			{
				byte value = readOnlySpan[i];
				ToCharsBuffer(value, buffer, num, casing);
				num += 2;
			}
			return buffer.ToString();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static char ToCharUpper(int value)
		{
			value &= 0xF;
			value += 48;
			if (value > 57)
			{
				value += 7;
			}
			return (char)value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static char ToCharLower(int value)
		{
			value &= 0xF;
			value += 48;
			if (value > 57)
			{
				value += 39;
			}
			return (char)value;
		}

		public static bool TryDecodeFromUtf16(ReadOnlySpan<char> chars, Span<byte> bytes)
		{
			int charsProcessed;
			return TryDecodeFromUtf16(chars, bytes, out charsProcessed);
		}

		public static bool TryDecodeFromUtf16(ReadOnlySpan<char> chars, Span<byte> bytes, out int charsProcessed)
		{
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			while (num2 < bytes.Length)
			{
				num3 = FromChar(chars[num + 1]);
				num4 = FromChar(chars[num]);
				if ((num3 | num4) == 255)
				{
					break;
				}
				bytes[num2++] = (byte)((num4 << 4) | num3);
				num += 2;
			}
			if (num3 == 255)
			{
				num++;
			}
			charsProcessed = num;
			return (num3 | num4) != 255;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int FromChar(int c)
		{
			if (c < CharToHexLookup.Length)
			{
				return CharToHexLookup[c];
			}
			return 255;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int FromUpperChar(int c)
		{
			if (c <= 71)
			{
				return CharToHexLookup[c];
			}
			return 255;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int FromLowerChar(int c)
		{
			switch (c)
			{
			case 48:
			case 49:
			case 50:
			case 51:
			case 52:
			case 53:
			case 54:
			case 55:
			case 56:
			case 57:
				return c - 48;
			case 97:
			case 98:
			case 99:
			case 100:
			case 101:
			case 102:
				return c - 97 + 10;
			default:
				return 255;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsHexChar(int c)
		{
			if (IntPtr.Size == 8)
			{
				ulong num = (uint)(c - 48);
				ulong num2 = (ulong)(-17875860044349952L << (int)num);
				ulong num3 = num - 64;
				return (long)(num2 & num3) < 0L;
			}
			return FromChar(c) != 255;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsHexUpperChar(int c)
		{
			if ((uint)(c - 48) > 9u)
			{
				return (uint)(c - 65) <= 5u;
			}
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool IsHexLowerChar(int c)
		{
			if ((uint)(c - 48) > 9u)
			{
				return (uint)(c - 97) <= 5u;
			}
			return true;
		}
	}
	internal static class Obsoletions
	{
		internal const string SharedUrlFormat = "https://aka.ms/dotnet-warnings/{0}";

		internal const string SystemTextEncodingUTF7Message = "The UTF-7 encoding is insecure and should not be used. Consider using UTF-8 instead.";

		internal const string SystemTextEncodingUTF7DiagId = "SYSLIB0001";

		internal const string PrincipalPermissionAttributeMessage = "PrincipalPermissionAttribute is not honored by the runtime and must not be used.";

		internal const string PrincipalPermissionAttributeDiagId = "SYSLIB0002";

		internal const string CodeAccessSecurityMessage = "Code Access Security is not supported or honored by the runtime.";

		internal const string CodeAccessSecurityDiagId = "SYSLIB0003";

		internal const string ConstrainedExecutionRegionMessage = "The Constrained Execution Region (CER) feature is not supported.";

		internal const string ConstrainedExecutionRegionDiagId = "SYSLIB0004";

		internal const string GlobalAssemblyCacheMessage = "The Global Assembly Cache is not supported.";

		internal const string GlobalAssemblyCacheDiagId = "SYSLIB0005";

		internal const string ThreadAbortMessage = "Thread.Abort is not supported and throws PlatformNotSupportedException.";

		internal const string ThreadResetAbortMessage = "Thread.ResetAbort is not supported and throws PlatformNotSupportedException.";

		internal const string ThreadAbortDiagId = "SYSLIB0006";

		internal const string DefaultCryptoAlgorithmsMessage = "The default implementation of this cryptography algorithm is not supported.";

		internal const string DefaultCryptoAlgorithmsDiagId = "SYSLIB0007";

		internal const string CreatePdbGeneratorMessage = "The CreatePdbGenerator API is not supported and throws PlatformNotSupportedException.";

		internal const string CreatePdbGeneratorDiagId = "SYSLIB0008";

		internal const string AuthenticationManagerMessage = "The AuthenticationManager Authenticate and PreAuthenticate methods are not supported and throw PlatformNotSupportedException.";

		internal const string AuthenticationManagerDiagId = "SYSLIB0009";

		internal const string RemotingApisMessage = "This Remoting API is not supported and throws PlatformNotSupportedException.";

		internal const string RemotingApisDiagId = "SYSLIB0010";

		internal const string BinaryFormatterMessage = "BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.";

		internal const string BinaryFormatterDiagId = "SYSLIB0011";

		internal const string CodeBaseMessage = "Assembly.CodeBase and Assembly.EscapedCodeBase are only included for .NET Framework compatibility. Use Assembly.Location instead.";

		internal const string CodeBaseDiagId = "SYSLIB0012";

		internal const string EscapeUriStringMessage = "Uri.EscapeUriString can corrupt the Uri string in some cases. Consider using Uri.EscapeDataString for query string components instead.";

		internal const string EscapeUriStringDiagId = "SYSLIB0013";

		internal const string WebRequestMessage = "WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.";

		internal const string WebRequestDiagId = "SYSLIB0014";

		internal const string DisablePrivateReflectionAttributeMessage = "DisablePrivateReflectionAttribute has no effect in .NET 6.0+.";

		internal const string DisablePrivateReflectionAttributeDiagId = "SYSLIB0015";

		internal const string GetContextInfoMessage = "Use the Graphics.GetContextInfo overloads that accept arguments for better performance and fewer allocations.";

		internal const string GetContextInfoDiagId = "SYSLIB0016";

		internal const string StrongNameKeyPairMessage = "Strong name signing is not supported and throws PlatformNotSupportedException.";

		internal const string StrongNameKeyPairDiagId = "SYSLIB0017";

		internal const string ReflectionOnlyLoadingMessage = "ReflectionOnly loading is not supported and throws PlatformNotSupportedException.";

		internal const string ReflectionOnlyLoadingDiagId = "SYSLIB0018";

		internal const string RuntimeEnvironmentMessage = "RuntimeEnvironment members SystemConfigurationFile, GetRuntimeInterfaceAsIntPtr, and GetRuntimeInterfaceAsObject are not supported and throw PlatformNotSupportedException.";

		internal const string RuntimeEnvironmentDiagId = "SYSLIB0019";

		internal const string JsonSerializerOptionsIgnoreNullValuesMessage = "JsonSerializerOptions.IgnoreNullValues is obsolete. To ignore null values when serializing, set DefaultIgnoreCondition to JsonIgnoreCondition.WhenWritingNull.";

		internal const string JsonSerializerOptionsIgnoreNullValuesDiagId = "SYSLIB0020";

		internal const string DerivedCryptographicTypesMessage = "Derived cryptographic types are obsolete. Use the Create method on the base type instead.";

		internal const string DerivedCryptographicTypesDiagId = "SYSLIB0021";

		internal const string RijndaelMessage = "The Rijndael and RijndaelManaged types are obsolete. Use Aes instead.";

		internal const string RijndaelDiagId = "SYSLIB0022";

		internal const string RNGCryptoServiceProviderMessage = "RNGCryptoServiceProvider is obsolete. To generate a random number, use one of the RandomNumberGenerator static methods instead.";

		internal const string RNGCryptoServiceProviderDiagId = "SYSLIB0023";

		internal const string AppDomainCreateUnloadMessage = "Creating and unloading AppDomains is not supported and throws an exception.";

		internal const string AppDomainCreateUnloadDiagId = "SYSLIB0024";

		internal const string SuppressIldasmAttributeMessage = "SuppressIldasmAttribute has no effect in .NET 6.0+.";

		internal const string SuppressIldasmAttributeDiagId = "SYSLIB0025";

		internal const string X509CertificateImmutableMessage = "X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.";

		internal const string X509CertificateImmutableDiagId = "SYSLIB0026";

		internal const string PublicKeyPropertyMessage = "PublicKey.Key is obsolete. Use the appropriate method to get the public key, such as GetRSAPublicKey.";

		internal const string PublicKeyPropertyDiagId = "SYSLIB0027";

		internal const string X509CertificatePrivateKeyMessage = "X509Certificate2.PrivateKey is obsolete. Use the appropriate method to get the private key, such as GetRSAPrivateKey, or use the CopyWithPrivateKey method to create a new instance with a private key.";

		internal const string X509CertificatePrivateKeyDiagId = "SYSLIB0028";

		internal const string ProduceLegacyHmacValuesMessage = "ProduceLegacyHmacValues is obsolete. Producing legacy HMAC values is not supported.";

		internal const string ProduceLegacyHmacValuesDiagId = "SYSLIB0029";

		internal const string UseManagedSha1Message = "HMACSHA1 always uses the algorithm implementation provided by the platform. Use a constructor without the useManagedSha1 parameter.";

		internal const string UseManagedSha1DiagId = "SYSLIB0030";

		internal const string CryptoConfigEncodeOIDMessage = "EncodeOID is obsolete. Use the ASN.1 functionality provided in System.Formats.Asn1.";

		internal const string CryptoConfigEncodeOIDDiagId = "SYSLIB0031";

		internal const string CorruptedStateRecoveryMessage = "Recovery from corrupted process state exceptions is not supported; HandleProcessCorruptedStateExceptionsAttribute is ignored.";

		internal const string CorruptedStateRecoveryDiagId = "SYSLIB0032";

		internal const string Rfc2898CryptDeriveKeyMessage = "Rfc2898DeriveBytes.CryptDeriveKey is obsolete and is not supported. Use PasswordDeriveBytes.CryptDeriveKey instead.";

		internal const string Rfc2898CryptDeriveKeyDiagId = "SYSLIB0033";

		internal const string CmsSignerCspParamsCtorMessage = "CmsSigner(CspParameters) is obsolete and is not supported. Use an alternative constructor instead.";

		internal const string CmsSignerCspParamsCtorDiagId = "SYSLIB0034";

		internal const string SignerInfoCounterSigMessage = "ComputeCounterSignature without specifying a CmsSigner is obsolete and is not supported. Use the overload that accepts a CmsSigner.";

		internal const string SignerInfoCounterSigDiagId = "SYSLIB0035";

		internal const string RegexCompileToAssemblyMessage = "Regex.CompileToAssembly is obsolete and not supported. Use the GeneratedRegexAttribute with the regular expression source generator instead.";

		internal const string RegexCompileToAssemblyDiagId = "SYSLIB0036";

		internal const string AssemblyNameMembersMessage = "AssemblyName members HashAlgorithm, ProcessorArchitecture, and VersionCompatibility are obsolete and not supported.";

		internal const string AssemblyNameMembersDiagId = "SYSLIB0037";

		internal const string SystemDataSerializationFormatBinaryMessage = "SerializationFormat.Binary is obsolete and should not be used. See https://aka.ms/serializationformat-binary-obsolete for more information.";

		internal const string SystemDataSerializationFormatBinaryDiagId = "SYSLIB0038";

		internal const string TlsVersion10and11Message = "TLS versions 1.0 and 1.1 have known vulnerabilities and are not recommended. Use a newer TLS version instead, or use SslProtocols.None to defer to OS defaults.";

		internal const string TlsVersion10and11DiagId = "SYSLIB0039";

		internal const string EncryptionPolicyMessage = "EncryptionPolicy.NoEncryption and AllowEncryption significantly reduce security and should not be used in production code.";

		internal const string EncryptionPolicyDiagId = "SYSLIB0040";

		internal const string Rfc2898OutdatedCtorMessage = "The default hash algorithm and iteration counts in Rfc2898DeriveBytes constructors are outdated and insecure. Use a constructor that accepts the hash algorithm and the number of iterations.";

		internal const string Rfc2898OutdatedCtorDiagId = "SYSLIB0041";

		internal const string EccXmlExportImportMessage = "ToXmlString and FromXmlString have no implementation for ECC types, and are obsolete. Use a standard import and export format such as ExportSubjectPublicKeyInfo or ImportSubjectPublicKeyInfo for public keys and ExportPkcs8PrivateKey or ImportPkcs8PrivateKey for private keys.";

		internal const string EccXmlExportImportDiagId = "SYSLIB0042";

		internal const string EcDhPublicKeyBlobMessage = "ECDiffieHellmanPublicKey.ToByteArray() and the associated constructor do not have a consistent and interoperable implementation on all platforms. Use ECDiffieHellmanPublicKey.ExportSubjectPublicKeyInfo() instead.";

		internal const string EcDhPublicKeyBlobDiagId = "SYSLIB0043";

		internal const string AssemblyNameCodeBaseMessage = "AssemblyName.CodeBase and AssemblyName.EscapedCodeBase are obsolete. Using them for loading an assembly is not supported.";

		internal const string AssemblyNameCodeBaseDiagId = "SYSLIB0044";

		internal const string CryptoStringFactoryMessage = "Cryptographic factory methods accepting an algorithm name are obsolete. Use the parameterless Create factory method on the algorithm type instead.";

		internal const string CryptoStringFactoryDiagId = "SYSLIB0045";

		internal const string ControlledExecutionRunMessage = "ControlledExecution.Run method may corrupt the process and should not be used in production code.";

		internal const string ControlledExecutionRunDiagId = "SYSLIB0046";

		internal const string XmlSecureResolverMessage = "XmlSecureResolver is obsolete. Use XmlResolver.ThrowingResolver instead when attempting to forbid XML external entity resolution.";

		internal const string XmlSecureResolverDiagId = "SYSLIB0047";

		internal const string RsaEncryptDecryptValueMessage = "RSA.EncryptValue and DecryptValue are not supported and throw NotSupportedException. Use RSA.Encrypt and RSA.Decrypt instead.";

		internal const string RsaEncryptDecryptDiagId = "SYSLIB0048";

		internal const string JsonSerializerOptionsAddContextMessage = "JsonSerializerOptions.AddContext is obsolete. To register a JsonSerializerContext, use either the TypeInfoResolver or TypeInfoResolverChain properties.";

		internal const string JsonSerializerOptionsAddContextDiagId = "SYSLIB0049";

		internal const string LegacyFormatterMessage = "Formatter-based serialization is obsolete and should not be used.";

		internal const string LegacyFormatterDiagId = "SYSLIB0050";

		internal const string LegacyFormatterImplMessage = "This API supports obsolete formatter-based serialization. It should not be called or extended by application code.";

		internal const string LegacyFormatterImplDiagId = "SYSLIB0051";

		internal const string RegexExtensibilityImplMessage = "This API supports obsolete mechanisms for Regex extensibility. It is not supported.";

		internal const string RegexExtensibilityDiagId = "SYSLIB0052";

		internal const string AesGcmTagConstructorMessage = "AesGcm should indicate the required tag size for encryption and decryption. Use a constructor that accepts the tag size.";

		internal const string AesGcmTagConstructorDiagId = "SYSLIB0053";
	}
	internal static class SR
	{
		private static readonly bool s_usingResourceKeys = AppContext.TryGetSwitch("System.Resources.UseSystemResourceKeys", out var isEnabled) && isEnabled;

		private static ResourceManager s_resourceManager;

		internal static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(typeof(SR)));

		internal static string ArrayDepthTooLarge => GetResourceString("ArrayDepthTooLarge");

		internal static string CallFlushToAvoidDataLoss => GetResourceString("CallFlushToAvoidDataLoss");

		internal static string CannotReadIncompleteUTF16 => GetResourceString("CannotReadIncompleteUTF16");

		internal static string CannotReadInvalidUTF16 => GetResourceString("CannotReadInvalidUTF16");

		internal static string CannotStartObjectArrayAfterPrimitiveOrClose => GetResourceString("CannotStartObjectArrayAfterPrimitiveOrClose");

		internal static string CannotStartObjectArrayWithoutProperty => GetResourceString("CannotStartObjectArrayWithoutProperty");

		internal static string CannotTranscodeInvalidUtf8 => GetResourceString("CannotTranscodeInvalidUtf8");

		internal static string CannotDecodeInvalidBase64 => GetResourceString("CannotDecodeInvalidBase64");

		internal static string CannotTranscodeInvalidUtf16 => GetResourceString("CannotTranscodeInvalidUtf16");

		internal static string CannotEncodeInvalidUTF16 => GetResourceString("CannotEncodeInvalidUTF16");

		internal static string CannotEncodeInvalidUTF8 => GetResourceString("CannotEncodeInvalidUTF8");

		internal static string CannotWritePropertyWithinArray => GetResourceString("CannotWritePropertyWithinArray");

		internal static string CannotWritePropertyAfterProperty => GetResourceString("CannotWritePropertyAfterProperty");

		internal static string CannotWriteValueAfterPrimitiveOrClose => GetResourceString("CannotWriteValueAfterPrimitiveOrClose");

		internal static string CannotWriteValueWithinObject => GetResourceString("CannotWriteValueWithinObject");

		internal static string DepthTooLarge => GetResourceString("DepthTooLarge");

		internal static string DestinationTooShort => GetResourceString("DestinationTooShort");

		internal static string EmptyJsonIsInvalid => GetResourceString("EmptyJsonIsInvalid");

		internal static string EndOfCommentNotFound => GetResourceString("EndOfCommentNotFound");

		internal static string EndOfStringNotFound => GetResourceString("EndOfStringNotFound");

		internal static string ExpectedEndAfterSingleJson => GetResourceString("ExpectedEndAfterSingleJson");

		internal static string ExpectedEndOfDigitNotFound => GetResourceString("ExpectedEndOfDigitNotFound");

		internal static string ExpectedFalse => GetResourceString("ExpectedFalse");

		internal static string ExpectedJsonTokens => GetResourceString("ExpectedJsonTokens");

		internal static string ExpectedOneCompleteToken => GetResourceString("ExpectedOneCompleteToken");

		internal static string ExpectedNextDigitEValueNotFound => GetResourceString("ExpectedNextDigitEValueNotFound");

		internal static string ExpectedNull => GetResourceString("ExpectedNull");

		internal static string ExpectedSeparatorAfterPropertyNameNotFound => GetResourceString("ExpectedSeparatorAfterPropertyNameNotFound");

		internal static string ExpectedStartOfPropertyNotFound => GetResourceString("ExpectedStartOfPropertyNotFound");

		internal static string ExpectedStartOfPropertyOrValueNotFound => GetResourceString("ExpectedStartOfPropertyOrValueNotFound");

		internal static string ExpectedStartOfValueNotFound => GetResourceString("ExpectedStartOfValueNotFound");

		internal static string ExpectedTrue => GetResourceString("ExpectedTrue");

		internal static string ExpectedValueAfterPropertyNameNotFound => GetResourceString("ExpectedValueAfterPropertyNameNotFound");

		internal static string FailedToGetLargerSpan => GetResourceString("FailedToGetLargerSpan");

		internal static string FoundInvalidCharacter => GetResourceString("FoundInvalidCharacter");

		internal static string InvalidCast => GetResourceString("InvalidCast");

		internal static string InvalidCharacterAfterEscapeWithinString => GetResourceString("InvalidCharacterAfterEscapeWithinString");

		internal static string InvalidCharacterWithinString => GetResourceString("InvalidCharacterWithinString");

		internal static string InvalidEnumTypeWithSpecialChar => GetResourceString("InvalidEnumTypeWithSpecialChar");

		internal static string InvalidEndOfJsonNonPrimitive => GetResourceString("InvalidEndOfJsonNonPrimitive");

		internal static string InvalidHexCharacterWithinString => GetResourceString("InvalidHexCharacterWithinString");

		internal static string JsonDocumentDoesNotSupportComments => GetResourceString("JsonDocumentDoesNotSupportComments");

		internal static string JsonElementHasWrongType => GetResourceString("JsonElementHasWrongType");

		internal static string DefaultTypeInfoResolverImmutable => GetResourceString("DefaultTypeInfoResolverImmutable");

		internal static string TypeInfoResolverChainImmutable => GetResourceString("TypeInfoResolverChainImmutable");

		internal static string TypeInfoImmutable => GetResourceString("TypeInfoImmutable");

		internal static string MaxDepthMustBePositive => GetResourceString("MaxDepthMustBePositive");

		internal static string CommentHandlingMustBeValid => GetResourceString("CommentHandlingMustBeValid");

		internal static string MismatchedObjectArray => GetResourceString("MismatchedObjectArray");

		internal static string CannotWriteEndAfterProperty => GetResourceString("CannotWriteEndAfterProperty");

		internal static string ObjectDepthTooLarge => GetResourceString("ObjectDepthTooLarge");

		internal static string PropertyNameTooLarge => GetResourceString("PropertyNameTooLarge");

		internal static string FormatDecimal => GetResourceString("FormatDecimal");

		internal static string FormatDouble => GetResourceString("FormatDouble");

		internal static string FormatInt32 => GetResourceString("FormatInt32");

		internal static string FormatInt64 => GetResourceString("FormatInt64");

		internal static string FormatSingle => GetResourceString("FormatSingle");

		internal static string FormatUInt32 => GetResourceString("FormatUInt32");

		internal static string FormatUInt64 => GetResourceString("FormatUInt64");

		internal static string RequiredDigitNotFoundAfterDecimal => GetResourceString("RequiredDigitNotFoundAfterDecimal");

		internal static string RequiredDigitNotFoundAfterSign => GetResourceString("RequiredDigitNotFoundAfterSign");

		internal static string RequiredDigitNotFoundEndOfData => GetResourceString("RequiredDigitNotFoundEndOfData");

		internal static string SpecialNumberValuesNotSupported => GetResourceString("SpecialNumberValuesNotSupported");

		internal static string ValueTooLarge => GetResourceString("ValueTooLarge");

		internal static string ZeroDepthAtEnd => GetResourceString("ZeroDepthAtEnd");

		internal static string DeserializeUnableToConvertValue => GetResourceString("DeserializeUnableToConvertValue");

		internal static string DeserializeWrongType => GetResourceString("DeserializeWrongType");

		internal static string SerializationInvalidBufferSize => GetResourceString("SerializationInvalidBufferSize");

		internal static string BufferWriterAdvancedTooFar => GetResourceString("BufferWriterAdvancedTooFar");

		internal static string InvalidComparison => GetResourceString("InvalidComparison");

		internal static string UnsupportedFormat => GetResourceString("UnsupportedFormat");

		internal static string ExpectedStartOfPropertyOrValueAfterComment => GetResourceString("ExpectedStartOfPropertyOrValueAfterComment");

		internal static string TrailingCommaNotAllowedBeforeArrayEnd => GetResourceString("TrailingCommaNotAllowedBeforeArrayEnd");

		internal static string TrailingCommaNotAllowedBeforeObjectEnd => GetResourceString("TrailingCommaNotAllowedBeforeObjectEnd");

		internal static string SerializerOptionsReadOnly => GetResourceString("SerializerOptionsReadOnly");

		internal static string SerializerOptions_InvalidChainedResolver => GetResourceString("SerializerOptions_InvalidChainedResolver");

		internal static string StreamNotWritable => GetResourceString("StreamNotWritable");

		internal static string CannotWriteCommentWithEmbeddedDelimiter => GetResourceString("CannotWriteCommentWithEmbeddedDelimiter");

		internal static string SerializerPropertyNameConflict => GetResourceString("SerializerPropertyNameConflict");

		internal static string SerializerPropertyNameNull => GetResourceString("SerializerPropertyNameNull");

		internal static string SerializationDataExtensionPropertyInvalid => GetResourceString("SerializationDataExtensionPropertyInvalid");

		internal static string SerializationDuplicateTypeAttribute => GetResourceString("SerializationDuplicateTypeAttribute");

		internal static string ExtensionDataConflictsWithUnmappedMemberHandling => GetResourceString("ExtensionDataConflictsWithUnmappedMemberHandling");

		internal static string SerializationNotSupportedType => GetResourceString("SerializationNotSupportedType");

		internal static string TypeRequiresAsyncSerialization => GetResourceString("TypeRequiresAsyncSerialization");

		internal static string InvalidCharacterAtStartOfComment => GetResourceString("InvalidCharacterAtStartOfComment");

		internal static string UnexpectedEndOfDataWhileReadingComment => GetResourceString("UnexpectedEndOfDataWhileReadingComment");

		internal static string CannotSkip => GetResourceString("CannotSkip");

		internal static string NotEnoughData => GetResourceString("NotEnoughData");

		internal static string UnexpectedEndOfLineSeparator => GetResourceString("UnexpectedEndOfLineSeparator");

		internal static string JsonSerializerDoesNotSupportComments => GetResourceString("JsonSerializerDoesNotSupportComments");

		internal static string DeserializeNoConstructor => GetResourceString("DeserializeNoConstructor");

		internal static string DeserializePolymorphicInterface => GetResourceString("DeserializePolymorphicInterface");

		internal static string SerializationConverterOnAttributeNotCompatible => GetResourceString("SerializationConverterOnAttributeNotCompatible");

		internal static string SerializationConverterOnAttributeInvalid => GetResourceString("SerializationConverterOnAttributeInvalid");

		internal static string SerializationConverterRead => GetResourceString("SerializationConverterRead");

		internal static string SerializationConverterNotCompatible => GetResourceString("SerializationConverterNotCompatible");

		internal static string ResolverTypeNotCompatible => GetResourceString("ResolverTypeNotCompatible");

		internal static string ResolverTypeInfoOptionsNotCompatible => GetResourceString("ResolverTypeInfoOptionsNotCompatible");

		internal static string SerializationConverterWrite => GetResourceString("SerializationConverterWrite");

		internal static string NamingPolicyReturnNull => GetResourceString("NamingPolicyReturnNull");

		internal static string SerializationDuplicateAttribute => GetResourceString("SerializationDuplicateAttribute");

		internal static string SerializeUnableToSerialize => GetResourceString("SerializeUnableToSerialize");

		internal static string FormatByte => GetResourceString("FormatByte");

		internal static string FormatInt16 => GetResourceString("FormatInt16");

		internal static string FormatSByte => GetResourceString("FormatSByte");

		internal static string FormatUInt16 => GetResourceString("FormatUInt16");

		internal static string SerializerCycleDetected => GetResourceString("SerializerCycleDetected");

		internal static string InvalidLeadingZeroInNumber => GetResourceString("InvalidLeadingZeroInNumber");

		internal static string MetadataCannotParsePreservedObjectToImmutable => GetResourceString("MetadataCannotParsePreservedObjectToImmutable");

		internal static string MetadataDuplicateIdFound => GetResourceString("MetadataDuplicateIdFound");

		internal static string MetadataIdIsNotFirstProperty => GetResourceString("MetadataIdIsNotFirstProperty");

		internal static string MetadataInvalidReferenceToValueType => GetResourceString("MetadataInvalidReferenceToValueType");

		internal static string MetadataInvalidTokenAfterValues => GetResourceString("MetadataInvalidTokenAfterValues");

		internal static string MetadataPreservedArrayFailed => GetResourceString("MetadataPreservedArrayFailed");

		internal static string MetadataInvalidPropertyInArrayMetadata => GetResourceString("MetadataInvalidPropertyInArrayMetadata");

		internal static string MetadataStandaloneValuesProperty => GetResourceString("MetadataStandaloneValuesProperty");

		internal static string MetadataReferenceCannotContainOtherProperties => GetResourceString("MetadataReferenceCannotContainOtherProperties");

		internal static string MetadataReferenceNotFound => GetResourceString("MetadataReferenceNotFound");

		internal static string MetadataValueWasNotString => GetResourceString("MetadataValueWasNotString");

		internal static string MetadataInvalidPropertyWithLeadingDollarSign => GetResourceString("MetadataInvalidPropertyWithLeadingDollarSign");

		internal static string MetadataUnexpectedProperty => GetResourceString("MetadataUnexpectedProperty");

		internal static string UnmappedJsonProperty => GetResourceString("UnmappedJsonProperty");

		internal static string MetadataDuplicateTypeProperty => GetResourceString("MetadataDuplicateTypeProperty");

		internal static string MultipleMembersBindWithConstructorParameter => GetResourceString("MultipleMembersBindWithConstructorParameter");

		internal static string ConstructorParamIncompleteBinding => GetResourceString("ConstructorParamIncompleteBinding");

		internal static string ObjectWithParameterizedCtorRefMetadataNotSupported => GetResourceString("ObjectWithParameterizedCtorRefMetadataNotSupported");

		internal static string SerializerConverterFactoryReturnsNull => GetResourceString("SerializerConverterFactoryReturnsNull");

		internal static string SerializationNotSupportedParentType => GetResourceString("SerializationNotSupportedParentType");

		internal static string ExtensionDataCannotBindToCtorParam => GetResourceString("ExtensionDataCannotBindToCtorParam");

		internal static string BufferMaximumSizeExceeded => GetResourceString("BufferMaximumSizeExceeded");

		internal static string CannotSerializeInvalidType => GetResourceString("CannotSerializeInvalidType");

		internal static string SerializeTypeInstanceNotSupported => GetResourceString("SerializeTypeInstanceNotSupported");

		internal static string JsonIncludeOnInaccessibleProperty => GetResourceString("JsonIncludeOnInaccessibleProperty");

		internal static string CannotSerializeInvalidMember => GetResourceString("CannotSerializeInvalidMember");

		internal static string CannotPopulateCollection => GetResourceString("CannotPopulateCollection");

		internal static string ConstructorContainsNullParameterNames => GetResourceString("ConstructorContainsNullParameterNames");

		internal static string DefaultIgnoreConditionAlreadySpecified => GetResourceString("DefaultIgnoreConditionAlreadySpecified");

		internal static string DefaultIgnoreConditionInvalid => GetResourceString("DefaultIgnoreConditionInvalid");

		internal static string DictionaryKeyTypeNotSupported => GetResourceString("DictionaryKeyTypeNotSupported");

		internal static string IgnoreConditionOnValueTypeInvalid => GetResourceString("IgnoreConditionOnValueTypeInvalid");

		internal static string NumberHandlingOnPropertyInvalid => GetResourceString("NumberHandlingOnPropertyInvalid");

		internal static string ConverterCanConvertMultipleTypes => GetResourceString("ConverterCanConvertMultipleTypes");

		internal static string MetadataReferenceOfTypeCannotBeAssignedToType => GetResourceString("MetadataReferenceOfTypeCannotBeAssignedToType");

		internal static string DeserializeUnableToAssignValue => GetResourceString("DeserializeUnableToAssignValue");

		internal static string DeserializeUnableToAssignNull => GetResourceString("DeserializeUnableToAssignNull");

		internal static string SerializerConverterFactoryReturnsJsonConverterFactory => GetResourceString("SerializerConverterFactoryReturnsJsonConverterFactory");

		internal static string SerializerConverterFactoryInvalidArgument => GetResourceString("SerializerConverterFactoryInvalidArgument");

		internal static string NodeElementWrongType => GetResourceString("NodeElementWrongType");

		internal static string NodeElementCannotBeObjectOrArray => GetResourceString("NodeElementCannotBeObjectOrArray");

		internal static string NodeAlreadyHasParent => GetResourceString("NodeAlreadyHasParent");

		internal static string NodeCycleDetected => GetResourceString("NodeCycleDetected");

		internal static string NodeUnableToConvert => GetResourceString("NodeUnableToConvert");

		internal static string NodeUnableToConvertElement => GetResourceString("NodeUnableToConvertElement");

		internal static string NodeValueNotAllowed => GetResourceString("NodeValueNotAllowed");

		internal static string NodeWrongType => GetResourceString("NodeWrongType");

		internal static string NodeParentWrongType => GetResourceString("NodeParentWrongType");

		internal static string NodeDuplicateKey => GetResourceString("NodeDuplicateKey");

		internal static string SerializerContextOptionsReadOnly => GetResourceString("SerializerContextOptionsReadOnly");

		internal static string ConverterForPropertyMustBeValid => GetResourceString("ConverterForPropertyMustBeValid");

		internal static string NoMetadataForType => GetResourceString("NoMetadataForType");

		internal static string AmbiguousMetadataForType => GetResourceString("AmbiguousMetadataForType");

		internal static string CollectionIsReadOnly => GetResourceString("CollectionIsReadOnly");

		internal static string ArrayIndexNegative => GetResourceString("ArrayIndexNegative");

		internal static string ArrayTooSmall => GetResourceString("ArrayTooSmall");

		internal static string NodeJsonObjectCustomConverterNotAllowedOnExtensionProperty => GetResourceString("NodeJsonObjectCustomConverterNotAllowedOnExtensionProperty");

		internal static string NoMetadataForTypeProperties => GetResourceString("NoMetadataForTypeProperties");

		internal static string FieldCannotBeVirtual => GetResourceString("FieldCannotBeVirtual");

		internal static string MissingFSharpCoreMember => GetResourceString("MissingFSharpCoreMember");

		internal static string FSharpDiscriminatedUnionsNotSupported => GetResourceString("FSharpDiscriminatedUnionsNotSupported");

		internal static string Polymorphism_BaseConverterDoesNotSupportMetadata => GetResourceString("Polymorphism_BaseConverterDoesNotSupportMetadata");

		internal static string Polymorphism_DerivedConverterDoesNotSupportMetadata => GetResourceString("Polymorphism_DerivedConverterDoesNotSupportMetadata");

		internal static string Polymorphism_TypeDoesNotSupportPolymorphism => GetResourceString("Polymorphism_TypeDoesNotSupportPolymorphism");

		internal static string Polymorphism_DerivedTypeIsNotSupported => GetResourceString("Polymorphism_DerivedTypeIsNotSupported");

		internal static string Polymorphism_DerivedTypeIsAlreadySpecified => GetResourceString("Polymorphism_DerivedTypeIsAlreadySpecified");

		internal static string Polymorphism_TypeDicriminatorIdIsAlreadySpecified => GetResourceString("Polymorphism_TypeDicriminatorIdIsAlreadySpecified");

		internal static string Polymorphism_InvalidCustomTypeDiscriminatorPropertyName => GetResourceString("Polymorphism_InvalidCustomTypeDiscriminatorPropertyName");

		internal static string Polymorphism_ConfigurationDoesNotSpecifyDerivedTypes => GetResourceString("Polymorphism_ConfigurationDoesNotSpecifyDerivedTypes");

		internal static string Polymorphism_UnrecognizedTypeDiscriminator => GetResourceString("Polymorphism_UnrecognizedTypeDiscriminator");

		internal static string Polymorphism_RuntimeTypeNotSupported => GetResourceString("Polymorphism_RuntimeTypeNotSupported");

		internal static string Polymorphism_RuntimeTypeDiamondAmbiguity => GetResourceString("Polymorphism_RuntimeTypeDiamondAmbiguity");

		internal static string InvalidJsonTypeInfoOperationForKind => GetResourceString("InvalidJsonTypeInfoOperationForKind");

		internal static string CreateObjectConverterNotCompatible => GetResourceString("CreateObjectConverterNotCompatible");

		internal static string JsonPropertyInfoBoundToDifferentParent => GetResourceString("JsonPropertyInfoBoundToDifferentParent");

		internal static string JsonSerializerOptionsNoTypeInfoResolverSpecified => GetResourceString("JsonSerializerOptionsNoTypeInfoResolverSpecified");

		internal static string JsonSerializerIsReflectionDisabled => GetResourceString("JsonSerializerIsReflectionDisabled");

		internal static string JsonPolymorphismOptionsAssociatedWithDifferentJsonTypeInfo => GetResourceString("JsonPolymorphismOptionsAssociatedWithDifferentJsonTypeInfo");

		internal static string JsonPropertyRequiredAndNotDeserializable => GetResourceString("JsonPropertyRequiredAndNotDeserializable");

		internal static string JsonPropertyRequiredAndExtensionData => GetResourceString("JsonPropertyRequiredAndExtensionData");

		internal static string JsonRequiredPropertiesMissing => GetResourceString("JsonRequiredPropertiesMissing");

		internal static string ObjectCreationHandlingPopulateNotSupportedByConverter => GetResourceString("ObjectCreationHandlingPopulateNotSupportedByConverter");

		internal static string ObjectCreationHandlingPropertyMustHaveAGetter => GetResourceString("ObjectCreationHandlingPropertyMustHaveAGetter");

		internal static string ObjectCreationHandlingPropertyValueTypeMustHaveASetter => GetResourceString("ObjectCreationHandlingPropertyValueTypeMustHaveASetter");

		internal static string ObjectCreationHandlingPropertyCannotAllowPolymorphicDeserialization => GetResourceString("ObjectCreationHandlingPropertyCannotAllowPolymorphicDeserialization");

		internal static string ObjectCreationHandlingPropertyCannotAllowReadOnlyMember => GetResourceString("ObjectCreationHandlingPropertyCannotAllowReadOnlyMember");

		internal static string ObjectCreationHandlingPropertyCannotAllowReferenceHandling => GetResourceString("ObjectCreationHandlingPropertyCannotAllowReferenceHandling");

		internal static string ObjectCreationHandlingPropertyDoesNotSupportParameterizedConstructors => GetResourceString("ObjectCreationHandlingPropertyDoesNotSupportParameterizedConstructors");

		internal static string FormatInt128 => GetResourceString("FormatInt128");

		internal static string FormatUInt128 => GetResourceString("FormatUInt128");

		internal static string FormatHalf => GetResourceString("FormatHalf");

		internal static bool UsingResourceKeys()
		{
			return s_usingResourceKeys;
		}

		private static string GetResourceString(string resourceKey)
		{
			if (UsingResourceKeys())
			{
				return resourceKey;
			}
			string result = null;
			try
			{
				result = ResourceManager.GetString(resourceKey);
			}
			catch (MissingManifestResourceException)
			{
			}
			return result;
		}

		private static string GetResourceString(string resourceKey, string defaultString)
		{
			string resourceString = GetResourceString(resourceKey);
			if (!(resourceKey == resourceString) && resourceString != null)
			{
				return resourceString;
			}
			return defaultString;
		}

		internal static string Format(string resourceFormat, object p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(resourceFormat, p1);
		}

		internal static string Format(string resourceFormat, object p1, object p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(resourceFormat, p1, p2);
		}

		internal static string Format(string resourceFormat, object p1, object p2, object p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(resourceFormat, p1, p2, p3);
		}

		internal static string Format(string resourceFormat, params object[] args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + ", " + string.Join(", ", args);
				}
				return string.Format(resourceFormat, args);
			}
			return resourceFormat;
		}

		internal static string Format(IFormatProvider provider, string resourceFormat, object p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(provider, resourceFormat, p1);
		}

		internal static string Format(IFormatProvider provider, string resourceFormat, object p1, object p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(provider, resourceFormat, p1, p2);
		}

		internal static string Format(IFormatProvider provider, string resourceFormat, object p1, object p2, object p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(provider, resourceFormat, p1, p2, p3);
		}

		internal static string Format(IFormatProvider provider, string resourceFormat, params object[] args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + ", " + string.Join(", ", args);
				}
				return string.Format(provider, resourceFormat, args);
			}
			return resourceFormat;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	internal sealed class ObsoleteAttribute : Attribute
	{
		public string Message { get; }

		public bool IsError { get; }

		public string DiagnosticId { get; set; }

		public string UrlFormat { get; set; }

		public ObsoleteAttribute()
		{
		}

		public ObsoleteAttribute(string message)
		{
			Message = message;
		}

		public ObsoleteAttribute(string message, bool error)
		{
			Message = message;
			IsError = error;
		}
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Field, AllowMultiple = true, Inherited = false)]
	internal sealed class DynamicDependencyAttribute : Attribute
	{
		public string MemberSignature { get; }

		public DynamicallyAccessedMemberTypes MemberTypes { get; }

		public Type Type { get; }

		public string TypeName { get; }

		public string AssemblyName { get; }

		public string Condition { get; set; }

		public DynamicDependencyAttribute(string memberSignature)
		{
			MemberSignature = memberSignature;
		}

		public DynamicDependencyAttribute(string memberSignature, Type type)
		{
			MemberSignature = memberSignature;
			Type = type;
		}

		public DynamicDependencyAttribute(string memberSignature, string typeName, string assemblyName)
		{
			MemberSignature = memberSignature;
			TypeName = typeName;
			AssemblyName = assemblyName;
		}

		public DynamicDependencyAttribute(DynamicallyAccessedMemberTypes memberTypes, Type type)
		{
			MemberTypes = memberTypes;
			Type = type;
		}

		public DynamicDependencyAttribute(DynamicallyAccessedMemberTypes memberTypes, string typeName, string assemblyName)
		{
			MemberTypes = memberTypes;
			TypeName = typeName;
			AssemblyName = assemblyName;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, Inherited = false)]
	internal sealed class DynamicallyAccessedMembersAttribute : Attribute
	{
		public DynamicallyAccessedMemberTypes MemberTypes { get; }

		public DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes memberTypes)
		{
			MemberTypes = memberTypes;
		}
	}
	[Flags]
	internal enum DynamicallyAccessedMemberTypes
	{
		None = 0,
		PublicParameterlessConstructor = 1,
		PublicConstructors = 3,
		NonPublicConstructors = 4,
		PublicMethods = 8,
		NonPublicMethods = 0x10,
		PublicFields = 0x20,
		NonPublicFields = 0x40,
		PublicNestedTypes = 0x80,
		NonPublicNestedTypes = 0x100,
		PublicProperties = 0x200,
		NonPublicProperties = 0x400,
		PublicEvents = 0x800,
		NonPublicEvents = 0x1000,
		Interfaces = 0x2000,
		All = -1
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Method, Inherited = false)]
	internal sealed class RequiresUnreferencedCodeAttribute : Attribute
	{
		public string Message { get; }

		public string Url { get; set; }

		public RequiresUnreferencedCodeAttribute(string message)
		{
			Message = message;
		}
	}
	[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
	internal sealed class UnconditionalSuppressMessageAttribute : Attribute
	{
		public string Category { get; }

		public string CheckId { get; }

		public string Scope { get; set; }

		public string Target { get; set; }

		public string MessageId { get; set; }

		public string Justification { get; set; }

		public UnconditionalSuppressMessageAttribute(string category, string checkId)
		{
			Category = category;
			CheckId = checkId;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	internal sealed class StringSyntaxAttribute : Attribute
	{
		public const string CompositeFormat = "CompositeFormat";

		public const string DateOnlyFormat = "DateOnlyFormat";

		public const string DateTimeFormat = "DateTimeFormat";

		public const string EnumFormat = "EnumFormat";

		public const string GuidFormat = "GuidFormat";

		public const string Json = "Json";

		public const string NumericFormat = "NumericFormat";

		public const string Regex = "Regex";

		public const string TimeOnlyFormat = "TimeOnlyFormat";

		public const string TimeSpanFormat = "TimeSpanFormat";

		public const string Uri = "Uri";

		public const string Xml = "Xml";

		public string Syntax { get; }

		public object[] Arguments { get; }

		public StringSyntaxAttribute(string syntax)
		{
			Syntax = syntax;
			Arguments = Array.Empty<object>();
		}

		public StringSyntaxAttribute(string syntax, params object[] arguments)
		{
			Syntax = syntax;
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Method, Inherited = false)]
	internal sealed class RequiresDynamicCodeAttribute : Attribute
	{
		public string Message { get; }

		public string Url { get; set; }

		public RequiresDynamicCodeAttribute(string message)
		{
			Message = message;
		}
	}
	[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.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class MaybeNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class NotNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal sealed class MaybeNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

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

		public NotNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[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.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.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	internal sealed class MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	internal sealed class MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
}
namespace System.Runtime.InteropServices
{
	[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
	internal sealed class LibraryImportAttribute : Attribute
	{
		public string LibraryName { get; }

		public string EntryPoint { get; set; }

		public StringMarshalling StringMarshalling { get; set; }

		public Type StringMarshallingCustomType { get; set; }

		public bool SetLastError { get; set; }

		public LibraryImportAttribute(string libraryName)
		{
			LibraryName = libraryName;
		}
	}
	internal enum StringMarshalling
	{
		Custom,
		Utf8,
		Utf16
	}
}
namespace System.Runtime.Versioning
{
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	internal sealed class RequiresPreviewFeaturesAttribute : Attribute
	{
		public string Message { get; }

		public string Url { get; set; }

		public RequiresPreviewFeaturesAttribute()
		{
		}

		public RequiresPreviewFeaturesAttribute(string message)
		{
			Message = message;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[EditorBrowsable(EditorBrowsableState.Never)]
	internal static class IsExternalInit
	{
	}
}
namespace System.Collections.Generic
{
	internal sealed class ReferenceEqualityComparer : IEqualityComparer<object>, IEqualityComparer
	{
		public static ReferenceEqualityComparer Instance { get; } = new ReferenceEqualityComparer();


		private ReferenceEqualityComparer()
		{
		}

		public new bool Equals(object x, object y)
		{
			return x == y;
		}

		public int GetHashCode(object obj)
		{
			return RuntimeHelpers.GetHashCode(obj);
		}
	}
	internal static class StackExtensions
	{
		public static bool TryPeek<T>(this Stack<T> stack, [MaybeNullWhen(false)] out T result)
		{
			if (stack.Count > 0)
			{
				result = stack.Peek();
				return true;
			}
			result = default(T);
			return false;
		}

		public static bool TryPop<T>(this Stack<T> stack, [MaybeNullWhen(false)] out T result)
		{
			if (stack.Count > 0)
			{
				result = stack.Pop();
				return true;
			}
			result = default(T);
			return false;
		}
	}
}
namespace System.Buffers
{
	internal sealed class ArrayBufferWriter<T> : IBufferWriter<T>
	{
		private const int ArrayMaxLength = 2147483591;

		private const int DefaultInitialBufferSize = 256;

		private T[] _buffer;

		private int _index;

		public ReadOnlyMemory<T> WrittenMemory => _buffer.AsMemory(0, _index);

		public ReadOnlySpan<T> WrittenSpan => _buffer.AsSpan(0, _index);

		public int WrittenCount => _index;

		public int Capacity => _buffer.Length;

		public int FreeCapacity => _buffer.Length - _index;

		public ArrayBufferWriter()
		{
			_buffer = Array.Empty<T>();
			_index = 0;
		}

		public ArrayBufferWriter(int initialCapacity)
		{
			if (initialCapacity <= 0)
			{
				throw new ArgumentException(null, "initialCapacity");
			}
			_buffer = new T[initialCapacity];
			_index = 0;
		}

		public void Clear()
		{
			_buffer.AsSpan(0, _index).Clear();
			_index = 0;
		}

		public void ResetWrittenCount()
		{
			_index = 0;
		}

		public void Advance(int count)
		{
			if (count < 0)
			{
				throw new ArgumentException(null, "count");
			}
			if (_index > _buffer.Length - count)
			{
				ThrowInvalidOperationException_AdvancedTooFar(_buffer.Length);
			}
			_index += count;
		}

		public Memory<T> GetMemory(int sizeHint = 0)
		{
			CheckAndResizeBuffer(sizeHint);
			return _buffer.AsMemory(_index);
		}

		public Span<T> GetSpan(int sizeHint = 0)
		{
			CheckAndResizeBuffer(sizeHint);
			return _buffer.AsSpan(_index);
		}

		private void CheckAndResizeBuffer(int sizeHint)
		{
			if (sizeHint < 0)
			{
				throw new ArgumentException("sizeHint");
			}
			if (sizeHint == 0)
			{
				sizeHint = 1;
			}
			if (sizeHint <= FreeCapacity)
			{
				return;
			}
			int num = _buffer.Length;
			int num2 = Math.Max(sizeHint, num);
			if (num == 0)
			{
				num2 = Math.Max(num2, 256);
			}
			int num3 = num + num2;
			if ((uint)num3 > 2147483647u)
			{
				uint num4 = (uint)(num - FreeCapacity + sizeHint);
				if (num4 > 2147483591)
				{
					ThrowOutOfMemoryException(num4);
				}
				num3 = 2147483591;
			}
			Array.Resize(ref _buffer, num3);
		}

		private static void ThrowInvalidOperationException_AdvancedTooFar(int capacity)
		{
			throw new InvalidOperationException(System.SR.Format(System.SR.BufferWriterAdvancedTooFar, capacity));
		}

		private static void ThrowOutOfMemoryException(uint capacity)
		{
			throw new OutOfMemoryException(System.SR.Format(System.SR.BufferMaximumSizeExceeded, capacity));
		}
	}
}
namespace System.Buffers.Text
{
	internal enum SequenceValidity
	{
		Empty,
		WellFormed,
		Incomplete,
		Invalid
	}
}
namespace System.Text.Json
{
	internal sealed class PooledByteBufferWriter : IBufferWriter<byte>, IDisposable
	{
		private byte[] _rentedBuffer;

		private int _index;

		private const int MinimumBufferSize = 256;

		public const int MaximumBufferSize = 2147483591;

		public ReadOnlyMemory<byte> WrittenMemory => _rentedBuffer.AsMemory(0, _index);

		public int WrittenCount => _index;

		public int Capacity => _rentedBuffer.Length;

		public int FreeCapacity => _rentedBuffer.Length - _index;

		private PooledByteBufferWriter()
		{
		}

		public PooledByteBufferWriter(int initialCapacity)
			: this()
		{
			_rentedBuffer = ArrayPool<byte>.Shared.Rent(initialCapacity);
			_index = 0;
		}

		public void Clear()
		{
			ClearHelper();
		}

		public void ClearAndReturnBuffers()
		{
			ClearHelper();
			byte[] rentedBuffer = _rentedBuffer;
			_rentedBuffer = null;
			ArrayPool<byte>.Shared.Return(rentedBuffer);
		}

		private void ClearHelper()
		{
			_rentedBuffer.AsSpan(0, _index).Clear();
			_index = 0;
		}

		public void Dispose()
		{
			if (_rentedBuffer != null)
			{
				ClearHelper();
				byte[] rentedBuffer = _rentedBuffer;
				_rentedBuffer = null;
				ArrayPool<byte>.Shared.Return(rentedBuffer);
			}
		}

		public void InitializeEmptyInstance(int initialCapacity)
		{
			_rentedBuffer = ArrayPool<byte>.Shared.Rent(initialCapacity);
			_index = 0;
		}

		public static PooledByteBufferWriter CreateEmptyInstanceForCaching()
		{
			return new PooledByteBufferWriter();
		}

		public void Advance(int count)
		{
			_index += count;
		}

		public Memory<byte> GetMemory(int sizeHint = 256)
		{
			CheckAndResizeBuffer(sizeHint);
			return _rentedBuffer.AsMemory(_index);
		}

		public Span<byte> GetSpan(int sizeHint = 256)
		{
			CheckAndResizeBuffer(sizeHint);
			return _rentedBuffer.AsSpan(_index);
		}

		internal Task WriteToStreamAsync(Stream destination, CancellationToken cancellationToken)
		{
			return destination.WriteAsync(_rentedBuffer, 0, _index, cancellationToken);
		}

		internal void WriteToStream(Stream destination)
		{
			destination.Write(_rentedBuffer, 0, _index);
		}

		private void CheckAndResizeBuffer(int sizeHint)
		{
			int num = _rentedBuffer.Length;
			int num2 = num - _index;
			if (_index >= 1073741795)
			{
				sizeHint = Math.Max(sizeHint, 2147483591 - num);
			}
			if (sizeHint <= num2)
			{
				return;
			}
			int num3 = Math.Max(sizeHint, num);
			int num4 = num + num3;
			if ((uint)num4 > 2147483591u)
			{
				num4 = num + sizeHint;
				if ((uint)num4 > 2147483591u)
				{
					ThrowHelper.ThrowOutOfMemoryException_BufferMaximumSizeExceeded((uint)num4);
				}
			}
			byte[] rentedBuffer = _rentedBuffer;
			_rentedBuffer = ArrayPool<byte>.Shared.Rent(num4);
			Span<byte> span = rentedBuffer.AsSpan(0, _index);
			span.CopyTo(_rentedBuffer);
			span.Clear();
			ArrayPool<byte>.Shared.Return(rentedBuffer);
		}
	}
	internal static class ThrowHelper
	{
		public const string ExceptionSourceValueToRethrowAsJsonException = "System.Text.Json.Rethrowable";

		[MethodImpl(MethodImplOptions.NoInlining)]
		[DoesNotReturn]
		public static void ThrowOutOfMemoryException_BufferMaximumSizeExceeded(uint capacity)
		{
			throw new OutOfMemoryException(System.SR.Format(System.SR.BufferMaximumSizeExceeded, capacity));
		}

		[DoesNotReturn]
		public static void ThrowArgumentNullException(string parameterName)
		{
			throw new ArgumentNullException(parameterName);
		}

		[DoesNotReturn]
		public static void ThrowArgumentOutOfRangeException_MaxDepthMustBePositive(string parameterName)
		{
			throw GetArgumentOutOfRangeException(parameterName, System.SR.MaxDepthMustBePositive);
		}

		private static ArgumentOutOfRangeException GetArgumentOutOfRangeException(string parameterName, string message)
		{
			return new ArgumentOutOfRangeException(parameterName, message);
		}

		[DoesNotReturn]
		public static void ThrowArgumentOutOfRangeException_CommentEnumMustBeInRange(string parameterName)
		{
			throw GetArgumentOutOfRangeException(parameterName, System.SR.CommentHandlingMustBeValid);
		}

		[DoesNotReturn]
		public static void ThrowArgumentOutOfRangeException_ArrayIndexNegative(string paramName)
		{
			throw new ArgumentOutOfRangeException(paramName, System.SR.ArrayIndexNegative);
		}

		[DoesNotReturn]
		public static void ThrowArgumentOutOfRangeException_JsonConverterFactory_TypeNotSupported(Type typeToConvert)
		{
			throw new ArgumentOutOfRangeException("typeToConvert", System.SR.Format(System.SR.SerializerConverterFactoryInvalidArgument, typeToConvert.FullName));
		}

		[DoesNotReturn]
		public static void ThrowArgumentException_ArrayTooSmall(string paramName)
		{
			throw new ArgumentException(System.SR.ArrayTooSmall, paramName);
		}

		private static ArgumentException GetArgumentException(string message)
		{
			return new ArgumentException(message);
		}

		[DoesNotReturn]
		public static void ThrowArgumentException(string message)
		{
			throw GetArgumentException(message);
		}

		public static InvalidOperationException GetInvalidOperationException_CallFlushFirst(int _buffered)
		{
			return GetInvalidOperationException(System.SR.Format(System.SR.CallFlushToAvoidDataLoss, _buffered));
		}

		[DoesNotReturn]
		public static void ThrowArgumentException_DestinationTooShort()
		{
			throw GetArgumentException(System.SR.DestinationTooShort);
		}

		[DoesNotReturn]
		public static void ThrowArgumentException_PropertyNameTooLarge(int tokenLength)
		{
			throw GetArgumentException(System.SR.Format(System.SR.PropertyNameTooLarge, tokenLength));
		}

		[DoesNotReturn]
		public static void ThrowArgumentException_ValueTooLarge(long tokenLength)
		{
			throw GetArgumentException(System.SR.Format(System.SR.ValueTooLarge, tokenLength));
		}

		[DoesNotReturn]
		public static void ThrowArgumentException_ValueNotSupported()
		{
			throw GetArgumentException(System.SR.SpecialNumberValuesNotSupported);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_NeedLargerSpan()
		{
			throw GetInvalidOperationException(System.SR.FailedToGetLargerSpan);
		}

		[DoesNotReturn]
		public static void ThrowPropertyNameTooLargeArgumentException(int length)
		{
			throw GetArgumentException(System.SR.Format(System.SR.PropertyNameTooLarge, length));
		}

		[DoesNotReturn]
		public static void ThrowArgumentException(ReadOnlySpan<byte> propertyName, ReadOnlySpan<byte> value)
		{
			if (propertyName.Length > 166666666)
			{
				ThrowArgumentException(System.SR.Format(System.SR.PropertyNameTooLarge, propertyName.Length));
			}
			else
			{
				ThrowArgumentException(System.SR.Format(System.SR.ValueTooLarge, value.Length));
			}
		}

		[DoesNotReturn]
		public static void ThrowArgumentException(ReadOnlySpan<byte> propertyName, ReadOnlySpan<char> value)
		{
			if (propertyName.Length > 166666666)
			{
				ThrowArgumentException(System.SR.Format(System.SR.PropertyNameTooLarge, propertyName.Length));
			}
			else
			{
				ThrowArgumentException(System.SR.Format(System.SR.ValueTooLarge, value.Length));
			}
		}

		[DoesNotReturn]
		public static void ThrowArgumentException(ReadOnlySpan<char> propertyName, ReadOnlySpan<byte> value)
		{
			if (propertyName.Length > 166666666)
			{
				ThrowArgumentException(System.SR.Format(System.SR.PropertyNameTooLarge, propertyName.Length));
			}
			else
			{
				ThrowArgumentException(System.SR.Format(System.SR.ValueTooLarge, value.Length));
			}
		}

		[DoesNotReturn]
		public static void ThrowArgumentException(ReadOnlySpan<char> propertyName, ReadOnlySpan<char> value)
		{
			if (propertyName.Length > 166666666)
			{
				ThrowArgumentException(System.SR.Format(System.SR.PropertyNameTooLarge, propertyName.Length));
			}
			else
			{
				ThrowArgumentException(System.SR.Format(System.SR.ValueTooLarge, value.Length));
			}
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationOrArgumentException(ReadOnlySpan<byte> propertyName, int currentDepth, int maxDepth)
		{
			currentDepth &= 0x7FFFFFFF;
			if (currentDepth >= maxDepth)
			{
				ThrowInvalidOperationException(System.SR.Format(System.SR.DepthTooLarge, currentDepth, maxDepth));
			}
			else
			{
				ThrowArgumentException(System.SR.Format(System.SR.PropertyNameTooLarge, propertyName.Length));
			}
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException(int currentDepth, int maxDepth)
		{
			currentDepth &= 0x7FFFFFFF;
			ThrowInvalidOperationException(System.SR.Format(System.SR.DepthTooLarge, currentDepth, maxDepth));
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException(string message)
		{
			throw GetInvalidOperationException(message);
		}

		private static InvalidOperationException GetInvalidOperationException(string message)
		{
			return new InvalidOperationException(message)
			{
				Source = "System.Text.Json.Rethrowable"
			};
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_DepthNonZeroOrEmptyJson(int currentDepth)
		{
			throw GetInvalidOperationException(currentDepth);
		}

		private static InvalidOperationException GetInvalidOperationException(int currentDepth)
		{
			currentDepth &= 0x7FFFFFFF;
			if (currentDepth != 0)
			{
				return GetInvalidOperationException(System.SR.Format(System.SR.ZeroDepthAtEnd, currentDepth));
			}
			return GetInvalidOperationException(System.SR.EmptyJsonIsInvalid);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationOrArgumentException(ReadOnlySpan<char> propertyName, int currentDepth, int maxDepth)
		{
			currentDepth &= 0x7FFFFFFF;
			if (currentDepth >= maxDepth)
			{
				ThrowInvalidOperationException(System.SR.Format(System.SR.DepthTooLarge, currentDepth, maxDepth));
			}
			else
			{
				ThrowArgumentException(System.SR.Format(System.SR.PropertyNameTooLarge, propertyName.Length));
			}
		}

		public static InvalidOperationException GetInvalidOperationException_ExpectedArray(JsonTokenType tokenType)
		{
			return GetInvalidOperationException("array", tokenType);
		}

		public static InvalidOperationException GetInvalidOperationException_ExpectedObject(JsonTokenType tokenType)
		{
			return GetInvalidOperationException("object", tokenType);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_ExpectedNumber(JsonTokenType tokenType)
		{
			throw GetInvalidOperationException("number", tokenType);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_ExpectedBoolean(JsonTokenType tokenType)
		{
			throw GetInvalidOperationException("boolean", tokenType);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_ExpectedString(JsonTokenType tokenType)
		{
			throw GetInvalidOperationException("string", tokenType);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_ExpectedPropertyName(JsonTokenType tokenType)
		{
			throw GetInvalidOperationException("propertyName", tokenType);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_ExpectedStringComparison(JsonTokenType tokenType)
		{
			throw GetInvalidOperationException(tokenType);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_ExpectedComment(JsonTokenType tokenType)
		{
			throw GetInvalidOperationException("comment", tokenType);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_CannotSkipOnPartial()
		{
			throw GetInvalidOperationException(System.SR.CannotSkip);
		}

		private static InvalidOperationException GetInvalidOperationException(string message, JsonTokenType tokenType)
		{
			return GetInvalidOperationException(System.SR.Format(System.SR.InvalidCast, tokenType, message));
		}

		private static InvalidOperationException GetInvalidOperationException(JsonTokenType tokenType)
		{
			return GetInvalidOperationException(System.SR.Format(System.SR.InvalidComparison, tokenType));
		}

		[DoesNotReturn]
		internal static void ThrowJsonElementWrongTypeException(JsonTokenType expectedType, JsonTokenType actualType)
		{
			throw GetJsonElementWrongTypeException(expectedType.ToValueKind(), actualType.ToValueKind());
		}

		internal static InvalidOperationException GetJsonElementWrongTypeException(JsonValueKind expectedType, JsonValueKind actualType)
		{
			return GetInvalidOperationException(System.SR.Format(System.SR.JsonElementHasWrongType, expectedType, actualType));
		}

		internal static InvalidOperationException GetJsonElementWrongTypeException(string expectedTypeName, JsonValueKind actualType)
		{
			return GetInvalidOperationException(System.SR.Format(System.SR.JsonElementHasWrongType, expectedTypeName, actualType));
		}

		[DoesNotReturn]
		public static void ThrowJsonReaderException(ref Utf8JsonReader json, ExceptionResource resource, byte nextByte = 0, ReadOnlySpan<byte> bytes = default(ReadOnlySpan<byte>))
		{
			throw GetJsonReaderException(ref json, resource, nextByte, bytes);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static JsonException GetJsonReaderException(ref Utf8JsonReader json, ExceptionResource resource, byte nextByte, ReadOnlySpan<byte> bytes)
		{
			string resourceString = GetResourceString(ref json, resource, nextByte, JsonHelpers.Utf8GetString(bytes));
			long lineNumber = json.CurrentState._lineNumber;
			long bytePositionInLine = json.CurrentState._bytePositionInLine;
			resourceString += $" LineNumber: {lineNumber} | BytePositionInLine: {bytePositionInLine}.";
			return new JsonReaderException(resourceString, lineNumber, bytePositionInLine);
		}

		private static bool IsPrintable(byte value)
		{
			if (value >= 32)
			{
				return value < 127;
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static string GetPrintableString(byte value)
		{
			if (!IsPrintable(value))
			{
				return $"0x{value:X2}";
			}
			char c = (char)value;
			return c.ToString();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static string GetResourceString(ref Utf8JsonReader json, ExceptionResource resource, byte nextByte, string characters)
		{
			string printableString = GetPrintableString(nextByte);
			string result = "";
			switch (resource)
			{
			case ExceptionResource.ArrayDepthTooLarge:
				result = System.SR.Format(System.SR.ArrayDepthTooLarge, json.CurrentState.Options.MaxDepth);
				break;
			case ExceptionResource.MismatchedObjectArray:
				result = System.SR.Format(System.SR.MismatchedObjectArray, printableString);
				break;
			case ExceptionResource.TrailingCommaNotAllowedBeforeArrayEnd:
				result = System.SR.TrailingCommaNotAllowedBeforeArrayEnd;
				break;
			case ExceptionResource.TrailingCommaNotAllowedBeforeObjectEnd:
				result = System.SR.TrailingCommaNotAllowedBeforeObjectEnd;
				break;
			case ExceptionResource.EndOfStringNotFound:
				result = System.SR.EndOfStringNotFound;
				break;
			case ExceptionResource.RequiredDigitNotFoundAfterSign:
				result = System.SR.Format(System.SR.RequiredDigitNotFoundAfterSign, printableString);
				break;
			case ExceptionResource.RequiredDigitNotFoundAfterDecimal:
				result = System.SR.Format(System.SR.RequiredDigitNotFoundAfterDecimal, printableString);
				break;
			case ExceptionResource.RequiredDigitNotFoundEndOfData:
				result = System.SR.RequiredDigitNotFoundEndOfData;
				break;
			case ExceptionResource.ExpectedEndAfterSingleJson:
				result = System.SR.Format(System.SR.ExpectedEndAfterSingleJson, printableString);
				break;
			case ExceptionResource.ExpectedEndOfDigitNotFound:
				result = System.SR.Format(System.SR.ExpectedEndOfDigitNotFound, printableString);
				break;
			case ExceptionResource.ExpectedNextDigitEValueNotFound:
				result = System.SR.Format(System.SR.ExpectedNextDigitEValueNotFound, printableString);
				break;
			case ExceptionResource.ExpectedSeparatorAfterPropertyNameNotFound:
				result = System.SR.Format(System.SR.ExpectedSeparatorAfterPropertyNameNotFound, printableString);
				break;
			case ExceptionResource.ExpectedStartOfPropertyNotFound:
				result = System.SR.Format(System.SR.ExpectedStartOfPropertyNotFound, printableString);
				break;
			case ExceptionResource.ExpectedStartOfPropertyOrValueNotFound:
				result = System.SR.ExpectedStartOfPropertyOrValueNotFound;
				break;
			case ExceptionResource.ExpectedStartOfPropertyOrValueAfterComment:
				result = System.SR.Format(System.SR.ExpectedStartOfPropertyOrValueAfterComment, printableString);
				break;
			case ExceptionResource.ExpectedStartOfValueNotFound:
				result = System.SR.Format(System.SR.ExpectedStartOfValueNotFound, printableString);
				break;
			case ExceptionResource.ExpectedValueAfterPropertyNameNotFound:
				result = System.SR.ExpectedValueAfterPropertyNameNotFound;
				break;
			case ExceptionResource.FoundInvalidCharacter:
				result = System.SR.Format(System.SR.FoundInvalidCharacter, printableString);
				break;
			case ExceptionResource.InvalidEndOfJsonNonPrimitive:
				result = System.SR.Format(System.SR.InvalidEndOfJsonNonPrimitive, json.TokenType);
				break;
			case ExceptionResource.ObjectDepthTooLarge:
				result = System.SR.Format(System.SR.ObjectDepthTooLarge, json.CurrentState.Options.MaxDepth);
				break;
			case ExceptionResource.ExpectedFalse:
				result = System.SR.Format(System.SR.ExpectedFalse, characters);
				break;
			case ExceptionResource.ExpectedNull:
				result = System.SR.Format(System.SR.ExpectedNull, characters);
				break;
			case ExceptionResource.ExpectedTrue:
				result = System.SR.Format(System.SR.ExpectedTrue, characters);
				break;
			case ExceptionResource.InvalidCharacterWithinString:
				result = System.SR.Format(System.SR.InvalidCharacterWithinString, printableString);
				break;
			case ExceptionResource.InvalidCharacterAfterEscapeWithinString:
				result = System.SR.Format(System.SR.InvalidCharacterAfterEscapeWithinString, printableString);
				break;
			case ExceptionResource.InvalidHexCharacterWithinString:
				result = System.SR.Format(System.SR.InvalidHexCharacterWithinString, printableString);
				break;
			case ExceptionResource.EndOfCommentNotFound:
				result = System.SR.EndOfCommentNotFound;
				break;
			case ExceptionResource.ZeroDepthAtEnd:
				result = System.SR.Format(System.SR.ZeroDepthAtEnd);
				break;
			case ExceptionResource.ExpectedJsonTokens:
				result = System.SR.ExpectedJsonTokens;
				break;
			case ExceptionResource.NotEnoughData:
				result = System.SR.NotEnoughData;
				break;
			case ExceptionResource.ExpectedOneCompleteToken:
				result = System.SR.ExpectedOneCompleteToken;
				break;
			case ExceptionResource.InvalidCharacterAtStartOfComment:
				result = System.SR.Format(System.SR.InvalidCharacterAtStartOfComment, printableString);
				break;
			case ExceptionResource.UnexpectedEndOfDataWhileReadingComment:
				result = System.SR.Format(System.SR.UnexpectedEndOfDataWhileReadingComment);
				break;
			case ExceptionResource.UnexpectedEndOfLineSeparator:
				result = System.SR.Format(System.SR.UnexpectedEndOfLineSeparator);
				break;
			case ExceptionResource.InvalidLeadingZeroInNumber:
				result = System.SR.Format(System.SR.InvalidLeadingZeroInNumber, printableString);
				break;
			}
			return result;
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException(ExceptionResource resource, int currentDepth, int maxDepth, byte token, JsonTokenType tokenType)
		{
			throw GetInvalidOperationException(resource, currentDepth, maxDepth, token, tokenType);
		}

		[DoesNotReturn]
		public static void ThrowArgumentException_InvalidCommentValue()
		{
			throw new ArgumentException(System.SR.CannotWriteCommentWithEmbeddedDelimiter);
		}

		[DoesNotReturn]
		public static void ThrowArgumentException_InvalidUTF8(ReadOnlySpan<byte> value)
		{
			StringBuilder stringBuilder = new StringBuilder();
			int num = Math.Min(value.Length, 10);
			for (int i = 0; i < num; i++)
			{
				byte b = value[i];
				if (IsPrintable(b))
				{
					stringBuilder.Append((char)b);
				}
				else
				{
					stringBuilder.Append($"0x{b:X2}");
				}
			}
			if (num < value.Length)
			{
				stringBuilder.Append("...");
			}
			throw new ArgumentException(System.SR.Format(System.SR.CannotEncodeInvalidUTF8, stringBuilder));
		}

		[DoesNotReturn]
		public static void ThrowArgumentException_InvalidUTF16(int charAsInt)
		{
			throw new ArgumentException(System.SR.Format(System.SR.CannotEncodeInvalidUTF16, $"0x{charAsInt:X2}"));
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_ReadInvalidUTF16(int charAsInt)
		{
			throw GetInvalidOperationException(System.SR.Format(System.SR.CannotReadInvalidUTF16, $"0x{charAsInt:X2}"));
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_ReadIncompleteUTF16()
		{
			throw GetInvalidOperationException(System.SR.CannotReadIncompleteUTF16);
		}

		public static InvalidOperationException GetInvalidOperationException_ReadInvalidUTF8(DecoderFallbackException innerException = null)
		{
			return GetInvalidOperationException(System.SR.CannotTranscodeInvalidUtf8, innerException);
		}

		public static ArgumentException GetArgumentException_ReadInvalidUTF16(EncoderFallbackException innerException)
		{
			return new ArgumentException(System.SR.CannotTranscodeInvalidUtf16, innerException);
		}

		public static InvalidOperationException GetInvalidOperationException(string message, Exception innerException)
		{
			InvalidOperationException ex = new InvalidOperationException(message, innerException);
			ex.Source = "System.Text.Json.Rethrowable";
			return ex;
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static InvalidOperationException GetInvalidOperationException(ExceptionResource resource, int currentDepth, int maxDepth, byte token, JsonTokenType tokenType)
		{
			string resourceString = GetResourceString(resource, currentDepth, maxDepth, token, tokenType);
			InvalidOperationException invalidOperationException = GetInvalidOperationException(resourceString);
			invalidOperationException.Source = "System.Text.Json.Rethrowable";
			return invalidOperationException;
		}

		[DoesNotReturn]
		public static void ThrowOutOfMemoryException(uint capacity)
		{
			throw new OutOfMemoryException(System.SR.Format(System.SR.BufferMaximumSizeExceeded, capacity));
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static string GetResourceString(ExceptionResource resource, int currentDepth, int maxDepth, byte token, JsonTokenType tokenType)
		{
			string result = "";
			switch (resource)
			{
			case ExceptionResource.MismatchedObjectArray:
				result = ((tokenType == JsonTokenType.PropertyName) ? System.SR.Format(System.SR.CannotWriteEndAfterProperty, (char)token) : System.SR.Format(System.SR.MismatchedObjectArray, (char)token));
				break;
			case ExceptionResource.DepthTooLarge:
				result = System.SR.Format(System.SR.DepthTooLarge, currentDepth & 0x7FFFFFFF, maxDepth);
				break;
			case ExceptionResource.CannotStartObjectArrayWithoutProperty:
				result = System.SR.Format(System.SR.CannotStartObjectArrayWithoutProperty, tokenType);
				break;
			case ExceptionResource.CannotStartObjectArrayAfterPrimitiveOrClose:
				result = System.SR.Format(System.SR.CannotStartObjectArrayAfterPrimitiveOrClose, tokenType);
				break;
			case ExceptionResource.CannotWriteValueWithinObject:
				result = System.SR.Format(System.SR.CannotWriteValueWithinObject, tokenType);
				break;
			case ExceptionResource.CannotWritePropertyWithinArray:
				result = ((tokenType == JsonTokenType.PropertyName) ? System.SR.Format(System.SR.CannotWritePropertyAfterProperty) : System.SR.Format(System.SR.CannotWritePropertyWithinArray, tokenType));
				break;
			case ExceptionResource.CannotWriteValueAfterPrimitiveOrClose:
				result = System.SR.Format(System.SR.CannotWriteValueAfterPrimitiveOrClose, tokenType);
				break;
			}
			return result;
		}

		[DoesNotReturn]
		public static void ThrowFormatException()
		{
			throw new FormatException
			{
				Source = "System.Text.Json.Rethrowable"
			};
		}

		public static void ThrowFormatException(NumericType numericType)
		{
			string message = "";
			switch (numericType)
			{
			case NumericType.Byte:
				message = System.SR.FormatByte;
				break;
			case NumericType.SByte:
				message = System.SR.FormatSByte;
				break;
			case NumericType.Int16:
				message = System.SR.FormatInt16;
				break;
			case NumericType.Int32:
				message = System.SR.FormatInt32;
				break;
			case NumericType.Int64:
				message = System.SR.FormatInt64;
				break;
			case NumericType.Int128:
				message = System.SR.FormatInt128;
				break;
			case NumericType.UInt16:
				message = System.SR.FormatUInt16;
				break;
			case NumericType.UInt32:
				message = System.SR.FormatUInt32;
				break;
			case NumericType.UInt64:
				message = System.SR.FormatUInt64;
				break;
			case NumericType.UInt128:
				message = System.SR.FormatUInt128;
				break;
			case NumericType.Half:
				message = System.SR.FormatHalf;
				break;
			case NumericType.Single:
				message = System.SR.FormatSingle;
				break;
			case NumericType.Double:
				message = System.SR.FormatDouble;
				break;
			case NumericType.Decimal:
				message = System.SR.FormatDecimal;
				break;
			}
			throw new FormatException(message)
			{
				Source = "System.Text.Json.Rethrowable"
			};
		}

		[DoesNotReturn]
		public static void ThrowFormatException(DataType dataType)
		{
			string message = "";
			switch (dataType)
			{
			case DataType.Boolean:
			case DataType.DateOnly:
			case DataType.DateTime:
			case DataType.DateTimeOffset:
			case DataType.TimeOnly:
			case DataType.TimeSpan:
			case DataType.Guid:
			case DataType.Version:
				message = System.SR.Format(System.SR.UnsupportedFormat, dataType);
				break;
			case DataType.Base64String:
				message = System.SR.CannotDecodeInvalidBase64;
				break;
			}
			throw new FormatException(message)
			{
				Source = "System.Text.Json.Rethrowable"
			};
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_ExpectedChar(JsonTokenType tokenType)
		{
			throw GetInvalidOperationException("char", tokenType);
		}

		[DoesNotReturn]
		public static void ThrowObjectDisposedException_Utf8JsonWriter()
		{
			throw new ObjectDisposedException("Utf8JsonWriter");
		}

		[DoesNotReturn]
		public static void ThrowObjectDisposedException_JsonDocument()
		{
			throw new ObjectDisposedException("JsonDocument");
		}

		[DoesNotReturn]
		public static void ThrowArgumentException_NodeValueNotAllowed(string paramName)
		{
			throw new ArgumentException(System.SR.NodeValueNotAllowed, paramName);
		}

		[DoesNotReturn]
		public static void ThrowArgumentException_DuplicateKey(string paramName, string propertyName)
		{
			throw new ArgumentException(System.SR.Format(System.SR.NodeDuplicateKey, propertyName), paramName);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_NodeAlreadyHasParent()
		{
			throw new InvalidOperationException(System.SR.NodeAlreadyHasParent);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_NodeCycleDetected()
		{
			throw new InvalidOperationException(System.SR.NodeCycleDetected);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_NodeElementCannotBeObjectOrArray()
		{
			throw new InvalidOperationException(System.SR.NodeElementCannotBeObjectOrArray);
		}

		[DoesNotReturn]
		public static void ThrowNotSupportedException_CollectionIsReadOnly()
		{
			throw GetNotSupportedException_CollectionIsReadOnly();
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_NodeWrongType(string typeName)
		{
			throw new InvalidOperationException(System.SR.Format(System.SR.NodeWrongType, typeName));
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_NodeParentWrongType(string typeName)
		{
			throw new InvalidOperationException(System.SR.Format(System.SR.NodeParentWrongType, typeName));
		}

		public static NotSupportedException GetNotSupportedException_CollectionIsReadOnly()
		{
			return new NotSupportedException(System.SR.CollectionIsReadOnly);
		}

		[DoesNotReturn]
		public static void ThrowArgumentException_DeserializeWrongType(Type type, object value)
		{
			throw new ArgumentException(System.SR.Format(System.SR.DeserializeWrongType, type, value.GetType()));
		}

		[DoesNotReturn]
		public static void ThrowArgumentException_SerializerDoesNotSupportComments(string paramName)
		{
			throw new ArgumentException(System.SR.JsonSerializerDoesNotSupportComments, paramName);
		}

		[DoesNotReturn]
		public static void ThrowNotSupportedException_SerializationNotSupported(Type propertyType)
		{
			throw new NotSupportedException(System.SR.Format(System.SR.SerializationNotSupportedType, propertyType));
		}

		[DoesNotReturn]
		public static void ThrowNotSupportedException_TypeRequiresAsyncSerialization(Type propertyType)
		{
			throw new NotSupportedException(System.SR.Format(System.SR.TypeRequiresAsyncSerialization, propertyType));
		}

		[DoesNotReturn]
		public static void ThrowNotSupportedException_DictionaryKeyTypeNotSupported(Type keyType, JsonConverter converter)
		{
			throw new NotSupportedException(System.SR.Format(System.SR.DictionaryKeyTypeNotSupported, keyType, converter.GetType()));
		}

		[DoesNotReturn]
		public static void ThrowJsonException_DeserializeUnableToConvertValue(Type propertyType)
		{
			throw new JsonException(System.SR.Format(System.SR.DeserializeUnableToConvertValue, propertyType))
			{
				AppendPathInformation = true
			};
		}

		[DoesNotReturn]
		public static void ThrowInvalidCastException_DeserializeUnableToAssignValue(Type typeOfValue, Type declaredType)
		{
			throw new InvalidCastException(System.SR.Format(System.SR.DeserializeUnableToAssignValue, typeOfValue, declaredType));
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_DeserializeUnableToAssignNull(Type declaredType)
		{
			throw new InvalidOperationException(System.SR.Format(System.SR.DeserializeUnableToAssignNull, declaredType));
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_ObjectCreationHandlingPopulateNotSupportedByConverter(JsonPropertyInfo propertyInfo)
		{
			throw new InvalidOperationException(System.SR.Format(System.SR.ObjectCreationHandlingPopulateNotSupportedByConverter, propertyInfo.Name, propertyInfo.DeclaringType));
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_ObjectCreationHandlingPropertyMustHaveAGetter(JsonPropertyInfo propertyInfo)
		{
			throw new InvalidOperationException(System.SR.Format(System.SR.ObjectCreationHandlingPropertyMustHaveAGetter, propertyInfo.Name, propertyInfo.DeclaringType));
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_ObjectCreationHandlingPropertyValueTypeMustHaveASetter(JsonPropertyInfo propertyInfo)
		{
			throw new InvalidOperationException(System.SR.Format(System.SR.ObjectCreationHandlingPropertyValueTypeMustHaveASetter, propertyInfo.Name, propertyInfo.DeclaringType));
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_ObjectCreationHandlingPropertyCannotAllowPolymorphicDeserialization(JsonPropertyInfo propertyInfo)
		{
			throw new InvalidOperationException(System.SR.Format(System.SR.ObjectCreationHandlingPropertyCannotAllowPolymorphicDeserialization, propertyInfo.Name, propertyInfo.DeclaringType));
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_ObjectCreationHandlingPropertyCannotAllowReadOnlyMember(JsonPropertyInfo propertyInfo)
		{
			throw new InvalidOperationException(System.SR.Format(System.SR.ObjectCreationHandlingPropertyCannotAllowReadOnlyMember, propertyInfo.Name, propertyInfo.DeclaringType));
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_ObjectCreationHandlingPropertyCannotAllowReferenceHandling()
		{
			throw new InvalidOperationException(System.SR.ObjectCreationHandlingPropertyCannotAllowReferenceHandling);
		}

		[DoesNotReturn]
		public static void ThrowNotSupportedException_ObjectCreationHandlingPropertyDoesNotSupportParameterizedConstructors()
		{
			throw new NotSupportedException(System.SR.ObjectCreationHandlingPropertyDoesNotSupportParameterizedConstructors);
		}

		[DoesNotReturn]
		public static void ThrowJsonException_SerializationConverterRead(JsonConverter converter)
		{
			throw new JsonException(System.SR.Format(System.SR.SerializationConverterRead, converter))
			{
				AppendPathInformation = true
			};
		}

		[DoesNotReturn]
		public static void ThrowJsonException_SerializationConverterWrite(JsonConverter converter)
		{
			throw new JsonException(System.SR.Format(System.SR.SerializationConverterWrite, converter))
			{
				AppendPathInformation = true
			};
		}

		[DoesNotReturn]
		public static void ThrowJsonException_SerializerCycleDetected(int maxDepth)
		{
			throw new JsonException(System.SR.Format(System.SR.SerializerCycleDetected, maxDepth))
			{
				AppendPathInformation = true
			};
		}

		[DoesNotReturn]
		public static void ThrowJsonException(string message = null)
		{
			throw new JsonException(message)
			{
				AppendPathInformation = true
			};
		}

		[DoesNotReturn]
		public static void ThrowArgumentException_CannotSerializeInvalidType(string paramName, Type typeToConvert, Type declaringType, string propertyName)
		{
			if (declaringType == null)
			{
				throw new ArgumentException(System.SR.Format(System.SR.CannotSerializeInvalidType, typeToConvert), paramName);
			}
			throw new ArgumentException(System.SR.Format(System.SR.CannotSerializeInvalidMember, typeToConvert, propertyName, declaringType), paramName);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_CannotSerializeInvalidType(Type typeToConvert, Type declaringType, MemberInfo memberInfo)
		{
			if (declaringType == null)
			{
				throw new InvalidOperationException(System.SR.Format(System.SR.CannotSerializeInvalidType, typeToConvert));
			}
			throw new InvalidOperationException(System.SR.Format(System.SR.CannotSerializeInvalidMember, typeToConvert, memberInfo.Name, declaringType));
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_SerializationConverterNotCompatible(Type converterType, Type type)
		{
			throw new InvalidOperationException(System.SR.Format(System.SR.SerializationConverterNotCompatible, converterType, type));
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_ResolverTypeNotCompatible(Type requestedType, Type actualType)
		{
			throw new InvalidOperationException(System.SR.Format(System.SR.ResolverTypeNotCompatible, actualType, requestedType));
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_ResolverTypeInfoOptionsNotCompatible()
		{
			throw new InvalidOperationException(System.SR.ResolverTypeInfoOptionsNotCompatible);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_JsonSerializerOptionsNoTypeInfoResolverSpecified()
		{
			throw new InvalidOperationException(System.SR.JsonSerializerOptionsNoTypeInfoResolverSpecified);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_JsonSerializerIsReflectionDisabled()
		{
			throw new InvalidOperationException(System.SR.JsonSerializerIsReflectionDisabled);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_SerializationConverterOnAttributeInvalid(Type classType, MemberInfo memberInfo)
		{
			string text = classType.ToString();
			if (memberInfo != null)
			{
				text = text + "." + memberInfo.Name;
			}
			throw new InvalidOperationException(System.SR.Format(System.SR.SerializationConverterOnAttributeInvalid, text));
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_SerializationConverterOnAttributeNotCompatible(Type classTypeAttributeIsOn, MemberInfo memberInfo, Type typeToConvert)
		{
			string text = classTypeAttributeIsOn.ToString();
			if (memberInfo != null)
			{
				text = text + "." + memberInfo.Name;
			}
			throw new InvalidOperationException(System.SR.Format(System.SR.SerializationConverterOnAttributeNotCompatible, text, typeToConvert));
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_SerializerOptionsReadOnly(JsonSerializerContext context)
		{
			string message = ((context == null) ? System.SR.SerializerOptionsReadOnly : System.SR.SerializerContextOptionsReadOnly);
			throw new InvalidOperationException(message);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_DefaultTypeInfoResolverImmutable()
		{
			throw new InvalidOperationException(System.SR.DefaultTypeInfoResolverImmutable);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_TypeInfoResolverChainImmutable()
		{
			throw new InvalidOperationException(System.SR.TypeInfoResolverChainImmutable);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_TypeInfoImmutable()
		{
			throw new InvalidOperationException(System.SR.TypeInfoImmutable);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_InvalidChainedResolver()
		{
			throw new InvalidOperationException(System.SR.SerializerOptions_InvalidChainedResolver);
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_SerializerPropertyNameConflict(Type type, string propertyName)
		{
			throw new InvalidOperationException(System.SR.Format(System.SR.SerializerPropertyNameConflict, type, propertyName));
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_SerializerPropertyNameNull(JsonPropertyInfo jsonPropertyInfo)
		{
			throw new InvalidOperationException(System.SR.Format(System.SR.SerializerPropertyNameNull, jsonPropertyInfo.DeclaringType, jsonPropertyInfo.MemberName));
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_JsonPropertyRequiredAndNotDeserializable(JsonPropertyInfo jsonPropertyInfo)
		{
			throw new InvalidOperationException(System.SR.Format(System.SR.JsonPropertyRequiredAndNotDeserializable, jsonPropertyInfo.Name, jsonPropertyInfo.DeclaringType));
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_JsonPropertyRequiredAndExtensionData(JsonPropertyInfo jsonPropertyInfo)
		{
			throw new InvalidOperationException(System.SR.Format(System.SR.JsonPropertyRequiredAndExtensionData, jsonPropertyInfo.Name, jsonPropertyInfo.DeclaringType));
		}

		[DoesNotReturn]
		public static void ThrowJsonException_JsonRequiredPropertyMissing(JsonTypeInfo parent, BitArray requiredPropertiesSet)
		{
			StringBuilder stringBuilder = new StringBuilder();
			bool flag = true;
			foreach (KeyValuePair<string, JsonPropertyInfo> item in parent.PropertyCache.List)
			{
				JsonPropertyInfo value = item.Value;
				if (value.IsRequired && !requiredPropertiesSet[value.RequiredPropertyIndex])
				{
					if (!flag)
					{
						stringBuilder.Append(CultureInfo.CurrentUICulture.TextInfo.ListSeparator);
						stringBuilder.Append(' ');
					}
					stringBuilder.Append(value.Name);
					flag = false;
					if (stringBuilder.Length >= 50)
					{
						break;
					}
				}
			}
			throw new JsonException(System.SR.Format(System.SR.JsonRequiredPropertiesMissing, parent.Type, stringBuilder.ToString()));
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_NamingPolicyReturnNull(JsonNamingPolicy namingPolicy)
		{
			throw new InvalidOperationException(System.SR.Format(System.SR.NamingPolicyReturnNull, namingPolicy));
		}

		[DoesNotReturn]
		public static void ThrowInvalidOperationException_SerializerConverterFactoryReturnsNull(Type converterType)
		{
			throw new InvalidOperationException(System.SR.Format(System.S

Mods/RealRadio/System.Threading.Channels.dll

Decompiled a day ago
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Sources;
using FxResources.System.Threading.Channels;
using Internal;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: AssemblyDefaultAlias("System.Threading.Channels")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata("IsTrimmable", "True")]
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyDescription("Provides types for passing data between producers and consumers.\r\n\r\nCommonly Used Types:\r\nSystem.Threading.Channel\r\nSystem.Threading.Channel<T>")]
[assembly: AssemblyFileVersion("8.0.23.53103")]
[assembly: AssemblyInformationalVersion("8.0.0+5535e31a712343a63f5d7d796cd874e563e5ac14")]
[assembly: AssemblyProduct("Microsoft® .NET")]
[assembly: AssemblyTitle("System.Threading.Channels")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/dotnet/runtime")]
[assembly: AssemblyVersion("8.0.0.0")]
[module: RefSafetyRules(11)]
[module: System.Runtime.CompilerServices.NullablePublicOnly(false)]
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 NullablePublicOnlyAttribute : Attribute
	{
		public readonly bool IncludesInternals;

		public NullablePublicOnlyAttribute(bool P_0)
		{
			IncludesInternals = 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 FxResources.System.Threading.Channels
{
	internal static class SR
	{
	}
}
namespace Internal
{
	internal static class PaddingHelpers
	{
		internal const int CACHE_LINE_SIZE = 128;
	}
	[StructLayout(LayoutKind.Explicit, Size = 124)]
	internal struct PaddingFor32
	{
	}
}
namespace System
{
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	internal readonly struct VoidResult
	{
	}
	internal static class Obsoletions
	{
		internal const string SharedUrlFormat = "https://aka.ms/dotnet-warnings/{0}";

		internal const string SystemTextEncodingUTF7Message = "The UTF-7 encoding is insecure and should not be used. Consider using UTF-8 instead.";

		internal const string SystemTextEncodingUTF7DiagId = "SYSLIB0001";

		internal const string PrincipalPermissionAttributeMessage = "PrincipalPermissionAttribute is not honored by the runtime and must not be used.";

		internal const string PrincipalPermissionAttributeDiagId = "SYSLIB0002";

		internal const string CodeAccessSecurityMessage = "Code Access Security is not supported or honored by the runtime.";

		internal const string CodeAccessSecurityDiagId = "SYSLIB0003";

		internal const string ConstrainedExecutionRegionMessage = "The Constrained Execution Region (CER) feature is not supported.";

		internal const string ConstrainedExecutionRegionDiagId = "SYSLIB0004";

		internal const string GlobalAssemblyCacheMessage = "The Global Assembly Cache is not supported.";

		internal const string GlobalAssemblyCacheDiagId = "SYSLIB0005";

		internal const string ThreadAbortMessage = "Thread.Abort is not supported and throws PlatformNotSupportedException.";

		internal const string ThreadResetAbortMessage = "Thread.ResetAbort is not supported and throws PlatformNotSupportedException.";

		internal const string ThreadAbortDiagId = "SYSLIB0006";

		internal const string DefaultCryptoAlgorithmsMessage = "The default implementation of this cryptography algorithm is not supported.";

		internal const string DefaultCryptoAlgorithmsDiagId = "SYSLIB0007";

		internal const string CreatePdbGeneratorMessage = "The CreatePdbGenerator API is not supported and throws PlatformNotSupportedException.";

		internal const string CreatePdbGeneratorDiagId = "SYSLIB0008";

		internal const string AuthenticationManagerMessage = "The AuthenticationManager Authenticate and PreAuthenticate methods are not supported and throw PlatformNotSupportedException.";

		internal const string AuthenticationManagerDiagId = "SYSLIB0009";

		internal const string RemotingApisMessage = "This Remoting API is not supported and throws PlatformNotSupportedException.";

		internal const string RemotingApisDiagId = "SYSLIB0010";

		internal const string BinaryFormatterMessage = "BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.";

		internal const string BinaryFormatterDiagId = "SYSLIB0011";

		internal const string CodeBaseMessage = "Assembly.CodeBase and Assembly.EscapedCodeBase are only included for .NET Framework compatibility. Use Assembly.Location instead.";

		internal const string CodeBaseDiagId = "SYSLIB0012";

		internal const string EscapeUriStringMessage = "Uri.EscapeUriString can corrupt the Uri string in some cases. Consider using Uri.EscapeDataString for query string components instead.";

		internal const string EscapeUriStringDiagId = "SYSLIB0013";

		internal const string WebRequestMessage = "WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.";

		internal const string WebRequestDiagId = "SYSLIB0014";

		internal const string DisablePrivateReflectionAttributeMessage = "DisablePrivateReflectionAttribute has no effect in .NET 6.0+.";

		internal const string DisablePrivateReflectionAttributeDiagId = "SYSLIB0015";

		internal const string GetContextInfoMessage = "Use the Graphics.GetContextInfo overloads that accept arguments for better performance and fewer allocations.";

		internal const string GetContextInfoDiagId = "SYSLIB0016";

		internal const string StrongNameKeyPairMessage = "Strong name signing is not supported and throws PlatformNotSupportedException.";

		internal const string StrongNameKeyPairDiagId = "SYSLIB0017";

		internal const string ReflectionOnlyLoadingMessage = "ReflectionOnly loading is not supported and throws PlatformNotSupportedException.";

		internal const string ReflectionOnlyLoadingDiagId = "SYSLIB0018";

		internal const string RuntimeEnvironmentMessage = "RuntimeEnvironment members SystemConfigurationFile, GetRuntimeInterfaceAsIntPtr, and GetRuntimeInterfaceAsObject are not supported and throw PlatformNotSupportedException.";

		internal const string RuntimeEnvironmentDiagId = "SYSLIB0019";

		internal const string JsonSerializerOptionsIgnoreNullValuesMessage = "JsonSerializerOptions.IgnoreNullValues is obsolete. To ignore null values when serializing, set DefaultIgnoreCondition to JsonIgnoreCondition.WhenWritingNull.";

		internal const string JsonSerializerOptionsIgnoreNullValuesDiagId = "SYSLIB0020";

		internal const string DerivedCryptographicTypesMessage = "Derived cryptographic types are obsolete. Use the Create method on the base type instead.";

		internal const string DerivedCryptographicTypesDiagId = "SYSLIB0021";

		internal const string RijndaelMessage = "The Rijndael and RijndaelManaged types are obsolete. Use Aes instead.";

		internal const string RijndaelDiagId = "SYSLIB0022";

		internal const string RNGCryptoServiceProviderMessage = "RNGCryptoServiceProvider is obsolete. To generate a random number, use one of the RandomNumberGenerator static methods instead.";

		internal const string RNGCryptoServiceProviderDiagId = "SYSLIB0023";

		internal const string AppDomainCreateUnloadMessage = "Creating and unloading AppDomains is not supported and throws an exception.";

		internal const string AppDomainCreateUnloadDiagId = "SYSLIB0024";

		internal const string SuppressIldasmAttributeMessage = "SuppressIldasmAttribute has no effect in .NET 6.0+.";

		internal const string SuppressIldasmAttributeDiagId = "SYSLIB0025";

		internal const string X509CertificateImmutableMessage = "X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate.";

		internal const string X509CertificateImmutableDiagId = "SYSLIB0026";

		internal const string PublicKeyPropertyMessage = "PublicKey.Key is obsolete. Use the appropriate method to get the public key, such as GetRSAPublicKey.";

		internal const string PublicKeyPropertyDiagId = "SYSLIB0027";

		internal const string X509CertificatePrivateKeyMessage = "X509Certificate2.PrivateKey is obsolete. Use the appropriate method to get the private key, such as GetRSAPrivateKey, or use the CopyWithPrivateKey method to create a new instance with a private key.";

		internal const string X509CertificatePrivateKeyDiagId = "SYSLIB0028";

		internal const string ProduceLegacyHmacValuesMessage = "ProduceLegacyHmacValues is obsolete. Producing legacy HMAC values is not supported.";

		internal const string ProduceLegacyHmacValuesDiagId = "SYSLIB0029";

		internal const string UseManagedSha1Message = "HMACSHA1 always uses the algorithm implementation provided by the platform. Use a constructor without the useManagedSha1 parameter.";

		internal const string UseManagedSha1DiagId = "SYSLIB0030";

		internal const string CryptoConfigEncodeOIDMessage = "EncodeOID is obsolete. Use the ASN.1 functionality provided in System.Formats.Asn1.";

		internal const string CryptoConfigEncodeOIDDiagId = "SYSLIB0031";

		internal const string CorruptedStateRecoveryMessage = "Recovery from corrupted process state exceptions is not supported; HandleProcessCorruptedStateExceptionsAttribute is ignored.";

		internal const string CorruptedStateRecoveryDiagId = "SYSLIB0032";

		internal const string Rfc2898CryptDeriveKeyMessage = "Rfc2898DeriveBytes.CryptDeriveKey is obsolete and is not supported. Use PasswordDeriveBytes.CryptDeriveKey instead.";

		internal const string Rfc2898CryptDeriveKeyDiagId = "SYSLIB0033";

		internal const string CmsSignerCspParamsCtorMessage = "CmsSigner(CspParameters) is obsolete and is not supported. Use an alternative constructor instead.";

		internal const string CmsSignerCspParamsCtorDiagId = "SYSLIB0034";

		internal const string SignerInfoCounterSigMessage = "ComputeCounterSignature without specifying a CmsSigner is obsolete and is not supported. Use the overload that accepts a CmsSigner.";

		internal const string SignerInfoCounterSigDiagId = "SYSLIB0035";

		internal const string RegexCompileToAssemblyMessage = "Regex.CompileToAssembly is obsolete and not supported. Use the GeneratedRegexAttribute with the regular expression source generator instead.";

		internal const string RegexCompileToAssemblyDiagId = "SYSLIB0036";

		internal const string AssemblyNameMembersMessage = "AssemblyName members HashAlgorithm, ProcessorArchitecture, and VersionCompatibility are obsolete and not supported.";

		internal const string AssemblyNameMembersDiagId = "SYSLIB0037";

		internal const string SystemDataSerializationFormatBinaryMessage = "SerializationFormat.Binary is obsolete and should not be used. See https://aka.ms/serializationformat-binary-obsolete for more information.";

		internal const string SystemDataSerializationFormatBinaryDiagId = "SYSLIB0038";

		internal const string TlsVersion10and11Message = "TLS versions 1.0 and 1.1 have known vulnerabilities and are not recommended. Use a newer TLS version instead, or use SslProtocols.None to defer to OS defaults.";

		internal const string TlsVersion10and11DiagId = "SYSLIB0039";

		internal const string EncryptionPolicyMessage = "EncryptionPolicy.NoEncryption and AllowEncryption significantly reduce security and should not be used in production code.";

		internal const string EncryptionPolicyDiagId = "SYSLIB0040";

		internal const string Rfc2898OutdatedCtorMessage = "The default hash algorithm and iteration counts in Rfc2898DeriveBytes constructors are outdated and insecure. Use a constructor that accepts the hash algorithm and the number of iterations.";

		internal const string Rfc2898OutdatedCtorDiagId = "SYSLIB0041";

		internal const string EccXmlExportImportMessage = "ToXmlString and FromXmlString have no implementation for ECC types, and are obsolete. Use a standard import and export format such as ExportSubjectPublicKeyInfo or ImportSubjectPublicKeyInfo for public keys and ExportPkcs8PrivateKey or ImportPkcs8PrivateKey for private keys.";

		internal const string EccXmlExportImportDiagId = "SYSLIB0042";

		internal const string EcDhPublicKeyBlobMessage = "ECDiffieHellmanPublicKey.ToByteArray() and the associated constructor do not have a consistent and interoperable implementation on all platforms. Use ECDiffieHellmanPublicKey.ExportSubjectPublicKeyInfo() instead.";

		internal const string EcDhPublicKeyBlobDiagId = "SYSLIB0043";

		internal const string AssemblyNameCodeBaseMessage = "AssemblyName.CodeBase and AssemblyName.EscapedCodeBase are obsolete. Using them for loading an assembly is not supported.";

		internal const string AssemblyNameCodeBaseDiagId = "SYSLIB0044";

		internal const string CryptoStringFactoryMessage = "Cryptographic factory methods accepting an algorithm name are obsolete. Use the parameterless Create factory method on the algorithm type instead.";

		internal const string CryptoStringFactoryDiagId = "SYSLIB0045";

		internal const string ControlledExecutionRunMessage = "ControlledExecution.Run method may corrupt the process and should not be used in production code.";

		internal const string ControlledExecutionRunDiagId = "SYSLIB0046";

		internal const string XmlSecureResolverMessage = "XmlSecureResolver is obsolete. Use XmlResolver.ThrowingResolver instead when attempting to forbid XML external entity resolution.";

		internal const string XmlSecureResolverDiagId = "SYSLIB0047";

		internal const string RsaEncryptDecryptValueMessage = "RSA.EncryptValue and DecryptValue are not supported and throw NotSupportedException. Use RSA.Encrypt and RSA.Decrypt instead.";

		internal const string RsaEncryptDecryptDiagId = "SYSLIB0048";

		internal const string JsonSerializerOptionsAddContextMessage = "JsonSerializerOptions.AddContext is obsolete. To register a JsonSerializerContext, use either the TypeInfoResolver or TypeInfoResolverChain properties.";

		internal const string JsonSerializerOptionsAddContextDiagId = "SYSLIB0049";

		internal const string LegacyFormatterMessage = "Formatter-based serialization is obsolete and should not be used.";

		internal const string LegacyFormatterDiagId = "SYSLIB0050";

		internal const string LegacyFormatterImplMessage = "This API supports obsolete formatter-based serialization. It should not be called or extended by application code.";

		internal const string LegacyFormatterImplDiagId = "SYSLIB0051";

		internal const string RegexExtensibilityImplMessage = "This API supports obsolete mechanisms for Regex extensibility. It is not supported.";

		internal const string RegexExtensibilityDiagId = "SYSLIB0052";

		internal const string AesGcmTagConstructorMessage = "AesGcm should indicate the required tag size for encryption and decryption. Use a constructor that accepts the tag size.";

		internal const string AesGcmTagConstructorDiagId = "SYSLIB0053";
	}
	internal static class SR
	{
		private static readonly bool s_usingResourceKeys = AppContext.TryGetSwitch("System.Resources.UseSystemResourceKeys", out var isEnabled) && isEnabled;

		private static ResourceManager s_resourceManager;

		internal static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(typeof(SR)));

		internal static string ChannelClosedException_DefaultMessage => GetResourceString("ChannelClosedException_DefaultMessage");

		internal static string InvalidOperation_IncompleteAsyncOperation => GetResourceString("InvalidOperation_IncompleteAsyncOperation");

		internal static string InvalidOperation_MultipleContinuations => GetResourceString("InvalidOperation_MultipleContinuations");

		internal static string InvalidOperation_IncorrectToken => GetResourceString("InvalidOperation_IncorrectToken");

		internal static bool UsingResourceKeys()
		{
			return s_usingResourceKeys;
		}

		private static string GetResourceString(string resourceKey)
		{
			if (UsingResourceKeys())
			{
				return resourceKey;
			}
			string result = null;
			try
			{
				result = ResourceManager.GetString(resourceKey);
			}
			catch (MissingManifestResourceException)
			{
			}
			return result;
		}

		private static string GetResourceString(string resourceKey, string defaultString)
		{
			string resourceString = GetResourceString(resourceKey);
			if (!(resourceKey == resourceString) && resourceString != null)
			{
				return resourceString;
			}
			return defaultString;
		}

		internal static string Format(string resourceFormat, object p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(resourceFormat, p1);
		}

		internal static string Format(string resourceFormat, object p1, object p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(resourceFormat, p1, p2);
		}

		internal static string Format(string resourceFormat, object p1, object p2, object p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(resourceFormat, p1, p2, p3);
		}

		internal static string Format(string resourceFormat, params object[] args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + ", " + string.Join(", ", args);
				}
				return string.Format(resourceFormat, args);
			}
			return resourceFormat;
		}

		internal static string Format(IFormatProvider provider, string resourceFormat, object p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(provider, resourceFormat, p1);
		}

		internal static string Format(IFormatProvider provider, string resourceFormat, object p1, object p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(provider, resourceFormat, p1, p2);
		}

		internal static string Format(IFormatProvider provider, string resourceFormat, object p1, object p2, object p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(provider, resourceFormat, p1, p2, p3);
		}

		internal static string Format(IFormatProvider provider, string resourceFormat, params object[] args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + ", " + string.Join(", ", args);
				}
				return string.Format(provider, resourceFormat, args);
			}
			return resourceFormat;
		}
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	internal sealed class MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	internal sealed class MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
}
namespace System.Runtime.InteropServices
{
	[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
	internal sealed class LibraryImportAttribute : Attribute
	{
		public string LibraryName { get; }

		public string EntryPoint { get; set; }

		public StringMarshalling StringMarshalling { get; set; }

		public Type StringMarshallingCustomType { get; set; }

		public bool SetLastError { get; set; }

		public LibraryImportAttribute(string libraryName)
		{
			LibraryName = libraryName;
		}
	}
	internal enum StringMarshalling
	{
		Custom,
		Utf8,
		Utf16
	}
}
namespace System.Collections.Generic
{
	[DebuggerDisplay("Count = {_size}")]
	internal sealed class Deque<T>
	{
		private T[] _array = Array.Empty<T>();

		private int _head;

		private int _tail;

		private int _size;

		public int Count => _size;

		public bool IsEmpty => _size == 0;

		public void EnqueueTail(T item)
		{
			if (_size == _array.Length)
			{
				Grow();
			}
			_array[_tail] = item;
			if (++_tail == _array.Length)
			{
				_tail = 0;
			}
			_size++;
		}

		public T DequeueHead()
		{
			T result = _array[_head];
			_array[_head] = default(T);
			if (++_head == _array.Length)
			{
				_head = 0;
			}
			_size--;
			return result;
		}

		public T PeekHead()
		{
			return _array[_head];
		}

		public T PeekTail()
		{
			int num = _tail - 1;
			if (num == -1)
			{
				num = _array.Length - 1;
			}
			return _array[num];
		}

		public T DequeueTail()
		{
			if (--_tail == -1)
			{
				_tail = _array.Length - 1;
			}
			T result = _array[_tail];
			_array[_tail] = default(T);
			_size--;
			return result;
		}

		public IEnumerator<T> GetEnumerator()
		{
			int pos = _head;
			int count = _size;
			while (count-- > 0)
			{
				yield return _array[pos];
				pos = (pos + 1) % _array.Length;
			}
		}

		private void Grow()
		{
			int num = (int)((long)_array.Length * 2L);
			if (num < _array.Length + 4)
			{
				num = _array.Length + 4;
			}
			T[] array = new T[num];
			if (_head == 0)
			{
				Array.Copy(_array, array, _size);
			}
			else
			{
				Array.Copy(_array, _head, array, 0, _array.Length - _head);
				Array.Copy(_array, 0, array, _array.Length - _head, _tail);
			}
			_array = array;
			_head = 0;
			_tail = _size;
		}
	}
}
namespace System.Collections.Concurrent
{
	internal interface IProducerConsumerQueue<T> : IEnumerable<T>, IEnumerable
	{
		bool IsEmpty { get; }

		int Count { get; }

		void Enqueue(T item);

		bool TryDequeue([MaybeNullWhen(false)] out T result);

		int GetCountSafe(object syncObj);
	}
	[DebuggerDisplay("Count = {Count}")]
	internal sealed class MultiProducerMultiConsumerQueue<T> : ConcurrentQueue<T>, IProducerConsumerQueue<T>, IEnumerable<T>, IEnumerable
	{
		bool IProducerConsumerQueue<T>.IsEmpty => base.IsEmpty;

		int IProducerConsumerQueue<T>.Count => base.Count;

		void IProducerConsumerQueue<T>.Enqueue(T item)
		{
			Enqueue(item);
		}

		bool IProducerConsumerQueue<T>.TryDequeue([MaybeNullWhen(false)] out T result)
		{
			return TryDequeue(out result);
		}

		int IProducerConsumerQueue<T>.GetCountSafe(object syncObj)
		{
			return base.Count;
		}
	}
	[DebuggerDisplay("Count = {Count}")]
	[DebuggerTypeProxy(typeof(SingleProducerSingleConsumerQueue<>.SingleProducerSingleConsumerQueue_DebugView))]
	internal sealed class SingleProducerSingleConsumerQueue<T> : IProducerConsumerQueue<T>, IEnumerable<T>, IEnumerable
	{
		[StructLayout(LayoutKind.Sequential)]
		private sealed class Segment
		{
			internal Segment _next;

			internal readonly T[] _array;

			internal SegmentState _state;

			internal Segment(int size)
			{
				_array = new T[size];
			}
		}

		private struct SegmentState
		{
			internal Internal.PaddingFor32 _pad0;

			internal volatile int _first;

			internal int _lastCopy;

			internal Internal.PaddingFor32 _pad1;

			internal int _firstCopy;

			internal volatile int _last;

			internal Internal.PaddingFor32 _pad2;
		}

		private sealed class SingleProducerSingleConsumerQueue_DebugView
		{
			private readonly SingleProducerSingleConsumerQueue<T> _queue;

			[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
			public T[] Items => new List<T>(_queue).ToArray();

			public SingleProducerSingleConsumerQueue_DebugView(SingleProducerSingleConsumerQueue<T> queue)
			{
				_queue = queue;
			}
		}

		private const int InitialSegmentSize = 32;

		private const int MaxSegmentSize = 16777216;

		private volatile Segment _head;

		private volatile Segment _tail;

		public bool IsEmpty
		{
			get
			{
				Segment head = _head;
				if (head._state._first != head._state._lastCopy)
				{
					return false;
				}
				if (head._state._first != head._state._last)
				{
					return false;
				}
				return head._next == null;
			}
		}

		public int Count
		{
			get
			{
				int num = 0;
				for (Segment segment = _head; segment != null; segment = segment._next)
				{
					int num2 = segment._array.Length;
					int first;
					int last;
					do
					{
						first = segment._state._first;
						last = segment._state._last;
					}
					while (first != segment._state._first);
					num += (last - first) & (num2 - 1);
				}
				return num;
			}
		}

		public SingleProducerSingleConsumerQueue()
		{
			_head = (_tail = new Segment(32));
		}

		public void Enqueue(T item)
		{
			Segment segment = _tail;
			T[] array = segment._array;
			int last = segment._state._last;
			int num = (last + 1) & (array.Length - 1);
			if (num != segment._state._firstCopy)
			{
				array[last] = item;
				segment._state._last = num;
			}
			else
			{
				EnqueueSlow(item, ref segment);
			}
		}

		private void EnqueueSlow(T item, ref Segment segment)
		{
			if (segment._state._firstCopy != segment._state._first)
			{
				segment._state._firstCopy = segment._state._first;
				Enqueue(item);
				return;
			}
			int size = Math.Min(_tail._array.Length * 2, 16777216);
			Segment segment2 = new Segment(size);
			segment2._array[0] = item;
			segment2._state._last = 1;
			segment2._state._lastCopy = 1;
			try
			{
			}
			finally
			{
				Volatile.Write(ref _tail._next, segment2);
				_tail = segment2;
			}
		}

		public bool TryDequeue([MaybeNullWhen(false)] out T result)
		{
			Segment head = _head;
			T[] array = head._array;
			int first = head._state._first;
			if (first != head._state._lastCopy)
			{
				result = array[first];
				array[first] = default(T);
				head._state._first = (first + 1) & (array.Length - 1);
				return true;
			}
			return TryDequeueSlow(head, array, peek: false, out result);
		}

		public bool TryPeek([MaybeNullWhen(false)] out T result)
		{
			Segment head = _head;
			T[] array = head._array;
			int first = head._state._first;
			if (first != head._state._lastCopy)
			{
				result = array[first];
				return true;
			}
			return TryDequeueSlow(head, array, peek: true, out result);
		}

		private bool TryDequeueSlow(Segment segment, T[] array, bool peek, [MaybeNullWhen(false)] out T result)
		{
			if (segment._state._last != segment._state._lastCopy)
			{
				segment._state._lastCopy = segment._state._last;
				if (!peek)
				{
					return TryDequeue(out result);
				}
				return TryPeek(out result);
			}
			if (segment._next != null && segment._state._first == segment._state._last)
			{
				segment = segment._next;
				array = segment._array;
				_head = segment;
			}
			int first = segment._state._first;
			if (first == segment._state._last)
			{
				result = default(T);
				return false;
			}
			result = array[first];
			if (!peek)
			{
				array[first] = default(T);
				segment._state._first = (first + 1) & (segment._array.Length - 1);
				segment._state._lastCopy = segment._state._last;
			}
			return true;
		}

		public bool TryDequeueIf(Predicate<T> predicate, [MaybeNullWhen(false)] out T result)
		{
			Segment head = _head;
			T[] array = head._array;
			int first = head._state._first;
			if (first != head._state._lastCopy)
			{
				result = array[first];
				if (predicate == null || predicate(result))
				{
					array[first] = default(T);
					head._state._first = (first + 1) & (array.Length - 1);
					return true;
				}
				result = default(T);
				return false;
			}
			return TryDequeueIfSlow(predicate, head, array, out result);
		}

		private bool TryDequeueIfSlow(Predicate<T> predicate, Segment segment, T[] array, [MaybeNullWhen(false)] out T result)
		{
			if (segment._state._last != segment._state._lastCopy)
			{
				segment._state._lastCopy = segment._state._last;
				return TryDequeueIf(predicate, out result);
			}
			if (segment._next != null && segment._state._first == segment._state._last)
			{
				segment = segment._next;
				array = segment._array;
				_head = segment;
			}
			int first = segment._state._first;
			if (first == segment._state._last)
			{
				result = default(T);
				return false;
			}
			result = array[first];
			if (predicate == null || predicate(result))
			{
				array[first] = default(T);
				segment._state._first = (first + 1) & (segment._array.Length - 1);
				segment._state._lastCopy = segment._state._last;
				return true;
			}
			result = default(T);
			return false;
		}

		public void Clear()
		{
			T result;
			while (TryDequeue(out result))
			{
			}
		}

		public IEnumerator<T> GetEnumerator()
		{
			for (Segment segment = _head; segment != null; segment = segment._next)
			{
				for (int pt = segment._state._first; pt != segment._state._last; pt = (pt + 1) & (segment._array.Length - 1))
				{
					yield return segment._array[pt];
				}
			}
		}

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

		int IProducerConsumerQueue<T>.GetCountSafe(object syncObj)
		{
			lock (syncObj)
			{
				return Count;
			}
		}
	}
}
namespace System.Threading.Channels
{
	internal abstract class AsyncOperation
	{
		protected static readonly Action<object> s_availableSentinel = AvailableSentinel;

		protected static readonly Action<object> s_completedSentinel = CompletedSentinel;

		private static void AvailableSentinel(object s)
		{
		}

		private static void CompletedSentinel(object s)
		{
		}

		protected static void ThrowIncompleteOperationException()
		{
			throw new InvalidOperationException(System.SR.InvalidOperation_IncompleteAsyncOperation);
		}

		protected static void ThrowMultipleContinuations()
		{
			throw new InvalidOperationException(System.SR.InvalidOperation_MultipleContinuations);
		}

		protected static void ThrowIncorrectCurrentIdException()
		{
			throw new InvalidOperationException(System.SR.InvalidOperation_IncorrectToken);
		}
	}
	internal class AsyncOperation<TResult> : AsyncOperation, IValueTaskSource, IValueTaskSource<TResult>
	{
		private readonly CancellationTokenRegistration _registration;

		private readonly bool _pooled;

		private readonly bool _runContinuationsAsynchronously;

		private volatile int _completionReserved;

		private TResult _result;

		private ExceptionDispatchInfo _error;

		private Action<object> _continuation;

		private object _continuationState;

		private object _schedulingContext;

		private ExecutionContext _executionContext;

		private short _currentId;

		public AsyncOperation<TResult> Next { get; set; }

		public CancellationToken CancellationToken { get; }

		public ValueTask ValueTask => new ValueTask(this, _currentId);

		public ValueTask<TResult> ValueTaskOfT => new ValueTask<TResult>(this, _currentId);

		internal bool IsCompleted => (object)_continuation == AsyncOperation.s_completedSentinel;

		public AsyncOperation(bool runContinuationsAsynchronously, CancellationToken cancellationToken = default(CancellationToken), bool pooled = false)
		{
			_continuation = (pooled ? AsyncOperation.s_availableSentinel : null);
			_pooled = pooled;
			_runContinuationsAsynchronously = runContinuationsAsynchronously;
			if (cancellationToken.CanBeCanceled)
			{
				CancellationToken = cancellationToken;
				_registration = UnsafeRegister(cancellationToken, delegate(object s)
				{
					AsyncOperation<TResult> asyncOperation = (AsyncOperation<TResult>)s;
					asyncOperation.TrySetCanceled(asyncOperation.CancellationToken);
				}, this);
			}
		}

		public ValueTaskSourceStatus GetStatus(short token)
		{
			if (_currentId != token)
			{
				AsyncOperation.ThrowIncorrectCurrentIdException();
			}
			if (IsCompleted)
			{
				if (_error != null)
				{
					if (!(_error.SourceException is OperationCanceledException))
					{
						return ValueTaskSourceStatus.Faulted;
					}
					return ValueTaskSourceStatus.Canceled;
				}
				return ValueTaskSourceStatus.Succeeded;
			}
			return ValueTaskSourceStatus.Pending;
		}

		public TResult GetResult(short token)
		{
			if (_currentId != token)
			{
				AsyncOperation.ThrowIncorrectCurrentIdException();
			}
			if (!IsCompleted)
			{
				AsyncOperation.ThrowIncompleteOperationException();
			}
			ExceptionDispatchInfo error = _error;
			TResult result = _result;
			_currentId++;
			if (_pooled)
			{
				Volatile.Write(ref _continuation, AsyncOperation.s_availableSentinel);
			}
			error?.Throw();
			return result;
		}

		void IValueTaskSource.GetResult(short token)
		{
			if (_currentId != token)
			{
				AsyncOperation.ThrowIncorrectCurrentIdException();
			}
			if (!IsCompleted)
			{
				AsyncOperation.ThrowIncompleteOperationException();
			}
			ExceptionDispatchInfo error = _error;
			_currentId++;
			if (_pooled)
			{
				Volatile.Write(ref _continuation, AsyncOperation.s_availableSentinel);
			}
			error?.Throw();
		}

		public bool TryOwnAndReset()
		{
			if ((object)Interlocked.CompareExchange(ref _continuation, null, AsyncOperation.s_availableSentinel) == AsyncOperation.s_availableSentinel)
			{
				_continuationState = null;
				_result = default(TResult);
				_error = null;
				_schedulingContext = null;
				_executionContext = null;
				return true;
			}
			return false;
		}

		public void OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags)
		{
			if (_currentId != token)
			{
				AsyncOperation.ThrowIncorrectCurrentIdException();
			}
			if (_continuationState != null)
			{
				AsyncOperation.ThrowMultipleContinuations();
			}
			_continuationState = state;
			if ((flags & ValueTaskSourceOnCompletedFlags.FlowExecutionContext) != 0)
			{
				_executionContext = ExecutionContext.Capture();
			}
			SynchronizationContext synchronizationContext = null;
			TaskScheduler taskScheduler = null;
			if ((flags & ValueTaskSourceOnCompletedFlags.UseSchedulingContext) != 0)
			{
				synchronizationContext = SynchronizationContext.Current;
				if (synchronizationContext != null && synchronizationContext.GetType() != typeof(SynchronizationContext))
				{
					_schedulingContext = synchronizationContext;
				}
				else
				{
					synchronizationContext = null;
					taskScheduler = TaskScheduler.Current;
					if (taskScheduler != TaskScheduler.Default)
					{
						_schedulingContext = taskScheduler;
					}
				}
			}
			Action<object> action = Interlocked.CompareExchange(ref _continuation, continuation, null);
			if (action == null)
			{
				return;
			}
			if ((object)action != AsyncOperation.s_completedSentinel)
			{
				AsyncOperation.ThrowMultipleContinuations();
			}
			if (_schedulingContext == null)
			{
				if (_executionContext == null)
				{
					UnsafeQueueUserWorkItem(continuation, state);
				}
				else
				{
					QueueUserWorkItem(continuation, state);
				}
			}
			else if (synchronizationContext != null)
			{
				synchronizationContext.Post(delegate(object s)
				{
					KeyValuePair<Action<object>, object> keyValuePair = (KeyValuePair<Action<object>, object>)s;
					keyValuePair.Key(keyValuePair.Value);
				}, new KeyValuePair<Action<object>, object>(continuation, state));
			}
			else
			{
				Task.Factory.StartNew(continuation, state, CancellationToken.None, TaskCreationOptions.DenyChildAttach, taskScheduler);
			}
		}

		public bool UnregisterCancellation()
		{
			if (CancellationToken.CanBeCanceled)
			{
				_registration.Dispose();
				return _completionReserved == 0;
			}
			return true;
		}

		public bool TrySetResult(TResult item)
		{
			UnregisterCancellation();
			if (TryReserveCompletionIfCancelable())
			{
				_result = item;
				SignalCompletion();
				return true;
			}
			return false;
		}

		public bool TrySetException(Exception exception)
		{
			UnregisterCancellation();
			if (TryReserveCompletionIfCancelable())
			{
				_error = ExceptionDispatchInfo.Capture(exception);
				SignalCompletion();
				return true;
			}
			return false;
		}

		public bool TrySetCanceled(CancellationToken cancellationToken = default(CancellationToken))
		{
			if (TryReserveCompletionIfCancelable())
			{
				_error = ExceptionDispatchInfo.Capture(new OperationCanceledException(cancellationToken));
				SignalCompletion();
				return true;
			}
			return false;
		}

		private bool TryReserveCompletionIfCancelable()
		{
			if (CancellationToken.CanBeCanceled)
			{
				return Interlocked.CompareExchange(ref _completionReserved, 1, 0) == 0;
			}
			return true;
		}

		private void SignalCompletion()
		{
			if (_continuation == null && Interlocked.CompareExchange(ref _continuation, AsyncOperation.s_completedSentinel, null) == null)
			{
				return;
			}
			if (_schedulingContext == null)
			{
				if (_runContinuationsAsynchronously)
				{
					UnsafeQueueSetCompletionAndInvokeContinuation();
					return;
				}
			}
			else if (_schedulingContext is SynchronizationContext synchronizationContext)
			{
				if (_runContinuationsAsynchronously || synchronizationContext != SynchronizationContext.Current)
				{
					synchronizationContext.Post(delegate(object s)
					{
						((AsyncOperation<TResult>)s).SetCompletionAndInvokeContinuation();
					}, this);
					return;
				}
			}
			else
			{
				TaskScheduler taskScheduler = (TaskScheduler)_schedulingContext;
				if (_runContinuationsAsynchronously || taskScheduler != TaskScheduler.Current)
				{
					Task.Factory.StartNew(delegate(object s)
					{
						((AsyncOperation<TResult>)s).SetCompletionAndInvokeContinuation();
					}, this, CancellationToken.None, TaskCreationOptions.DenyChildAttach, taskScheduler);
					return;
				}
			}
			SetCompletionAndInvokeContinuation();
		}

		private void SetCompletionAndInvokeContinuation()
		{
			if (_executionContext == null)
			{
				Action<object> continuation = _continuation;
				_continuation = AsyncOperation.s_completedSentinel;
				continuation(_continuationState);
				return;
			}
			ExecutionContext.Run(_executionContext, delegate(object s)
			{
				AsyncOperation<TResult> asyncOperation = (AsyncOperation<TResult>)s;
				Action<object> continuation2 = asyncOperation._continuation;
				asyncOperation._continuation = AsyncOperation.s_completedSentinel;
				continuation2(asyncOperation._continuationState);
			}, this);
		}

		private void UnsafeQueueSetCompletionAndInvokeContinuation()
		{
			ThreadPool.UnsafeQueueUserWorkItem(delegate(object s)
			{
				((AsyncOperation<TResult>)s).SetCompletionAndInvokeContinuation();
			}, this);
		}

		private static void UnsafeQueueUserWorkItem(Action<object> action, object state)
		{
			QueueUserWorkItem(action, state);
		}

		private static void QueueUserWorkItem(Action<object> action, object state)
		{
			Task.Factory.StartNew(action, state, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
		}

		private static CancellationTokenRegistration UnsafeRegister(CancellationToken cancellationToken, Action<object> action, object state)
		{
			return cancellationToken.Register(action, state);
		}
	}
	internal sealed class VoidAsyncOperationWithData<TData> : AsyncOperation<VoidResult>
	{
		public TData Item { get; set; }

		public VoidAsyncOperationWithData(bool runContinuationsAsynchronously, CancellationToken cancellationToken = default(CancellationToken), bool pooled = false)
			: base(runContinuationsAsynchronously, cancellationToken, pooled)
		{
		}
	}
	[DebuggerDisplay("Items = {ItemsCountForDebugger}, Capacity = {_bufferedCapacity}, Mode = {_mode}, Closed = {ChannelIsClosedForDebugger}")]
	[DebuggerTypeProxy(typeof(DebugEnumeratorDebugView<>))]
	internal sealed class BoundedChannel<T> : Channel<T>, IDebugEnumerable<T>
	{
		[DebuggerDisplay("Items = {ItemsCountForDebugger}")]
		[DebuggerTypeProxy(typeof(DebugEnumeratorDebugView<>))]
		private sealed class BoundedChannelReader : ChannelReader<T>, IDebugEnumerable<T>
		{
			internal readonly BoundedChannel<T> _parent;

			private readonly AsyncOperation<T> _readerSingleton;

			private readonly AsyncOperation<bool> _waiterSingleton;

			public override Task Completion => _parent._completion.Task;

			public override bool CanCount => true;

			public override bool CanPeek => true;

			public override int Count
			{
				get
				{
					BoundedChannel<T> parent = _parent;
					lock (parent.SyncObj)
					{
						return parent._items.Count;
					}
				}
			}

			private int ItemsCountForDebugger => _parent._items.Count;

			internal BoundedChannelReader(BoundedChannel<T> parent)
			{
				_parent = parent;
				_readerSingleton = new AsyncOperation<T>(parent._runContinuationsAsynchronously, default(CancellationToken), pooled: true);
				_waiterSingleton = new AsyncOperation<bool>(parent._runContinuationsAsynchronously, default(CancellationToken), pooled: true);
			}

			public override bool TryRead([MaybeNullWhen(false)] out T item)
			{
				BoundedChannel<T> parent = _parent;
				lock (parent.SyncObj)
				{
					if (!parent._items.IsEmpty)
					{
						item = DequeueItemAndPostProcess();
						return true;
					}
				}
				item = default(T);
				return false;
			}

			public override bool TryPeek([MaybeNullWhen(false)] out T item)
			{
				BoundedChannel<T> parent = _parent;
				lock (parent.SyncObj)
				{
					if (!parent._items.IsEmpty)
					{
						item = parent._items.PeekHead();
						return true;
					}
				}
				item = default(T);
				return false;
			}

			public override ValueTask<T> ReadAsync(CancellationToken cancellationToken)
			{
				if (cancellationToken.IsCancellationRequested)
				{
					return new ValueTask<T>(Task.FromCanceled<T>(cancellationToken));
				}
				BoundedChannel<T> parent = _parent;
				lock (parent.SyncObj)
				{
					if (!parent._items.IsEmpty)
					{
						return new ValueTask<T>(DequeueItemAndPostProcess());
					}
					if (parent._doneWriting != null)
					{
						return ChannelUtilities.GetInvalidCompletionValueTask<T>(parent._doneWriting);
					}
					if (!cancellationToken.CanBeCanceled)
					{
						AsyncOperation<T> readerSingleton = _readerSingleton;
						if (readerSingleton.TryOwnAndReset())
						{
							parent._blockedReaders.EnqueueTail(readerSingleton);
							return readerSingleton.ValueTaskOfT;
						}
					}
					AsyncOperation<T> asyncOperation = new AsyncOperation<T>(parent._runContinuationsAsynchronously | cancellationToken.CanBeCanceled, cancellationToken);
					parent._blockedReaders.EnqueueTail(asyncOperation);
					return asyncOperation.ValueTaskOfT;
				}
			}

			public override ValueTask<bool> WaitToReadAsync(CancellationToken cancellationToken)
			{
				if (cancellationToken.IsCancellationRequested)
				{
					return new ValueTask<bool>(Task.FromCanceled<bool>(cancellationToken));
				}
				BoundedChannel<T> parent = _parent;
				lock (parent.SyncObj)
				{
					if (!parent._items.IsEmpty)
					{
						return new ValueTask<bool>(result: true);
					}
					if (parent._doneWriting != null)
					{
						return (parent._doneWriting != ChannelUtilities.s_doneWritingSentinel) ? new ValueTask<bool>(Task.FromException<bool>(parent._doneWriting)) : default(ValueTask<bool>);
					}
					if (!cancellationToken.CanBeCanceled)
					{
						AsyncOperation<bool> waiterSingleton = _waiterSingleton;
						if (waiterSingleton.TryOwnAndReset())
						{
							ChannelUtilities.QueueWaiter(ref parent._waitingReadersTail, waiterSingleton);
							return waiterSingleton.ValueTaskOfT;
						}
					}
					AsyncOperation<bool> asyncOperation = new AsyncOperation<bool>(parent._runContinuationsAsynchronously | cancellationToken.CanBeCanceled, cancellationToken);
					ChannelUtilities.QueueWaiter(ref _parent._waitingReadersTail, asyncOperation);
					return asyncOperation.ValueTaskOfT;
				}
			}

			private T DequeueItemAndPostProcess()
			{
				BoundedChannel<T> parent = _parent;
				T result = parent._items.DequeueHead();
				if (parent._doneWriting != null)
				{
					if (parent._items.IsEmpty)
					{
						ChannelUtilities.Complete(parent._completion, parent._doneWriting);
					}
				}
				else
				{
					while (!parent._blockedWriters.IsEmpty)
					{
						VoidAsyncOperationWithData<T> voidAsyncOperationWithData = parent._blockedWriters.DequeueHead();
						if (voidAsyncOperationWithData.TrySetResult(default(VoidResult)))
						{
							parent._items.EnqueueTail(voidAsyncOperationWithData.Item);
							return result;
						}
					}
					ChannelUtilities.WakeUpWaiters(ref parent._waitingWritersTail, result: true);
				}
				return result;
			}

			IEnumerator<T> IDebugEnumerable<T>.GetEnumerator()
			{
				return _parent._items.GetEnumerator();
			}
		}

		[DebuggerDisplay("Items = {ItemsCountForDebugger}, Capacity = {CapacityForDebugger}")]
		[DebuggerTypeProxy(typeof(DebugEnumeratorDebugView<>))]
		private sealed class BoundedChannelWriter : ChannelWriter<T>, IDebugEnumerable<T>
		{
			internal readonly BoundedChannel<T> _parent;

			private readonly VoidAsyncOperationWithData<T> _writerSingleton;

			private readonly AsyncOperation<bool> _waiterSingleton;

			private int ItemsCountForDebugger => _parent._items.Count;

			private int CapacityForDebugger => _parent._bufferedCapacity;

			internal BoundedChannelWriter(BoundedChannel<T> parent)
			{
				_parent = parent;
				_writerSingleton = new VoidAsyncOperationWithData<T>(runContinuationsAsynchronously: true, default(CancellationToken), pooled: true);
				_waiterSingleton = new AsyncOperation<bool>(runContinuationsAsynchronously: true, default(CancellationToken), pooled: true);
			}

			public override bool TryComplete(Exception error)
			{
				BoundedChannel<T> parent = _parent;
				bool isEmpty;
				lock (parent.SyncObj)
				{
					if (parent._doneWriting != null)
					{
						return false;
					}
					parent._doneWriting = error ?? ChannelUtilities.s_doneWritingSentinel;
					isEmpty = parent._items.IsEmpty;
				}
				if (isEmpty)
				{
					ChannelUtilities.Complete(parent._completion, error);
				}
				ChannelUtilities.FailOperations<AsyncOperation<T>, T>(parent._blockedReaders, ChannelUtilities.CreateInvalidCompletionException(error));
				ChannelUtilities.FailOperations<VoidAsyncOperationWithData<T>, VoidResult>(parent._blockedWriters, ChannelUtilities.CreateInvalidCompletionException(error));
				ChannelUtilities.WakeUpWaiters(ref parent._waitingReadersTail, result: false, error);
				ChannelUtilities.WakeUpWaiters(ref parent._waitingWritersTail, result: false, error);
				return true;
			}

			public override bool TryWrite(T item)
			{
				AsyncOperation<T> asyncOperation = null;
				AsyncOperation<bool> listTail = null;
				BoundedChannel<T> parent = _parent;
				bool lockTaken = false;
				try
				{
					Monitor.Enter(parent.SyncObj, ref lockTaken);
					if (parent._doneWriting != null)
					{
						return false;
					}
					int count = parent._items.Count;
					if (count != 0)
					{
						if (count < parent._bufferedCapacity)
						{
							parent._items.EnqueueTail(item);
							return true;
						}
						if (parent._mode == BoundedChannelFullMode.Wait)
						{
							return false;
						}
						if (parent._mode == BoundedChannelFullMode.DropWrite)
						{
							Monitor.Exit(parent.SyncObj);
							lockTaken = false;
							parent._itemDropped?.Invoke(item);
							return true;
						}
						T obj = ((parent._mode == BoundedChannelFullMode.DropNewest) ? parent._items.DequeueTail() : parent._items.DequeueHead());
						parent._items.EnqueueTail(item);
						Monitor.Exit(parent.SyncObj);
						lockTaken = false;
						parent._itemDropped?.Invoke(obj);
						return true;
					}
					while (!parent._blockedReaders.IsEmpty)
					{
						AsyncOperation<T> asyncOperation2 = parent._blockedReaders.DequeueHead();
						if (asyncOperation2.UnregisterCancellation())
						{
							asyncOperation = asyncOperation2;
							break;
						}
					}
					if (asyncOperation == null)
					{
						parent._items.EnqueueTail(item);
						listTail = parent._waitingReadersTail;
						if (listTail == null)
						{
							return true;
						}
						parent._waitingReadersTail = null;
					}
				}
				finally
				{
					if (lockTaken)
					{
						Monitor.Exit(parent.SyncObj);
					}
				}
				if (asyncOperation != null)
				{
					bool flag = asyncOperation.TrySetResult(item);
				}
				else
				{
					ChannelUtilities.WakeUpWaiters(ref listTail, result: true);
				}
				return true;
			}

			public override ValueTask<bool> WaitToWriteAsync(CancellationToken cancellationToken)
			{
				if (cancellationToken.IsCancellationRequested)
				{
					return new ValueTask<bool>(Task.FromCanceled<bool>(cancellationToken));
				}
				BoundedChannel<T> parent = _parent;
				lock (parent.SyncObj)
				{
					if (parent._doneWriting != null)
					{
						return (parent._doneWriting != ChannelUtilities.s_doneWritingSentinel) ? new ValueTask<bool>(Task.FromException<bool>(parent._doneWriting)) : default(ValueTask<bool>);
					}
					if (parent._items.Count < parent._bufferedCapacity || parent._mode != 0)
					{
						return new ValueTask<bool>(result: true);
					}
					if (!cancellationToken.CanBeCanceled)
					{
						AsyncOperation<bool> waiterSingleton = _waiterSingleton;
						if (waiterSingleton.TryOwnAndReset())
						{
							ChannelUtilities.QueueWaiter(ref parent._waitingWritersTail, waiterSingleton);
							return waiterSingleton.ValueTaskOfT;
						}
					}
					AsyncOperation<bool> asyncOperation = new AsyncOperation<bool>(runContinuationsAsynchronously: true, cancellationToken);
					ChannelUtilities.QueueWaiter(ref parent._waitingWritersTail, asyncOperation);
					return asyncOperation.ValueTaskOfT;
				}
			}

			public override ValueTask WriteAsync(T item, CancellationToken cancellationToken)
			{
				if (cancellationToken.IsCancellationRequested)
				{
					return new ValueTask(Task.FromCanceled(cancellationToken));
				}
				AsyncOperation<T> asyncOperation = null;
				AsyncOperation<bool> listTail = null;
				BoundedChannel<T> parent = _parent;
				bool lockTaken = false;
				try
				{
					Monitor.Enter(parent.SyncObj, ref lockTaken);
					if (parent._doneWriting != null)
					{
						return new ValueTask(Task.FromException(ChannelUtilities.CreateInvalidCompletionException(parent._doneWriting)));
					}
					int count = parent._items.Count;
					if (count != 0)
					{
						if (count < parent._bufferedCapacity)
						{
							parent._items.EnqueueTail(item);
							return default(ValueTask);
						}
						if (parent._mode == BoundedChannelFullMode.Wait)
						{
							if (!cancellationToken.CanBeCanceled)
							{
								VoidAsyncOperationWithData<T> writerSingleton = _writerSingleton;
								if (writerSingleton.TryOwnAndReset())
								{
									writerSingleton.Item = item;
									parent._blockedWriters.EnqueueTail(writerSingleton);
									return writerSingleton.ValueTask;
								}
							}
							VoidAsyncOperationWithData<T> voidAsyncOperationWithData = new VoidAsyncOperationWithData<T>(runContinuationsAsynchronously: true, cancellationToken);
							voidAsyncOperationWithData.Item = item;
							parent._blockedWriters.EnqueueTail(voidAsyncOperationWithData);
							return voidAsyncOperationWithData.ValueTask;
						}
						if (parent._mode == BoundedChannelFullMode.DropWrite)
						{
							Monitor.Exit(parent.SyncObj);
							lockTaken = false;
							parent._itemDropped?.Invoke(item);
							return default(ValueTask);
						}
						T obj = ((parent._mode == BoundedChannelFullMode.DropNewest) ? parent._items.DequeueTail() : parent._items.DequeueHead());
						parent._items.EnqueueTail(item);
						Monitor.Exit(parent.SyncObj);
						lockTaken = false;
						parent._itemDropped?.Invoke(obj);
						return default(ValueTask);
					}
					while (!parent._blockedReaders.IsEmpty)
					{
						AsyncOperation<T> asyncOperation2 = parent._blockedReaders.DequeueHead();
						if (asyncOperation2.UnregisterCancellation())
						{
							asyncOperation = asyncOperation2;
							break;
						}
					}
					if (asyncOperation == null)
					{
						parent._items.EnqueueTail(item);
						listTail = parent._waitingReadersTail;
						if (listTail == null)
						{
							return default(ValueTask);
						}
						parent._waitingReadersTail = null;
					}
				}
				finally
				{
					if (lockTaken)
					{
						Monitor.Exit(parent.SyncObj);
					}
				}
				if (asyncOperation != null)
				{
					bool flag = asyncOperation.TrySetResult(item);
				}
				else
				{
					ChannelUtilities.WakeUpWaiters(ref listTail, result: true);
				}
				return default(ValueTask);
			}

			IEnumerator<T> IDebugEnumerable<T>.GetEnumerator()
			{
				return _parent._items.GetEnumerator();
			}
		}

		private readonly BoundedChannelFullMode _mode;

		private readonly Action<T> _itemDropped;

		private readonly TaskCompletionSource _completion;

		private readonly int _bufferedCapacity;

		private readonly Deque<T> _items = new Deque<T>();

		private readonly Deque<AsyncOperation<T>> _blockedReaders = new Deque<AsyncOperation<T>>();

		private readonly Deque<VoidAsyncOperationWithData<T>> _blockedWriters = new Deque<VoidAsyncOperationWithData<T>>();

		private AsyncOperation<bool> _waitingReadersTail;

		private AsyncOperation<bool> _waitingWritersTail;

		private readonly bool _runContinuationsAsynchronously;

		private Exception _doneWriting;

		private object SyncObj => _items;

		private int ItemsCountForDebugger => _items.Count;

		private bool ChannelIsClosedForDebugger => _doneWriting != null;

		internal BoundedChannel(int bufferedCapacity, BoundedChannelFullMode mode, bool runContinuationsAsynchronously, Action<T> itemDropped)
		{
			_bufferedCapacity = bufferedCapacity;
			_mode = mode;
			_runContinuationsAsynchronously = runContinuationsAsynchronously;
			_itemDropped = itemDropped;
			_completion = new TaskCompletionSource(runContinuationsAsynchronously ? TaskCreationOptions.RunContinuationsAsynchronously : TaskCreationOptions.None);
			base.Reader = new BoundedChannelReader(this);
			base.Writer = new BoundedChannelWriter(this);
		}

		[Conditional("DEBUG")]
		private void AssertInvariants()
		{
			_ = _items.IsEmpty;
			_ = _items.Count;
			_ = _bufferedCapacity;
			_ = _blockedReaders.IsEmpty;
			_ = _blockedWriters.IsEmpty;
			_ = _completion.Task.IsCompleted;
		}

		IEnumerator<T> IDebugEnumerable<T>.GetEnumerator()
		{
			return _items.GetEnumerator();
		}
	}
	public enum BoundedChannelFullMode
	{
		Wait,
		DropNewest,
		DropOldest,
		DropWrite
	}
	public static class Channel
	{
		public static Channel<T> CreateUnbounded<T>()
		{
			return new UnboundedChannel<T>(runContinuationsAsynchronously: true);
		}

		public static Channel<T> CreateUnbounded<T>(UnboundedChannelOptions options)
		{
			if (options == null)
			{
				throw new ArgumentNullException("options");
			}
			if (options.SingleReader)
			{
				return new SingleConsumerUnboundedChannel<T>(!options.AllowSynchronousContinuations);
			}
			return new UnboundedChannel<T>(!options.AllowSynchronousContinuations);
		}

		public static Channel<T> CreateBounded<T>(int capacity)
		{
			if (capacity < 1)
			{
				throw new ArgumentOutOfRangeException("capacity");
			}
			return new BoundedChannel<T>(capacity, BoundedChannelFullMode.Wait, runContinuationsAsynchronously: true, null);
		}

		public static Channel<T> CreateBounded<T>(BoundedChannelOptions options)
		{
			return CreateBounded<T>(options, null);
		}

		public static Channel<T> CreateBounded<T>(BoundedChannelOptions options, Action<T>? itemDropped)
		{
			if (options == null)
			{
				throw new ArgumentNullException("options");
			}
			return new BoundedChannel<T>(options.Capacity, options.FullMode, !options.AllowSynchronousContinuations, itemDropped);
		}
	}
	[Serializable]
	public class ChannelClosedException : InvalidOperationException
	{
		public ChannelClosedException()
			: base(System.SR.ChannelClosedException_DefaultMessage)
		{
		}

		public ChannelClosedException(string? message)
			: base(message)
		{
		}

		public ChannelClosedException(Exception? innerException)
			: base(System.SR.ChannelClosedException_DefaultMessage, innerException)
		{
		}

		public ChannelClosedException(string? message, Exception? innerException)
			: base(message, innerException)
		{
		}

		protected ChannelClosedException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}
	}
	public abstract class ChannelOptions
	{
		public bool SingleWriter { get; set; }

		public bool SingleReader { get; set; }

		public bool AllowSynchronousContinuations { get; set; }
	}
	public sealed class BoundedChannelOptions : ChannelOptions
	{
		private int _capacity;

		private BoundedChannelFullMode _mode;

		public int Capacity
		{
			get
			{
				return _capacity;
			}
			set
			{
				if (value < 1)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_capacity = value;
			}
		}

		public BoundedChannelFullMode FullMode
		{
			get
			{
				return _mode;
			}
			set
			{
				if ((uint)value <= 3u)
				{
					_mode = value;
					return;
				}
				throw new ArgumentOutOfRangeException("value");
			}
		}

		public BoundedChannelOptions(int capacity)
		{
			if (capacity < 1)
			{
				throw new ArgumentOutOfRangeException("capacity");
			}
			_capacity = capacity;
		}
	}
	public sealed class UnboundedChannelOptions : ChannelOptions
	{
	}
	public abstract class ChannelReader<T>
	{
		public virtual Task Completion => ChannelUtilities.s_neverCompletingTask;

		public virtual bool CanCount => false;

		public virtual bool CanPeek => false;

		public virtual int Count
		{
			get
			{
				throw new NotSupportedException();
			}
		}

		public abstract bool TryRead([MaybeNullWhen(false)] out T item);

		public virtual bool TryPeek([MaybeNullWhen(false)] out T item)
		{
			item = default(T);
			return false;
		}

		public abstract ValueTask<bool> WaitToReadAsync(CancellationToken cancellationToken = default(CancellationToken));

		public virtual ValueTask<T> ReadAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			if (cancellationToken.IsCancellationRequested)
			{
				return new ValueTask<T>(Task.FromCanceled<T>(cancellationToken));
			}
			try
			{
				if (TryRead(out var item))
				{
					return new ValueTask<T>(item);
				}
			}
			catch (Exception ex) when (!(ex is ChannelClosedException) && !(ex is OperationCanceledException))
			{
				return new ValueTask<T>(Task.FromException<T>(ex));
			}
			return ReadAsyncCore(cancellationToken);
			async ValueTask<T> ReadAsyncCore(CancellationToken ct)
			{
				T item2;
				do
				{
					if (!(await WaitToReadAsync(ct).ConfigureAwait(continueOnCapturedContext: false)))
					{
						throw new ChannelClosedException();
					}
				}
				while (!TryRead(out item2));
				return item2;
			}
		}

		public virtual async IAsyncEnumerable<T> ReadAllAsync([EnumeratorCancellation] CancellationToken cancellationToken = default(CancellationToken))
		{
			while (await WaitToReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false))
			{
				T item;
				while (TryRead(out item))
				{
					yield return item;
				}
			}
		}
	}
	internal static class ChannelUtilities
	{
		internal static readonly Exception s_doneWritingSentinel = new Exception("s_doneWritingSentinel");

		internal static readonly Task<bool> s_trueTask = Task.FromResult(result: true);

		internal static readonly Task<bool> s_falseTask = Task.FromResult(result: false);

		internal static readonly Task s_neverCompletingTask = new TaskCompletionSource<bool>().Task;

		internal static void Complete(TaskCompletionSource tcs, Exception error = null)
		{
			if (error is OperationCanceledException ex)
			{
				tcs.TrySetCanceled(ex.CancellationToken);
			}
			else if (error != null && error != s_doneWritingSentinel)
			{
				if (tcs.TrySetException(error))
				{
					_ = tcs.Task.Exception;
				}
			}
			else
			{
				tcs.TrySetResult();
			}
		}

		internal static ValueTask<T> GetInvalidCompletionValueTask<T>(Exception error)
		{
			Task<T> task = ((error == s_doneWritingSentinel) ? Task.FromException<T>(CreateInvalidCompletionException()) : ((error is OperationCanceledException ex) ? Task.FromCanceled<T>(ex.CancellationToken.IsCancellationRequested ? ex.CancellationToken : new CancellationToken(canceled: true)) : Task.FromException<T>(CreateInvalidCompletionException(error))));
			return new ValueTask<T>(task);
		}

		internal static void QueueWaiter(ref AsyncOperation<bool> tail, AsyncOperation<bool> waiter)
		{
			AsyncOperation<bool> asyncOperation = tail;
			if (asyncOperation == null)
			{
				waiter.Next = waiter;
			}
			else
			{
				waiter.Next = asyncOperation.Next;
				asyncOperation.Next = waiter;
			}
			tail = waiter;
		}

		internal static void WakeUpWaiters(ref AsyncOperation<bool> listTail, bool result, Exception error = null)
		{
			AsyncOperation<bool> asyncOperation = listTail;
			if (asyncOperation != null)
			{
				listTail = null;
				AsyncOperation<bool> next = asyncOperation.Next;
				AsyncOperation<bool> asyncOperation2 = next;
				do
				{
					AsyncOperation<bool> next2 = asyncOperation2.Next;
					asyncOperation2.Next = null;
					bool flag = ((error != null) ? asyncOperation2.TrySetException(error) : asyncOperation2.TrySetResult(result));
					asyncOperation2 = next2;
				}
				while (asyncOperation2 != next);
			}
		}

		internal static void FailOperations<T, TInner>(Deque<T> operations, Exception error) where T : AsyncOperation<TInner>
		{
			while (!operations.IsEmpty)
			{
				operations.DequeueHead().TrySetException(error);
			}
		}

		internal static Exception CreateInvalidCompletionException(Exception inner = null)
		{
			if (!(inner is OperationCanceledException))
			{
				if (inner == null || inner == s_doneWritingSentinel)
				{
					return new ChannelClosedException();
				}
				return new ChannelClosedException(inner);
			}
			return inner;
		}
	}
	public abstract class ChannelWriter<T>
	{
		public virtual bool TryComplete(Exception? error = null)
		{
			return false;
		}

		public abstract bool TryWrite(T item);

		public abstract ValueTask<bool> WaitToWriteAsync(CancellationToken cancellationToken = default(CancellationToken));

		public virtual ValueTask WriteAsync(T item, CancellationToken cancellationToken = default(CancellationToken))
		{
			try
			{
				return cancellationToken.IsCancellationRequested ? new ValueTask(Task.FromCanceled<T>(cancellationToken)) : (TryWrite(item) ? default(ValueTask) : WriteAsyncCore(item, cancellationToken));
			}
			catch (Exception exception)
			{
				return new ValueTask(Task.FromException(exception));
			}
		}

		private async ValueTask WriteAsyncCore(T innerItem, CancellationToken ct)
		{
			while (await WaitToWriteAsync(ct).ConfigureAwait(continueOnCapturedContext: false))
			{
				if (TryWrite(innerItem))
				{
					return;
				}
			}
			throw ChannelUtilities.CreateInvalidCompletionException();
		}

		public void Complete(Exception? error = null)
		{
			if (!TryComplete(error))
			{
				throw ChannelUtilities.CreateInvalidCompletionException();
			}
		}
	}
	public abstract class Channel<T> : Channel<T, T>
	{
	}
	public abstract class Channel<TWrite, TRead>
	{
		public ChannelReader<TRead> Reader { get; protected set; }

		public ChannelWriter<TWrite> Writer { get; protected set; }

		public static implicit operator ChannelReader<TRead>(Channel<TWrite, TRead> channel)
		{
			return channel.Reader;
		}

		public static implicit operator ChannelWriter<TWrite>(Channel<TWrite, TRead> channel)
		{
			return channel.Writer;
		}
	}
	internal interface IDebugEnumerable<T>
	{
		IEnumerator<T> GetEnumerator();
	}
	internal sealed class DebugEnumeratorDebugView<T>
	{
		[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
		public T[] Items { get; }

		public DebugEnumeratorDebugView(IDebugEnumerable<T> enumerable)
		{
			List<T> list = new List<T>();
			foreach (T item in enumerable)
			{
				list.Add(item);
			}
			Items = list.ToArray();
		}
	}
	[DebuggerDisplay("Items = {ItemsCountForDebugger}, Closed = {ChannelIsClosedForDebugger}")]
	[DebuggerTypeProxy(typeof(DebugEnumeratorDebugView<>))]
	internal sealed class SingleConsumerUnboundedChannel<T> : Channel<T>, IDebugEnumerable<T>
	{
		[DebuggerDisplay("Items = {ItemsCountForDebugger}")]
		[DebuggerTypeProxy(typeof(DebugEnumeratorDebugView<>))]
		private sealed class UnboundedChannelReader : ChannelReader<T>, IDebugEnumerable<T>
		{
			internal readonly SingleConsumerUnboundedChannel<T> _parent;

			private readonly AsyncOperation<T> _readerSingleton;

			private readonly AsyncOperation<bool> _waiterSingleton;

			public override Task Completion => _parent._completion.Task;

			public override bool CanPeek => true;

			private int ItemsCountForDebugger => _parent._items.Count;

			internal UnboundedChannelReader(SingleConsumerUnboundedChannel<T> parent)
			{
				_parent = parent;
				_readerSingleton = new AsyncOperation<T>(parent._runContinuationsAsynchronously, default(CancellationToken), pooled: true);
				_waiterSingleton = new AsyncOperation<bool>(parent._runContinuationsAsynchronously, default(CancellationToken), pooled: true);
			}

			public override ValueTask<T> ReadAsync(CancellationToken cancellationToken)
			{
				if (cancellationToken.IsCancellationRequested)
				{
					return new ValueTask<T>(Task.FromCanceled<T>(cancellationToken));
				}
				if (TryRead(out var item))
				{
					return new ValueTask<T>(item);
				}
				SingleConsumerUnboundedChannel<T> parent = _parent;
				AsyncOperation<T> asyncOperation;
				AsyncOperation<T> asyncOperation2;
				lock (parent.SyncObj)
				{
					if (TryRead(out item))
					{
						return new ValueTask<T>(item);
					}
					if (parent._doneWriting != null)
					{
						return ChannelUtilities.GetInvalidCompletionValueTask<T>(parent._doneWriting);
					}
					asyncOperation = parent._blockedReader;
					if (!cancellationToken.CanBeCanceled && _readerSingleton.TryOwnAndReset())
					{
						asyncOperation2 = _readerSingleton;
						if (asyncOperation2 == asyncOperation)
						{
							asyncOperation = null;
						}
					}
					else
					{
						asyncOperation2 = new AsyncOperation<T>(_parent._runContinuationsAsynchronously, cancellationToken);
					}
					parent._blockedReader = asyncOperation2;
				}
				asyncOperation?.TrySetCanceled();
				return asyncOperation2.ValueTaskOfT;
			}

			public override bool TryRead([MaybeNullWhen(false)] out T item)
			{
				SingleConsumerUnboundedChannel<T> parent = _parent;
				if (parent._items.TryDequeue(out item))
				{
					if (parent._doneWriting != null && parent._items.IsEmpty)
					{
						ChannelUtilities.Complete(parent._completion, parent._doneWriting);
					}
					return true;
				}
				return false;
			}

			public override bool TryPeek([MaybeNullWhen(false)] out T item)
			{
				return _parent._items.TryPeek(out item);
			}

			public override ValueTask<bool> WaitToReadAsync(CancellationToken cancellationToken)
			{
				if (cancellationToken.IsCancellationRequested)
				{
					return new ValueTask<bool>(Task.FromCanceled<bool>(cancellationToken));
				}
				if (!_parent._items.IsEmpty)
				{
					return new ValueTask<bool>(result: true);
				}
				SingleConsumerUnboundedChannel<T> parent = _parent;
				AsyncOperation<bool> asyncOperation = null;
				AsyncOperation<bool> asyncOperation2;
				lock (parent.SyncObj)
				{
					if (!parent._items.IsEmpty)
					{
						return new ValueTask<bool>(result: true);
					}
					if (parent._doneWriting != null)
					{
						return (parent._doneWriting != ChannelUtilities.s_doneWritingSentinel) ? new ValueTask<bool>(Task.FromException<bool>(parent._doneWriting)) : default(ValueTask<bool>);
					}
					asyncOperation = parent._waitingReader;
					if (!cancellationToken.CanBeCanceled && _waiterSingleton.TryOwnAndReset())
					{
						asyncOperation2 = _waiterSingleton;
						if (asyncOperation2 == asyncOperation)
						{
							asyncOperation = null;
						}
					}
					else
					{
						asyncOperation2 = new AsyncOperation<bool>(_parent._runContinuationsAsynchronously, cancellationToken);
					}
					parent._waitingReader = asyncOperation2;
				}
				asyncOperation?.TrySetCanceled();
				return asyncOperation2.ValueTaskOfT;
			}

			IEnumerator<T> IDebugEnumerable<T>.GetEnumerator()
			{
				return _parent._items.GetEnumerator();
			}
		}

		[DebuggerDisplay("Items = {ItemsCountForDebugger}")]
		[DebuggerTypeProxy(typeof(DebugEnumeratorDebugView<>))]
		private sealed class UnboundedChannelWriter : ChannelWriter<T>, IDebugEnumerable<T>
		{
			internal readonly SingleConsumerUnboundedChannel<T> _parent;

			private int ItemsCountForDebugger => _parent._items.Count;

			internal UnboundedChannelWriter(SingleConsumerUnboundedChannel<T> parent)
			{
				_parent = parent;
			}

			public override bool TryComplete(Exception error)
			{
				AsyncOperation<T> asyncOperation = null;
				AsyncOperation<bool> asyncOperation2 = null;
				bool flag = false;
				SingleConsumerUnboundedChannel<T> parent = _parent;
				lock (parent.SyncObj)
				{
					if (parent._doneWriting != null)
					{
						return false;
					}
					parent._doneWriting = error ?? ChannelUtilities.s_doneWritingSentinel;
					if (parent._items.IsEmpty)
					{
						flag = true;
						if (parent._blockedReader != null)
						{
							asyncOperation = parent._blockedReader;
							parent._blockedReader = null;
						}
						if (parent._waitingReader != null)
						{
							asyncOperation2 = parent._waitingReader;
							parent._waitingReader = null;
						}
					}
				}
				if (flag)
				{
					ChannelUtilities.Complete(parent._completion, error);
				}
				if (asyncOperation != null)
				{
					error = ChannelUtilities.CreateInvalidCompletionException(error);
					asyncOperation.TrySetException(error);
				}
				if (asyncOperation2 != null)
				{
					if (error != null)
					{
						asyncOperation2.TrySetException(error);
					}
					else
					{
						asyncOperation2.TrySetResult(item: false);
					}
				}
				return true;
			}

			public override bool TryWrite(T item)
			{
				SingleConsumerUnboundedChannel<T> parent = _parent;
				AsyncOperation<T> asyncOperation;
				do
				{
					asyncOperation = null;
					AsyncOperation<bool> asyncOperation2 = null;
					lock (parent.SyncObj)
					{
						if (parent._doneWriting != null)
						{
							return false;
						}
						asyncOperation = parent._blockedReader;
						if (asyncOperation != null)
						{
							parent._blockedReader = null;
						}
						else
						{
							parent._items.Enqueue(item);
							asyncOperation2 = parent._waitingReader;
							if (asyncOperation2 == null)
							{
								return true;
							}
							parent._waitingReader = null;
						}
					}
					if (asyncOperation2 != null)
					{
						asyncOperation2.TrySetResult(item: true);
						return true;
					}
				}
				while (!asyncOperation.TrySetResult(item));
				return true;
			}

			public override ValueTask<bool> WaitToWriteAsync(CancellationToken cancellationToken)
			{
				Exception doneWriting = _parent._doneWriting;
				if (!cancellationToken.IsCancellationRequested)
				{
					if (doneWriting != null)
					{
						if (doneWriting == ChannelUtilities.s_doneWritingSentinel)
						{
							return default(ValueTask<bool>);
						}
						return new ValueTask<bool>(Task.FromException<bool>(doneWriting));
					}
					return new ValueTask<bool>(result: true);
				}
				return new ValueTask<bool>(Task.FromCanceled<bool>(cancellationToken));
			}

			public override ValueTask WriteAsync(T item, CancellationToken cancellationToken)
			{
				if (!cancellationToken.IsCancellationRequested)
				{
					if (!TryWrite(item))
					{
						return new ValueTask(Task.FromException(ChannelUtilities.CreateInvalidCompletionException(_parent._doneWriting)));
					}
					return default(ValueTask);
				}
				return new ValueTask(Task.FromCanceled(cancellationToken));
			}

			IEnumerator<T> IDebugEnumerable<T>.GetEnumerator()
			{
				return _parent._items.GetEnumerator();
			}
		}

		private readonly TaskCompletionSource _completion;

		private readonly SingleProducerSingleConsumerQueue<T> _items = new SingleProducerSingleConsumerQueue<T>();

		private readonly bool _runContinuationsAsynchronously;

		private volatile Exception _doneWriting;

		private AsyncOperation<T> _blockedReader;

		private AsyncOperation<bool> _waitingReader;

		private object SyncObj => _items;

		private int ItemsCountForDebugger => _items.Count;

		private bool ChannelIsClosedForDebugger => _doneWriting != null;

		internal SingleConsumerUnboundedChannel(bool runContinuationsAsynchronously)
		{
			_runContinuationsAsynchronously = runContinuationsAsynchronously;
			_completion = new TaskCompletionSource(runContinuationsAsynchronously ? TaskCreationOptions.RunContinuationsAsynchronously : TaskCreationOptions.None);
			base.Reader = new UnboundedChannelReader(this);
			base.Writer = new UnboundedChannelWriter(this);
		}

		IEnumerator<T> IDebugEnumerable<T>.GetEnumerator()
		{
			return _items.GetEnumerator();
		}
	}
	internal sealed class TaskCompletionSource : TaskCompletionSource<VoidResult>
	{
		public TaskCompletionSource(TaskCreationOptions creationOptions)
			: base(creationOptions)
		{
		}

		public bool TrySetResult()
		{
			return TrySetResult(default(VoidResult));
		}
	}
	[DebuggerDisplay("Items = {ItemsCountForDebugger}, Closed = {ChannelIsClosedForDebugger}")]
	[DebuggerTypeProxy(typeof(DebugEnumeratorDebugView<>))]
	internal sealed class UnboundedChannel<T> : Channel<T>, IDebugEnumerable<T>
	{
		[DebuggerDisplay("Items = {Count}")]
		[DebuggerTypeProxy(typeof(DebugEnumeratorDebugView<>))]
		private sealed class UnboundedChannelReader : ChannelReader<T>, IDebugEnumerable<T>
		{
			internal readonly UnboundedChannel<T> _parent;

			private readonly AsyncOperation<T> _readerSingleton;

			private readonly AsyncOperation<bool> _waiterSingleton;

			public override Task Completion => _parent._completion.Task;

			public override bool CanCount => true;

			public override bool CanPeek => true;

			public override int Count => _parent._items.Count;

			internal UnboundedChannelReader(UnboundedChannel<T> parent)
			{
				_parent = parent;
				_readerSingleton = new AsyncOperation<T>(parent._runContinuationsAsynchronously, default(CancellationToken), pooled: true);
				_waiterSingleton = new AsyncOperation<bool>(parent._runContinuationsAsynchronously, default(CancellationToken), pooled: true);
			}

			public override ValueTask<T> ReadAsync(CancellationToken cancellationToken)
			{
				if (cancellationToken.IsCancellationRequested)
				{
					return new ValueTask<T>(Task.FromCanceled<T>(cancellationToken));
				}
				UnboundedChannel<T> parent = _parent;
				if (parent._items.TryDequeue(out var result))
				{
					CompleteIfDone(parent);
					return new ValueTask<T>(result);
				}
				lock (parent.SyncObj)
				{
					if (parent._items.TryDequeue(out result))
					{
						CompleteIfDone(parent);
						return new ValueTask<T>(result);
					}
					if (parent._doneWriting != null)
					{
						return ChannelUtilities.GetInvalidCompletionValueTask<T>(parent._doneWriting);
					}
					if (!cancellationToken.CanBeCanceled)
					{
						AsyncOperation<T> readerSingleton = _readerSingleton;
						if (readerSingleton.TryOwnAndReset())
						{
							parent._blockedReaders.EnqueueTail(readerSingleton);
							return readerSingleton.ValueTaskOfT;
						}
					}
					AsyncOperation<T> asyncOperation = new AsyncOperation<T>(parent._runContinuationsAsynchronously, cancellationToken);
					parent._blockedReaders.EnqueueTail(asyncOperation);
					return asyncOperation.ValueTaskOfT;
				}
			}

			public override bool TryRead([MaybeNullWhen(false)] out T item)
			{
				UnboundedChannel<T> parent = _parent;
				if (parent._items.TryDequeue(out item))
				{
					CompleteIfDone(parent);
					return true;
				}
				item = default(T);
				return false;
			}

			public override bool TryPeek([MaybeNullWhen(false)] out T item)
			{
				return _parent._items.TryPeek(out item);
			}

			private static void CompleteIfDone(UnboundedChannel<T> parent)
			{
				if (parent._doneWriting != null && parent._items.IsEmpty)
				{
					ChannelUtilities.Complete(parent._completion, parent._doneWriting);
				}
			}

			public override ValueTask<bool> WaitToReadAsync(CancellationToken cancellationToken)
			{
				if (cancellationToken.IsCancellationRequested)
				{
					return new ValueTask<bool>(Task.FromCanceled<bool>(cancellationToken));
				}
				if (!_parent._items.IsEmpty)
				{
					return new ValueTask<bool>(result: true);
				}
				UnboundedChannel<T> parent = _parent;
				lock (parent.SyncObj)
				{
					if (!parent._items.IsEmpty)
					{
						return new ValueTask<bool>(result: true);
					}
					if (parent._doneWriting != null)
					{
						return (parent._doneWriting != ChannelUtilities.s_doneWritingSentinel) ? new ValueTask<bool>(Task.FromException<bool>(parent._doneWriting)) : default(ValueTask<bool>);
					}
					if (!cancellationToken.CanBeCanceled)
					{
						AsyncOperation<bool> waiterSingleton = _waiterSingleton;
						if (waiterSingleton.TryOwnAndReset())
						{
							ChannelUtilities.QueueWaiter(ref parent._waitingReadersTail, waiterSingleton);
							return waiterSingleton.ValueTaskOfT;
						}
					}
					AsyncOperation<bool> asyncOperation = new AsyncOperation<bool>(parent._runContinuationsAsynchronously, cancellationToken);
					ChannelUtilities.QueueWaiter(ref parent._waitingReadersTail, asyncOperation);
					return asyncOperation.ValueTaskOfT;
				}
			}

			IEnumerator<T> IDebugEnumerable<T>.GetEnumerator()
			{
				return _parent._items.GetEnumerator();
			}
		}

		[DebuggerDisplay("Items = {ItemsCountForDebugger}")]
		[DebuggerTypeProxy(typeof(DebugEnumeratorDebugView<>))]
		private sealed class UnboundedChannelWriter : ChannelWriter<T>, IDebugEnumerable<T>
		{
			internal readonly UnboundedChannel<T> _parent;

			private int ItemsCountForDebugger => _parent._items.Count;

			internal UnboundedChannelWriter(UnboundedChannel<T> parent)
			{
				_parent = parent;
			}

			public override bool TryComplete(Exception error)
			{
				UnboundedChannel<T> parent = _parent;
				bool isEmpty;
				lock (parent.SyncObj)
				{
					if (parent._doneWriting != null)
					{
						return false;
					}
					parent._doneWriting = error ?? ChannelUtilities.s_doneWritingSentinel;
					isEmpty = parent._items.IsEmpty;
				}
				if (isEmpty)
				{
					ChannelUtilities.Complete(parent._completion, error);
				}
				ChannelUtilities.FailOperations<AsyncOperation<T>, T>(parent._blockedReaders, ChannelUtilities.CreateInvalidCompletionException(error));
				ChannelUtilities.WakeUpWaiters(ref parent._waitingReadersTail, result: false, error);
				return true;
			}

			public override bool TryWrite(T item)
			{
				UnboundedChannel<T> parent = _parent;
				AsyncOperation<bool> listTail;
				while (true)
				{
					AsyncOperation<T> asyncOperation = null;
					listTail = null;
					lock (parent.SyncObj)
					{
						if (parent._doneWriting != null)
						{
							return false;
						}
						if (parent._blockedReaders.IsEmpty)
						{
							parent._items.Enqueue(item);
							listTail = parent._waitingReadersTail;
							if (listTail == null)
							{
								return true;
							}
							parent._waitingReadersTail = null;
						}
						else
						{
							asyncOperation = parent._blockedReaders.DequeueHead();
						}
					}
					if (asyncOperation == null)
					{
						break;
					}
					if (asyncOperation.TrySetResult(item))
					{
						return true;
					}
				}
				ChannelUtilities.WakeUpWaiters(ref listTail, result: true);
				return true;
			}

			public override ValueTask<bool> WaitToWriteAsync(CancellationToken cancellationToken)
			{
				Exception doneWriting = _parent._doneWriting;
				if (!cancellationToken.IsCancellationRequested)
				{
					if (doneWriting != null)
					{
						if (doneWriting == ChannelUtilities.s_doneWritingSentinel)
						{
							return default(ValueTask<bool>);
						}
						return new ValueTask<bool>(Task.FromException<bool>(doneWriting));
					}
					return new ValueTask<bool>(result: true);
				}
				return new ValueTask<bool>(Task.FromCanceled<bool>(cancellationToken));
			}

			public override ValueTask WriteAsync(T item, CancellationToken cancellationToken)
			{
				if (!cancellationToken.IsCancellationRequested)
				{
					if (!TryWrite(item))
					{
						return new ValueTask(Task.FromException(ChannelUtilities.CreateInvalidCompletionException(_parent._doneWriting)));
					}
					return default(ValueTask);
				}
				return new ValueTask(Task.FromCanceled(cancellationToken));
			}

			IEnumerator<T> IDebugEnumerable<T>.GetEnumerator()
			{
				return _parent._items.GetEnumerator();
			}
		}

		private readonly TaskCompletionSource _completion;

		private readonly ConcurrentQueue<T> _items = new ConcurrentQueue<T>();

		private readonly Deque<AsyncOperation<T>> _blockedReaders = new Deque<AsyncOperation<T>>();

		private readonly bool _runContinuationsAsynchronously;

		private AsyncOperation<bool> _waitingReadersTail;

		private Exception _doneWriting;

		private object SyncObj => _items;

		private int ItemsCountForDebugger => _items.Count;

		private bool ChannelIsClosedForDebugger => _doneWriting != null;

		internal UnboundedChannel(bool runContinuationsAsynchronously)
		{
			_runContinuationsAsynchronously = runContinuationsAsynchronously;
			_completion = new TaskCompletionSource(runContinuationsAsynchronously ? TaskCreationOptions.RunContinuationsAsynchronously : TaskCreationOptions.None);
			base.Reader = new UnboundedChannelReader(this);
			base.Writer = new UnboundedChannelWriter(this);
		}

		[Conditional("DEBUG")]
		private void AssertInvariants()
		{
			if (!_items.IsEmpty)
			{
				_ = _runContinuationsAsynchronously;
			}
			if (!_blockedReaders.IsEmpty || _waitingReadersTail != null)
			{
				_ = _runContinuationsAsynchronously;
			}
			_ = _completion.Task.IsCompleted;
		}

		IEnumerator<T> IDebugEnumerable<T>.GetEnumerator()
		{
			return _items.GetEnumerator();
		}
	}
}

Mods/RealRadio/Websocket.Client.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.WebSockets;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using System.Threading.Channels;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.IO;
using Websocket.Client.Exceptions;
using Websocket.Client.Threading;
using Websocket.Client.Validations;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Mariusz Kotas")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright 2023 Mariusz Kotas. All rights reserved.")]
[assembly: AssemblyDescription("Client for websocket API with built-in reconnection and error handling")]
[assembly: AssemblyFileVersion("5.1.2.0")]
[assembly: AssemblyInformationalVersion("5.1.2+714bed8bea035db30f0b149fcbec794c084fc965")]
[assembly: AssemblyProduct("Websocket.Client")]
[assembly: AssemblyTitle("Websocket.Client")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Marfusios/websocket-client")]
[assembly: AssemblyVersion("5.1.2.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 Websocket.Client
{
	public interface IWebsocketClient : IDisposable
	{
		Uri Url { get; set; }

		IObservable<ResponseMessage> MessageReceived { get; }

		IObservable<ReconnectionInfo> ReconnectionHappened { get; }

		IObservable<DisconnectionInfo> DisconnectionHappened { get; }

		TimeSpan? ReconnectTimeout { get; set; }

		TimeSpan? ErrorReconnectTimeout { get; set; }

		TimeSpan? LostReconnectTimeout { get; set; }

		string? Name { get; set; }

		bool IsStarted { get; }

		bool IsRunning { get; }

		bool IsReconnectionEnabled { get; set; }

		bool IsTextMessageConversionEnabled { get; set; }

		ClientWebSocket? NativeClient { get; }

		Encoding? MessageEncoding { get; set; }

		Task Start();

		Task StartOrFail();

		Task<bool> Stop(WebSocketCloseStatus status, string statusDescription);

		Task<bool> StopOrFail(WebSocketCloseStatus status, string statusDescription);

		bool Send(string message);

		bool Send(byte[] message);

		bool Send(ArraySegment<byte> message);

		Task SendInstant(string message);

		Task SendInstant(byte[] message);

		bool SendAsText(byte[] message);

		bool SendAsText(ArraySegment<byte> message);

		Task Reconnect();

		Task ReconnectOrFail();

		void StreamFakeMessage(ResponseMessage message);
	}
	public class DisconnectionInfo
	{
		public DisconnectionType Type { get; }

		public WebSocketCloseStatus? CloseStatus { get; }

		public string? CloseStatusDescription { get; }

		public string? SubProtocol { get; }

		public Exception? Exception { get; }

		public bool CancelReconnection { get; set; }

		public bool CancelClosing { get; set; }

		public DisconnectionInfo(DisconnectionType type, WebSocketCloseStatus? closeStatus, string? closeStatusDescription, string? subProtocol, Exception? exception)
		{
			Type = type;
			CloseStatus = closeStatus;
			CloseStatusDescription = closeStatusDescription;
			SubProtocol = subProtocol;
			Exception = exception;
		}

		public static DisconnectionInfo Create(DisconnectionType type, WebSocket? client, Exception? exception)
		{
			return new DisconnectionInfo(type, client?.CloseStatus, client?.CloseStatusDescription, client?.SubProtocol, exception);
		}
	}
	public enum DisconnectionType
	{
		Exit,
		Lost,
		NoMessageReceived,
		Error,
		ByUser,
		ByServer
	}
	public class ReconnectionInfo
	{
		public ReconnectionType Type { get; }

		public ReconnectionInfo(ReconnectionType type)
		{
			Type = type;
		}

		public static ReconnectionInfo Create(ReconnectionType type)
		{
			return new ReconnectionInfo(type);
		}
	}
	public enum ReconnectionType
	{
		Initial,
		Lost,
		NoMessageReceived,
		Error,
		ByUser,
		ByServer
	}
	internal abstract class RequestMessage
	{
	}
	internal class RequestTextMessage : RequestMessage
	{
		public string Text { get; }

		public RequestTextMessage(string text)
		{
			Text = text;
		}
	}
	internal class RequestBinaryMessage : RequestMessage
	{
		public byte[] Data { get; }

		public RequestBinaryMessage(byte[] data)
		{
			Data = data;
		}
	}
	internal class RequestBinarySegmentMessage : RequestMessage
	{
		public ArraySegment<byte> Data { get; }

		public RequestBinarySegmentMessage(ArraySegment<byte> data)
		{
			Data = data;
		}
	}
	public class ResponseMessage
	{
		private readonly byte[]? _binary;

		public string? Text { get; }

		public byte[]? Binary
		{
			get
			{
				if (Stream != null)
				{
					return Stream.ToArray();
				}
				return _binary;
			}
		}

		public MemoryStream? Stream { get; }

		public WebSocketMessageType MessageType { get; }

		private ResponseMessage(MemoryStream? memoryStream, byte[]? binary, string? text, WebSocketMessageType messageType)
		{
			Stream = memoryStream;
			_binary = binary;
			Text = text;
			MessageType = messageType;
		}

		public override string ToString()
		{
			if (MessageType == WebSocketMessageType.Text)
			{
				return Text ?? string.Empty;
			}
			return $"Type binary, length: {Binary?.Length}";
		}

		public static ResponseMessage TextMessage(string? data)
		{
			return new ResponseMessage(null, null, data, WebSocketMessageType.Text);
		}

		public static ResponseMessage BinaryMessage(byte[]? data)
		{
			return new ResponseMessage(null, data, null, WebSocketMessageType.Binary);
		}

		public static ResponseMessage BinaryStreamMessage(MemoryStream? memoryStream)
		{
			return new ResponseMessage(memoryStream, null, null, WebSocketMessageType.Binary);
		}
	}
	public class WebsocketClient : IWebsocketClient, IDisposable
	{
		private readonly ILogger<WebsocketClient> _logger;

		private readonly WebsocketAsyncLock _locker = new WebsocketAsyncLock();

		private readonly Func<Uri, CancellationToken, Task<WebSocket>> _connectionFactory;

		private static readonly RecyclableMemoryStreamManager _memoryStreamManager = new RecyclableMemoryStreamManager();

		private Uri _url;

		private Timer? _lastChanceTimer;

		private DateTime _lastReceivedMsg = DateTime.UtcNow;

		private Timer? _errorReconnectTimer;

		private bool _disposing;

		private bool _reconnecting;

		private bool _stopping;

		private bool _isReconnectionEnabled = true;

		private WebSocket? _client;

		private CancellationTokenSource? _cancellation;

		private CancellationTokenSource? _cancellationTotal;

		private readonly Subject<ResponseMessage> _messageReceivedSubject = new Subject<ResponseMessage>();

		private readonly Subject<ReconnectionInfo> _reconnectionSubject = new Subject<ReconnectionInfo>();

		private readonly Subject<DisconnectionInfo> _disconnectedSubject = new Subject<DisconnectionInfo>();

		private readonly Channel<RequestMessage> _messagesTextToSendQueue = Channel.CreateUnbounded<RequestMessage>(new UnboundedChannelOptions
		{
			SingleReader = true,
			SingleWriter = false
		});

		private readonly Channel<ArraySegment<byte>> _messagesBinaryToSendQueue = Channel.CreateUnbounded<ArraySegment<byte>>(new UnboundedChannelOptions
		{
			SingleReader = true,
			SingleWriter = false
		});

		public Uri Url
		{
			get
			{
				return _url;
			}
			set
			{
				Websocket.Client.Validations.Validations.ValidateInput(value, "Url");
				_url = value;
			}
		}

		public IObservable<ResponseMessage> MessageReceived => Observable.AsObservable<ResponseMessage>((IObservable<ResponseMessage>)_messageReceivedSubject);

		public IObservable<ReconnectionInfo> ReconnectionHappened => Observable.AsObservable<ReconnectionInfo>((IObservable<ReconnectionInfo>)_reconnectionSubject);

		public IObservable<DisconnectionInfo> DisconnectionHappened => Observable.AsObservable<DisconnectionInfo>((IObservable<DisconnectionInfo>)_disconnectedSubject);

		public TimeSpan? ReconnectTimeout { get; set; } = TimeSpan.FromMinutes(1.0);


		public TimeSpan? ErrorReconnectTimeout { get; set; } = TimeSpan.FromMinutes(1.0);


		public TimeSpan? LostReconnectTimeout { get; set; }

		public bool IsReconnectionEnabled
		{
			get
			{
				return _isReconnectionEnabled;
			}
			set
			{
				_isReconnectionEnabled = value;
				if (IsStarted)
				{
					if (_isReconnectionEnabled)
					{
						ActivateLastChance();
					}
					else
					{
						DeactivateLastChance();
					}
				}
			}
		}

		public string? Name { get; set; }

		public bool IsStarted { get; private set; }

		public bool IsRunning { get; private set; }

		public bool IsTextMessageConversionEnabled { get; set; } = true;


		public bool IsStreamDisposedAutomatically { get; set; } = true;


		public Encoding? MessageEncoding { get; set; }

		public ClientWebSocket? NativeClient => GetSpecificOrThrow(_client);

		public WebsocketClient(Uri url, Func<ClientWebSocket>? clientFactory = null)
			: this(url, null, GetClientFactory(clientFactory))
		{
		}

		public WebsocketClient(Uri url, ILogger<WebsocketClient>? logger, Func<ClientWebSocket>? clientFactory = null)
			: this(url, logger, GetClientFactory(clientFactory))
		{
		}

		public WebsocketClient(Uri url, ILogger<WebsocketClient>? logger, Func<Uri, CancellationToken, Task<WebSocket>>? connectionFactory)
		{
			Websocket.Client.Validations.Validations.ValidateInput(url, "url");
			_logger = logger ?? NullLogger<WebsocketClient>.Instance;
			_url = url;
			_connectionFactory = connectionFactory ?? ((Func<Uri, CancellationToken, Task<WebSocket>>)async delegate(Uri uri, CancellationToken token)
			{
				ClientWebSocket client = new ClientWebSocket();
				await client.ConnectAsync(uri, token).ConfigureAwait(continueOnCapturedContext: false);
				return client;
			});
		}

		public void Dispose()
		{
			_disposing = true;
			_logger.LogDebug(L("Disposing.."), Name);
			try
			{
				_messagesTextToSendQueue.Writer.Complete();
				_messagesBinaryToSendQueue.Writer.Complete();
				_lastChanceTimer?.Dispose();
				_errorReconnectTimer?.Dispose();
				_cancellation?.Cancel();
				_cancellationTotal?.Cancel();
				_client?.Abort();
				_client?.Dispose();
				_cancellation?.Dispose();
				_cancellationTotal?.Dispose();
				((SubjectBase<ResponseMessage>)(object)_messageReceivedSubject).OnCompleted();
				((SubjectBase<ReconnectionInfo>)(object)_reconnectionSubject).OnCompleted();
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, L("Failed to dispose client, error: {error}"), Name, ex.Message);
			}
			if (IsRunning)
			{
				((SubjectBase<DisconnectionInfo>)(object)_disconnectedSubject).OnNext(DisconnectionInfo.Create(DisconnectionType.Exit, _client, null));
			}
			IsRunning = false;
			IsStarted = false;
			((SubjectBase<DisconnectionInfo>)(object)_disconnectedSubject).OnCompleted();
		}

		public Task Start()
		{
			return StartInternal(failFast: false);
		}

		public Task StartOrFail()
		{
			return StartInternal(failFast: true);
		}

		public async Task<bool> Stop(WebSocketCloseStatus status, string statusDescription)
		{
			bool result = await StopInternal(_client, status, statusDescription, null, failFast: false, byServer: false).ConfigureAwait(continueOnCapturedContext: false);
			((SubjectBase<DisconnectionInfo>)(object)_disconnectedSubject).OnNext(DisconnectionInfo.Create(DisconnectionType.ByUser, _client, null));
			return result;
		}

		public async Task<bool> StopOrFail(WebSocketCloseStatus status, string statusDescription)
		{
			bool result = await StopInternal(_client, status, statusDescription, null, failFast: true, byServer: false).ConfigureAwait(continueOnCapturedContext: false);
			((SubjectBase<DisconnectionInfo>)(object)_disconnectedSubject).OnNext(DisconnectionInfo.Create(DisconnectionType.ByUser, _client, null));
			return result;
		}

		private static Func<Uri, CancellationToken, Task<WebSocket>>? GetClientFactory(Func<ClientWebSocket>? clientFactory)
		{
			Func<ClientWebSocket> clientFactory2 = clientFactory;
			if (clientFactory2 == null)
			{
				return null;
			}
			return async delegate(Uri uri, CancellationToken token)
			{
				ClientWebSocket client = clientFactory2();
				await client.ConnectAsync(uri, token).ConfigureAwait(continueOnCapturedContext: false);
				return client;
			};
		}

		private async Task StartInternal(bool failFast)
		{
			if (_disposing)
			{
				throw new WebsocketException("Client " + Name + " is already disposed, starting not possible");
			}
			if (IsStarted)
			{
				_logger.LogDebug(L("Client already started, ignoring.."), Name);
				return;
			}
			IsStarted = true;
			_logger.LogDebug(L("Starting.."), Name);
			_cancellation = new CancellationTokenSource();
			_cancellationTotal = new CancellationTokenSource();
			await StartClient(_url, _cancellation.Token, ReconnectionType.Initial, failFast).ConfigureAwait(continueOnCapturedContext: false);
			StartBackgroundThreadForSendingText();
			StartBackgroundThreadForSendingBinary();
		}

		private async Task<bool> StopInternal(WebSocket? client, WebSocketCloseStatus status, string statusDescription, CancellationToken? cancellation, bool failFast, bool byServer)
		{
			if (_disposing)
			{
				throw new WebsocketException("Client " + Name + " is already disposed, stopping not possible");
			}
			DeactivateLastChance();
			if (client == null)
			{
				IsStarted = false;
				IsRunning = false;
				return false;
			}
			if (!IsRunning)
			{
				_logger.LogInformation(L("Client is already stopped"), Name);
				IsStarted = false;
				return false;
			}
			bool result = false;
			try
			{
				CancellationToken cancellationToken = cancellation ?? CancellationToken.None;
				_stopping = true;
				if (!byServer)
				{
					await client.CloseAsync(status, statusDescription, cancellationToken);
				}
				else
				{
					await client.CloseOutputAsync(status, statusDescription, cancellationToken);
				}
				result = true;
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, L("Error while stopping client, message: '{error}'"), Name, ex.Message);
				if (failFast)
				{
					throw new WebsocketException("Failed to stop Websocket client " + Name + ", error: '" + ex.Message + "'", ex);
				}
			}
			finally
			{
				IsRunning = false;
				_stopping = false;
				if (!byServer || !IsReconnectionEnabled)
				{
					IsStarted = false;
				}
			}
			return result;
		}

		private async Task StartClient(Uri uri, CancellationToken token, ReconnectionType type, bool failFast)
		{
			DeactivateLastChance();
			try
			{
				_client = await _connectionFactory(uri, token).ConfigureAwait(continueOnCapturedContext: false);
				Listen(_client, token);
				IsRunning = true;
				IsStarted = true;
				((SubjectBase<ReconnectionInfo>)(object)_reconnectionSubject).OnNext(ReconnectionInfo.Create(type));
				_lastReceivedMsg = DateTime.UtcNow;
				ActivateLastChance();
			}
			catch (Exception ex)
			{
				DisconnectionInfo disconnectionInfo = DisconnectionInfo.Create(DisconnectionType.Error, _client, ex);
				((SubjectBase<DisconnectionInfo>)(object)_disconnectedSubject).OnNext(disconnectionInfo);
				if (disconnectionInfo.CancelReconnection)
				{
					_logger.LogError(ex, L("Exception while connecting. Reconnecting canceled by user, exiting. Error: '{error}'"), Name, ex.Message);
					return;
				}
				if (failFast)
				{
					throw new WebsocketException("Failed to start Websocket client " + Name + ", error: '" + ex.Message + "'", ex);
				}
				if (!ErrorReconnectTimeout.HasValue)
				{
					_logger.LogError(ex, L("Exception while connecting. Reconnecting disabled, exiting. Error: '{error}'"), Name, ex.Message);
					return;
				}
				TimeSpan value = ErrorReconnectTimeout.Value;
				_logger.LogError(ex, L("Exception while connecting. Waiting {timeout} sec before next reconnection try. Error: '{error}'"), Name, value.TotalSeconds, ex.Message);
				_errorReconnectTimer?.Dispose();
				_errorReconnectTimer = new Timer(ReconnectOnError, ex, value, Timeout.InfiniteTimeSpan);
			}
		}

		private void ReconnectOnError(object? state)
		{
			Reconnect(ReconnectionType.Error, failFast: false, state as Exception).ConfigureAwait(continueOnCapturedContext: false);
		}

		private bool IsClientConnected()
		{
			WebSocket? client = _client;
			if (client == null)
			{
				return false;
			}
			return client.State == WebSocketState.Open;
		}

		private async Task Listen(WebSocket client, CancellationToken token)
		{
			Exception causedException = null;
			try
			{
				Memory<byte> buffer = new Memory<byte>(new byte[4096]);
				do
				{
					RecyclableMemoryStream ms = _memoryStreamManager.GetStream();
					ValueWebSocketReceiveResult valueWebSocketReceiveResult;
					do
					{
						valueWebSocketReceiveResult = await client.ReceiveAsync(buffer, token);
						((Stream)(object)ms).Write((ReadOnlySpan<byte>)buffer.Slice(0, valueWebSocketReceiveResult.Count).Span);
					}
					while (!valueWebSocketReceiveResult.EndOfMessage);
					((Stream)(object)ms).Seek(0L, SeekOrigin.Begin);
					bool flag = true;
					ResponseMessage responseMessage;
					if (valueWebSocketReceiveResult.MessageType == WebSocketMessageType.Text && IsTextMessageConversionEnabled)
					{
						responseMessage = ResponseMessage.TextMessage(GetEncoding().GetString(((MemoryStream)(object)ms).ToArray()));
					}
					else
					{
						if (valueWebSocketReceiveResult.MessageType == WebSocketMessageType.Close)
						{
							_logger.LogTrace(L("Received close message"), Name);
							if (!IsStarted || _stopping)
							{
								return;
							}
							DisconnectionInfo disconnectionInfo = DisconnectionInfo.Create(DisconnectionType.ByServer, client, null);
							((SubjectBase<DisconnectionInfo>)(object)_disconnectedSubject).OnNext(disconnectionInfo);
							if (disconnectionInfo.CancelClosing)
							{
								if (IsReconnectionEnabled)
								{
									throw new OperationCanceledException("Websocket connection was closed by server (client: " + Name + ")");
								}
								continue;
							}
							await StopInternal(client, WebSocketCloseStatus.NormalClosure, "Closing", token, failFast: false, byServer: true);
							if (IsReconnectionEnabled && !ShouldIgnoreReconnection(client))
							{
								ReconnectSynchronized(ReconnectionType.Lost, failFast: false, null);
							}
							return;
						}
						if (IsStreamDisposedAutomatically)
						{
							responseMessage = ResponseMessage.BinaryMessage(((MemoryStream)(object)ms).ToArray());
						}
						else
						{
							responseMessage = ResponseMessage.BinaryStreamMessage((MemoryStream?)(object)ms);
							flag = false;
						}
					}
					if (flag)
					{
						((Stream)(object)ms).Dispose();
					}
					_logger.LogTrace(L("Received:  {message}"), Name, responseMessage);
					_lastReceivedMsg = DateTime.UtcNow;
					((SubjectBase<ResponseMessage>)(object)_messageReceivedSubject).OnNext(responseMessage);
				}
				while (client.State == WebSocketState.Open && !token.IsCancellationRequested);
			}
			catch (TaskCanceledException ex)
			{
				causedException = ex;
			}
			catch (OperationCanceledException ex2)
			{
				causedException = ex2;
			}
			catch (ObjectDisposedException ex3)
			{
				causedException = ex3;
			}
			catch (Exception ex4)
			{
				_logger.LogError(ex4, L("Error while listening to websocket stream, error: '{error}'"), Name, ex4.Message);
				causedException = ex4;
			}
			if (!ShouldIgnoreReconnection(client) && IsStarted)
			{
				if (LostReconnectTimeout.HasValue)
				{
					TimeSpan value = LostReconnectTimeout.Value;
					_logger.LogWarning(L("Listening websocket stream is lost. Waiting {timeout} sec before next reconnection try."), Name, value.TotalSeconds);
					await Task.Delay(value, token).ConfigureAwait(continueOnCapturedContext: false);
				}
				ReconnectSynchronized(ReconnectionType.Lost, failFast: false, causedException);
			}
		}

		private bool ShouldIgnoreReconnection(WebSocket client)
		{
			bool num = _disposing || _reconnecting || _stopping;
			bool flag = client != _client;
			return num || flag;
		}

		private Encoding GetEncoding()
		{
			if (MessageEncoding == null)
			{
				MessageEncoding = Encoding.UTF8;
			}
			return MessageEncoding;
		}

		private ClientWebSocket? GetSpecificOrThrow(WebSocket? client)
		{
			if (client == null)
			{
				return null;
			}
			return (client as ClientWebSocket) ?? throw new WebsocketException("Cannot cast 'WebSocket' client to 'ClientWebSocket', provide correct type via factory or don't use this property at all.");
		}

		private string L(string msg)
		{
			return "[WEBSOCKET {name}] " + msg;
		}

		private DisconnectionType TranslateTypeToDisconnection(ReconnectionType type)
		{
			return (DisconnectionType)type;
		}

		public Task Reconnect()
		{
			return ReconnectInternal(failFast: false);
		}

		public Task ReconnectOrFail()
		{
			return ReconnectInternal(failFast: true);
		}

		private async Task ReconnectInternal(bool failFast)
		{
			if (!IsStarted)
			{
				_logger.LogDebug(L("Client not started, ignoring reconnection.."), Name);
				return;
			}
			try
			{
				await ReconnectSynchronized(ReconnectionType.ByUser, failFast, null).ConfigureAwait(continueOnCapturedContext: false);
			}
			finally
			{
				_reconnecting = false;
			}
		}

		private async Task ReconnectSynchronized(ReconnectionType type, bool failFast, Exception? causedException)
		{
			using (await _locker.LockAsync())
			{
				await Reconnect(type, failFast, causedException);
			}
		}

		private async Task Reconnect(ReconnectionType type, bool failFast, Exception? causedException)
		{
			IsRunning = false;
			if (_disposing || !IsStarted)
			{
				return;
			}
			_reconnecting = true;
			DisconnectionInfo disconnectionInfo = DisconnectionInfo.Create(TranslateTypeToDisconnection(type), _client, causedException);
			if (type != ReconnectionType.Error)
			{
				((SubjectBase<DisconnectionInfo>)(object)_disconnectedSubject).OnNext(disconnectionInfo);
				if (disconnectionInfo.CancelReconnection)
				{
					_logger.LogInformation(L("Reconnecting canceled by user, exiting."), Name);
				}
			}
			_cancellation?.Cancel();
			try
			{
				_client?.Abort();
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, L("Exception while aborting client. Error: '{error}'"), Name, ex.Message);
			}
			_client?.Dispose();
			if (!IsReconnectionEnabled || disconnectionInfo.CancelReconnection)
			{
				IsStarted = false;
				_reconnecting = false;
				return;
			}
			_logger.LogDebug(L("Reconnecting..."), Name);
			_cancellation = new CancellationTokenSource();
			await StartClient(_url, _cancellation.Token, type, failFast).ConfigureAwait(continueOnCapturedContext: false);
			_reconnecting = false;
		}

		private void ActivateLastChance()
		{
			int num = 1000;
			_lastChanceTimer = new Timer(LastChance, null, num, num);
		}

		private void DeactivateLastChance()
		{
			_lastChanceTimer?.Dispose();
			_lastChanceTimer = null;
		}

		private void LastChance(object? state)
		{
			if (!IsReconnectionEnabled || !ReconnectTimeout.HasValue)
			{
				DeactivateLastChance();
				return;
			}
			double num = Math.Abs(ReconnectTimeout.Value.TotalMilliseconds);
			if (Math.Abs(DateTime.UtcNow.Subtract(_lastReceivedMsg).TotalMilliseconds) > num)
			{
				_logger.LogDebug(L("Last message received more than {timeoutMs} ms ago. Hard restart.."), Name, num.ToString("F"));
				DeactivateLastChance();
				ReconnectSynchronized(ReconnectionType.NoMessageReceived, failFast: false, null);
			}
		}

		public bool Send(string message)
		{
			Websocket.Client.Validations.Validations.ValidateInput(message, "message");
			return _messagesTextToSendQueue.Writer.TryWrite(new RequestTextMessage(message));
		}

		public bool Send(byte[] message)
		{
			Websocket.Client.Validations.Validations.ValidateInput(message, "message");
			return _messagesBinaryToSendQueue.Writer.TryWrite(new ArraySegment<byte>(message));
		}

		public bool Send(ArraySegment<byte> message)
		{
			Websocket.Client.Validations.Validations.ValidateInput(message, "message");
			return _messagesBinaryToSendQueue.Writer.TryWrite(message);
		}

		public Task SendInstant(string message)
		{
			Websocket.Client.Validations.Validations.ValidateInput(message, "message");
			return SendInternalSynchronized(new RequestTextMessage(message));
		}

		public Task SendInstant(byte[] message)
		{
			return SendInternalSynchronized(new ArraySegment<byte>(message));
		}

		public bool SendAsText(byte[] message)
		{
			Websocket.Client.Validations.Validations.ValidateInput(message, "message");
			return _messagesTextToSendQueue.Writer.TryWrite(new RequestBinaryMessage(message));
		}

		public bool SendAsText(ArraySegment<byte> message)
		{
			Websocket.Client.Validations.Validations.ValidateInput(message, "message");
			return _messagesTextToSendQueue.Writer.TryWrite(new RequestBinarySegmentMessage(message));
		}

		public void StreamFakeMessage(ResponseMessage message)
		{
			Websocket.Client.Validations.Validations.ValidateInput(message, "message");
			((SubjectBase<ResponseMessage>)(object)_messageReceivedSubject).OnNext(message);
		}

		private async Task SendTextFromQueue()
		{
			_ = 1;
			try
			{
				while (await _messagesTextToSendQueue.Reader.WaitToReadAsync())
				{
					RequestMessage message;
					while (_messagesTextToSendQueue.Reader.TryRead(out message))
					{
						try
						{
							await SendInternalSynchronized(message).ConfigureAwait(continueOnCapturedContext: false);
						}
						catch (Exception ex)
						{
							_logger.LogError(ex, L("Failed to send text message: '{message}'. Error: {error}"), Name, message, ex.Message);
						}
					}
				}
			}
			catch (TaskCanceledException)
			{
			}
			catch (OperationCanceledException)
			{
			}
			catch (Exception ex4)
			{
				if (!(_cancellationTotal?.IsCancellationRequested ?? false) && !_disposing)
				{
					_logger.LogTrace(L("Sending text thread failed, error: {error}. Creating a new sending thread."), Name, ex4.Message);
					StartBackgroundThreadForSendingText();
				}
			}
		}

		private async Task SendBinaryFromQueue()
		{
			_ = 1;
			try
			{
				while (await _messagesBinaryToSendQueue.Reader.WaitToReadAsync())
				{
					ArraySegment<byte> message;
					while (_messagesBinaryToSendQueue.Reader.TryRead(out message))
					{
						try
						{
							await SendInternalSynchronized(message).ConfigureAwait(continueOnCapturedContext: false);
						}
						catch (Exception ex)
						{
							_logger.LogError(ex, L("Failed to send binary message: '{message}'. Error: {error}"), Name, message, ex.Message);
						}
					}
				}
			}
			catch (TaskCanceledException)
			{
			}
			catch (OperationCanceledException)
			{
			}
			catch (Exception ex4)
			{
				if (!(_cancellationTotal?.IsCancellationRequested ?? false) && !_disposing)
				{
					_logger.LogTrace(L("Sending binary thread failed, error: {error}. Creating a new sending thread."), Name, ex4.Message);
					StartBackgroundThreadForSendingBinary();
				}
			}
		}

		private void StartBackgroundThreadForSendingText()
		{
			Task.Factory.StartNew((object _) => SendTextFromQueue(), TaskCreationOptions.LongRunning, _cancellationTotal?.Token ?? CancellationToken.None);
		}

		private void StartBackgroundThreadForSendingBinary()
		{
			Task.Factory.StartNew((object _) => SendBinaryFromQueue(), TaskCreationOptions.LongRunning, _cancellationTotal?.Token ?? CancellationToken.None);
		}

		private async Task SendInternalSynchronized(RequestMessage message)
		{
			using (await _locker.LockAsync())
			{
				await SendInternal(message);
			}
		}

		private async Task SendInternal(RequestMessage message)
		{
			if (!IsClientConnected())
			{
				_logger.LogDebug(L("Client is not connected to server, cannot send: {message}"), Name, message);
				return;
			}
			_logger.LogTrace(L("Sending: {message}"), Name, message);
			ReadOnlyMemory<byte> buffer;
			if (!(message is RequestTextMessage requestTextMessage))
			{
				if (!(message is RequestBinaryMessage requestBinaryMessage))
				{
					if (!(message is RequestBinarySegmentMessage requestBinarySegmentMessage))
					{
						throw new ArgumentException($"Unknown message type: {message.GetType()}");
					}
					buffer = requestBinarySegmentMessage.Data.AsMemory();
				}
				else
				{
					buffer = MemoryMarshal.AsMemory<byte>(requestBinaryMessage.Data);
				}
			}
			else
			{
				buffer = MemoryMarshal.AsMemory<byte>(GetEncoding().GetBytes(requestTextMessage.Text));
			}
			await _client.SendAsync(buffer, WebSocketMessageType.Text, endOfMessage: true, _cancellation?.Token ?? CancellationToken.None).ConfigureAwait(continueOnCapturedContext: false);
		}

		private async Task SendInternalSynchronized(ArraySegment<byte> message)
		{
			using (await _locker.LockAsync())
			{
				await SendInternal(message);
			}
		}

		private async Task SendInternal(ArraySegment<byte> payload)
		{
			if (!IsClientConnected())
			{
				_logger.LogDebug(L("Client is not connected to server, cannot send binary, length: {length}"), Name, payload.Count);
			}
			else
			{
				_logger.LogTrace(L("Sending binary, length: {length}"), Name, payload.Count);
				await _client.SendAsync(payload, WebSocketMessageType.Binary, endOfMessage: true, _cancellation?.Token ?? CancellationToken.None).ConfigureAwait(continueOnCapturedContext: false);
			}
		}
	}
}
namespace Websocket.Client.Validations
{
	internal static class Validations
	{
		public static void ValidateInput(string value, string name)
		{
			if (string.IsNullOrEmpty(value))
			{
				throw new WebsocketBadInputException("Input string parameter '" + name + "' is null or empty. Please correct it.");
			}
		}

		public static void ValidateInput<T>(T value, string name)
		{
			if (object.Equals(value, default(T)))
			{
				throw new WebsocketBadInputException("Input parameter '" + name + "' is null. Please correct it.");
			}
		}

		public static void ValidateInputCollection<T>(IEnumerable<T> collection, string name)
		{
			ValidateInput(collection, name);
			if (!collection.Any())
			{
				throw new WebsocketBadInputException("Input collection '" + name + "' is empty. Please correct it.");
			}
		}

		public static void ValidateInput(int value, string name, int minValue = int.MinValue, int maxValue = int.MaxValue)
		{
			if (value < minValue)
			{
				throw new WebsocketBadInputException($"Input parameter '{name}' is lower than {minValue}. Please correct it.");
			}
			if (value > maxValue)
			{
				throw new WebsocketBadInputException($"Input parameter '{name}' is higher than {maxValue}. Please correct it.");
			}
		}

		public static void ValidateInput(long value, string name, long minValue = long.MinValue, long maxValue = long.MaxValue)
		{
			if (value < minValue)
			{
				throw new WebsocketBadInputException($"Input parameter '{name}' is lower than {minValue}. Please correct it.");
			}
			if (value > maxValue)
			{
				throw new WebsocketBadInputException($"Input parameter '{name}' is higher than {maxValue}. Please correct it.");
			}
		}

		public static void ValidateInput(double value, string name, double minValue = double.MinValue, double maxValue = double.MaxValue)
		{
			if (value < minValue)
			{
				throw new WebsocketBadInputException($"Input parameter '{name}' is lower than {minValue}. Please correct it.");
			}
			if (value > maxValue)
			{
				throw new WebsocketBadInputException($"Input parameter '{name}' is higher than {maxValue}. Please correct it.");
			}
		}
	}
}
namespace Websocket.Client.Threading
{
	public class WebsocketAsyncLock
	{
		private class Releaser : IDisposable
		{
			private readonly SemaphoreSlim _semaphore;

			public Releaser(SemaphoreSlim semaphore)
			{
				_semaphore = semaphore;
			}

			public void Dispose()
			{
				_semaphore.Release();
			}
		}

		private readonly Task<IDisposable> _releaserTask;

		private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);

		private readonly IDisposable _releaser;

		public WebsocketAsyncLock()
		{
			_releaser = new Releaser(_semaphore);
			_releaserTask = Task.FromResult(_releaser);
		}

		public IDisposable Lock()
		{
			_semaphore.Wait();
			return _releaser;
		}

		public Task<IDisposable> LockAsync()
		{
			Task task = _semaphore.WaitAsync();
			if (!task.IsCompleted)
			{
				return task.ContinueWith((Task _, object releaser) => (IDisposable)releaser, _releaser, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
			}
			return _releaserTask;
		}
	}
}
namespace Websocket.Client.Exceptions
{
	public class WebsocketBadInputException : WebsocketException
	{
		public WebsocketBadInputException()
		{
		}

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

		public WebsocketBadInputException(string message, Exception innerException)
			: base(message, innerException)
		{
		}
	}
	public class WebsocketException : Exception
	{
		public WebsocketException()
		{
		}

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

		public WebsocketException(string message, Exception innerException)
			: base(message, innerException)
		{
		}
	}
}

Mods/RealRadio/YoutubeDLSharp.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using YoutubeDLSharp.Converters;
using YoutubeDLSharp.Helpers;
using YoutubeDLSharp.Metadata;
using YoutubeDLSharp.Options;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("Bluegrams")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("© 2020-2025 Bluegrams")]
[assembly: AssemblyDescription("\r\n\t\tA simple .NET wrapper library for youtube-dl and yt-dlp.\r\n\r\nNote: Package versions >= 1.0 are optimized to work with yt-dlp.\r\nPackage versions 0.x retain support for the original youtube-dl.\r\n\t")]
[assembly: AssemblyFileVersion("1.1.2.25113")]
[assembly: AssemblyInformationalVersion("1.1.2+278031d4e0ac90b92bd8b5860e5bf26e777afe14")]
[assembly: AssemblyProduct("YoutubeDLSharp")]
[assembly: AssemblyTitle("YoutubeDLSharp")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Bluegrams/YoutubeDLSharp")]
[assembly: AssemblyVersion("1.1.2.25113")]
namespace YoutubeDLSharp
{
	public enum DownloadState
	{
		None,
		PreProcessing,
		Downloading,
		PostProcessing,
		Error,
		Success
	}
	public class DownloadProgress
	{
		public DownloadState State { get; }

		public float Progress { get; }

		public string TotalDownloadSize { get; }

		public string DownloadSpeed { get; }

		public string ETA { get; }

		public int VideoIndex { get; }

		public string Data { get; }

		public DownloadProgress(DownloadState status, float progress = 0f, string totalDownloadSize = null, string downloadSpeed = null, string eta = null, int index = 1, string data = null)
		{
			State = status;
			Progress = progress;
			TotalDownloadSize = totalDownloadSize;
			DownloadSpeed = downloadSpeed;
			ETA = eta;
			VideoIndex = index;
			Data = data;
		}
	}
	public class RunResult<T>
	{
		public bool Success { get; }

		public string[] ErrorOutput { get; }

		public T Data { get; }

		public RunResult(bool success, string[] error, T result)
		{
			Success = success;
			ErrorOutput = error;
			Data = result;
		}
	}
	public static class Utils
	{
		internal class FFmpegApi
		{
			public class Root
			{
				[JsonProperty("version")]
				public string Version { get; set; }

				[JsonProperty("permalink")]
				public string Permalink { get; set; }

				[JsonProperty("bin")]
				public Bin Bin { get; set; }
			}

			public class Bin
			{
				[JsonProperty("windows-64")]
				public OsBinVersion Windows64 { get; set; }

				[JsonProperty("linux-64")]
				public OsBinVersion Linux64 { get; set; }

				[JsonProperty("osx-64")]
				public OsBinVersion Osx64 { get; set; }
			}

			public class OsBinVersion
			{
				[JsonProperty("ffmpeg")]
				public string Ffmpeg { get; set; }

				[JsonProperty("ffprobe")]
				public string Ffprobe { get; set; }
			}

			public enum BinaryType
			{
				[EnumMember(Value = "ffmpeg")]
				FFmpeg,
				[EnumMember(Value = "ffprobe")]
				FFprobe
			}
		}

		private static readonly HttpClient _client = new HttpClient();

		private static readonly Regex rgxTimestamp = new Regex("[0-9]+(?::[0-9]+)+", RegexOptions.Compiled);

		private static readonly Dictionary<char, string> accentChars = "ÂÃÄÀÁÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖŐØŒÙÚÛÜŰÝÞßàáâãäåæçèéêëìíîïðñòóôõöőøœùúûüűýþÿ".Zip(new string[68]
		{
			"A", "A", "A", "A", "A", "A", "AE", "C", "E", "E",
			"E", "E", "I", "I", "I", "I", "D", "N", "O", "O",
			"O", "O", "O", "O", "O", "OE", "U", "U", "U", "U",
			"U", "Y", "P", "ss", "a", "a", "a", "a", "a", "a",
			"ae", "c", "e", "e", "e", "e", "i", "i", "i", "i",
			"o", "n", "o", "o", "o", "o", "o", "o", "o", "oe",
			"u", "u", "u", "u", "u", "y", "p", "y"
		}, (char c, string s) => new
		{
			Key = c,
			Val = s
		}).ToDictionary(o => o.Key, o => o.Val);

		public static string YtDlpBinaryName => GetYtDlpBinaryName();

		public static string FfmpegBinaryName => GetFfmpegBinaryName();

		public static string FfprobeBinaryName => GetFfprobeBinaryName();

		public static string Sanitize(string s, bool restricted = false)
		{
			rgxTimestamp.Replace(s, (Match m) => m.Groups[0].Value.Replace(':', '_'));
			string text = string.Join("", s.Select((char c) => sanitizeChar(c, restricted)));
			text = text.Replace("__", "_").Trim(new char[1] { '_' });
			if (restricted && text.StartsWith("-_"))
			{
				text = text.Substring(2);
			}
			if (text.StartsWith("-"))
			{
				text = "_" + text.Substring(1);
			}
			text = text.TrimStart(new char[1] { '.' });
			if (string.IsNullOrWhiteSpace(text))
			{
				text = "_";
			}
			return text;
		}

		private static string sanitizeChar(char c, bool restricted)
		{
			if (restricted && accentChars.ContainsKey(c))
			{
				return accentChars[c];
			}
			if (c != '?' && c >= ' ')
			{
				switch (c)
				{
				case '\u007f':
					break;
				case '"':
					if (!restricted)
					{
						return "'";
					}
					return "";
				case ':':
					if (!restricted)
					{
						return " -";
					}
					return "_-";
				default:
					if (Enumerable.Contains("\\/|*<>", c))
					{
						return "_";
					}
					if (restricted && Enumerable.Contains("!&'()[]{}$;`^,# ", c))
					{
						return "_";
					}
					if (restricted && c > '\u007f')
					{
						return "_";
					}
					return c.ToString();
				}
			}
			return "";
		}

		public static string GetFullPath(string fileName)
		{
			if (File.Exists(fileName))
			{
				return Path.GetFullPath(fileName);
			}
			string[] array = Environment.GetEnvironmentVariable("PATH").Split(new char[1] { Path.PathSeparator });
			for (int i = 0; i < array.Length; i++)
			{
				string text = Path.Combine(array[i], fileName);
				if (File.Exists(text))
				{
					return text;
				}
			}
			return null;
		}

		public static async Task DownloadBinaries(bool skipExisting = true, string directoryPath = "")
		{
			if (skipExisting)
			{
				if (!File.Exists(Path.Combine(directoryPath, GetYtDlpBinaryName())))
				{
					await DownloadYtDlp(directoryPath);
				}
				if (!File.Exists(Path.Combine(directoryPath, GetFfmpegBinaryName())))
				{
					await DownloadFFmpeg(directoryPath);
				}
				if (!File.Exists(Path.Combine(directoryPath, GetFfprobeBinaryName())))
				{
					await DownloadFFprobe(directoryPath);
				}
			}
			else
			{
				await DownloadYtDlp(directoryPath);
				await DownloadFFmpeg(directoryPath);
				await DownloadFFprobe(directoryPath);
			}
		}

		private static string GetYtDlpDownloadUrl()
		{
			return OSHelper.GetOSVersion() switch
			{
				OSVersion.Windows => "https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp.exe", 
				OSVersion.OSX => "https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_macos", 
				OSVersion.Linux => "https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp", 
				_ => throw new Exception("Your OS isn't supported"), 
			};
		}

		private static string GetYtDlpBinaryName()
		{
			return Path.GetFileName(GetYtDlpDownloadUrl());
		}

		private static string GetFfmpegBinaryName()
		{
			switch (OSHelper.GetOSVersion())
			{
			case OSVersion.Windows:
				return "ffmpeg.exe";
			case OSVersion.OSX:
			case OSVersion.Linux:
				return "ffmpeg";
			default:
				throw new Exception("Your OS isn't supported");
			}
		}

		private static string GetFfprobeBinaryName()
		{
			switch (OSHelper.GetOSVersion())
			{
			case OSVersion.Windows:
				return "ffprobe.exe";
			case OSVersion.OSX:
			case OSVersion.Linux:
				return "ffprobe";
			default:
				throw new Exception("Your OS isn't supported");
			}
		}

		public static async Task DownloadYtDlp(string directoryPath = "")
		{
			string ytDlpDownloadUrl = GetYtDlpDownloadUrl();
			if (string.IsNullOrEmpty(directoryPath))
			{
				directoryPath = Directory.GetCurrentDirectory();
			}
			string downloadLocation = Path.Combine(directoryPath, Path.GetFileName(ytDlpDownloadUrl));
			File.WriteAllBytes(downloadLocation, await DownloadFileBytesAsync(ytDlpDownloadUrl));
		}

		public static async Task DownloadFFmpeg(string directoryPath = "")
		{
			await FFDownloader(directoryPath);
		}

		public static async Task DownloadFFprobe(string directoryPath = "")
		{
			await FFDownloader(directoryPath, FFmpegApi.BinaryType.FFprobe);
		}

		private static async Task FFDownloader(string directoryPath = "", FFmpegApi.BinaryType binary = FFmpegApi.BinaryType.FFmpeg)
		{
			if (string.IsNullOrEmpty(directoryPath))
			{
				directoryPath = Directory.GetCurrentDirectory();
			}
			FFmpegApi.Root root = JsonConvert.DeserializeObject<FFmpegApi.Root>(await (await _client.GetAsync("https://ffbinaries.com/api/v1/version/latest")).Content.ReadAsStringAsync());
			FFmpegApi.OsBinVersion osBinVersion = OSHelper.GetOSVersion() switch
			{
				OSVersion.Windows => root?.Bin.Windows64, 
				OSVersion.OSX => root?.Bin.Osx64, 
				OSVersion.Linux => root?.Bin.Linux64, 
				_ => throw new NotImplementedException("Your OS isn't supported"), 
			};
			using MemoryStream stream = new MemoryStream(await DownloadFileBytesAsync((binary == FFmpegApi.BinaryType.FFmpeg) ? osBinVersion.Ffmpeg : osBinVersion.Ffprobe));
			using ZipArchive zipArchive = new ZipArchive(stream, ZipArchiveMode.Read);
			if (zipArchive.Entries.Count > 0)
			{
				zipArchive.Entries[0].ExtractToFile(Path.Combine(directoryPath, zipArchive.Entries[0].FullName), overwrite: true);
			}
		}

		private static async Task<byte[]> DownloadFileBytesAsync(string uri)
		{
			if (!Uri.TryCreate(uri, UriKind.Absolute, out Uri _))
			{
				throw new InvalidOperationException("URI is invalid.");
			}
			return await _client.GetByteArrayAsync(uri);
		}

		public static void EnsureSuccess<T>(this RunResult<T> runResult)
		{
			if (!runResult.Success)
			{
				throw new Exception("Download failed:\n" + string.Join("\n", runResult.ErrorOutput));
			}
		}
	}
	public class YoutubeDL
	{
		private static readonly Regex rgxFile = new Regex("^outfile:\\s\\\"?(.*)\\\"?", RegexOptions.Compiled);

		private static Regex rgxFilePostProc = new Regex("\\[download\\] Destination: [a-zA-Z]:\\\\\\S+\\.\\S{3,}", RegexOptions.Compiled);

		protected ProcessRunner runner;

		public string YoutubeDLPath { get; set; } = Utils.YtDlpBinaryName;


		public string FFmpegPath { get; set; } = Utils.FfmpegBinaryName;


		public string OutputFolder { get; set; } = Environment.CurrentDirectory;


		public string OutputFileTemplate { get; set; } = "%(title)s [%(id)s].%(ext)s";


		public bool RestrictFilenames { get; set; }

		public bool OverwriteFiles { get; set; } = true;


		public bool IgnoreDownloadErrors { get; set; } = true;


		public string PythonInterpreterPath { get; set; }

		public string Version => FileVersionInfo.GetVersionInfo(Utils.GetFullPath(YoutubeDLPath)).FileVersion;

		public YoutubeDL(byte maxNumberOfProcesses = 4)
		{
			runner = new ProcessRunner(maxNumberOfProcesses);
		}

		public async Task SetMaxNumberOfProcesses(byte count)
		{
			await runner.SetTotalCount(count);
		}

		public async Task<RunResult<string[]>> RunWithOptions(string[] urls, OptionSet options, CancellationToken ct)
		{
			List<string> output = new List<string>();
			YoutubeDLProcess youtubeDLProcess = CreateYoutubeDLProcess();
			youtubeDLProcess.OutputReceived += delegate(object o, DataReceivedEventArgs e)
			{
				output.Add(e.Data);
			};
			var (num, error) = await runner.RunThrottled(youtubeDLProcess, urls, options, ct);
			return new RunResult<string[]>(num == 0, error, output.ToArray());
		}

		public async Task<RunResult<string>> RunWithOptions(string url, OptionSet options, CancellationToken ct = default(CancellationToken), IProgress<DownloadProgress> progress = null, IProgress<string> output = null, bool showArgs = true)
		{
			string outFile = string.Empty;
			YoutubeDLProcess youtubeDLProcess = CreateYoutubeDLProcess();
			if (showArgs)
			{
				output?.Report("Arguments: " + youtubeDLProcess.ConvertToArgs(new string[1] { url }, options) + "\n");
			}
			else
			{
				output?.Report("Starting Download: " + url);
			}
			youtubeDLProcess.OutputReceived += delegate(object o, DataReceivedEventArgs e)
			{
				Match match = rgxFilePostProc.Match(e.Data);
				if (match.Success)
				{
					outFile = match.Groups[0].ToString().Replace("[download] Destination:", "").Replace(" ", "");
					progress?.Report(new DownloadProgress(DownloadState.Success, 0f, null, null, null, 1, outFile));
				}
				output?.Report(e.Data);
			};
			var (num, error) = await runner.RunThrottled(youtubeDLProcess, new string[1] { url }, options, ct, progress);
			return new RunResult<string>(num == 0, error, outFile);
		}

		public async Task<string> RunUpdate()
		{
			string output = string.Empty;
			YoutubeDLProcess youtubeDLProcess = CreateYoutubeDLProcess();
			youtubeDLProcess.OutputReceived += delegate(object o, DataReceivedEventArgs e)
			{
				output = e.Data;
			};
			await youtubeDLProcess.RunAsync(null, new OptionSet
			{
				Update = true
			});
			return output;
		}

		public async Task<RunResult<VideoData>> RunVideoDataFetch(string url, CancellationToken ct = default(CancellationToken), bool flat = true, bool fetchComments = false, OptionSet overrideOptions = null)
		{
			OptionSet optionSet = GetDownloadOptions();
			optionSet.DumpSingleJson = true;
			optionSet.FlatPlaylist = flat;
			optionSet.WriteComments = fetchComments;
			if (overrideOptions != null)
			{
				optionSet = optionSet.OverrideOptions(overrideOptions);
			}
			VideoData videoData = null;
			YoutubeDLProcess process = CreateYoutubeDLProcess();
			process.OutputReceived += delegate(object o, DataReceivedEventArgs e)
			{
				try
				{
					videoData = JsonConvert.DeserializeObject<VideoData>(e.Data);
				}
				catch (JsonSerializationException)
				{
					process.RedirectToError(e);
				}
			};
			var (num, error) = await runner.RunThrottled(process, new string[1] { url }, optionSet, ct);
			return new RunResult<VideoData>(num == 0, error, videoData);
		}

		public async Task<RunResult<string>> RunVideoDownload(string url, string format = "bestvideo+bestaudio/best", DownloadMergeFormat mergeFormat = DownloadMergeFormat.Unspecified, VideoRecodeFormat recodeFormat = VideoRecodeFormat.None, CancellationToken ct = default(CancellationToken), IProgress<DownloadProgress> progress = null, IProgress<string> output = null, OptionSet overrideOptions = null)
		{
			OptionSet optionSet = GetDownloadOptions();
			optionSet.Format = format;
			optionSet.MergeOutputFormat = mergeFormat;
			optionSet.RecodeVideo = recodeFormat;
			if (overrideOptions != null)
			{
				optionSet = optionSet.OverrideOptions(overrideOptions);
			}
			string outputFile = string.Empty;
			YoutubeDLProcess youtubeDLProcess = CreateYoutubeDLProcess();
			output?.Report("Arguments: " + youtubeDLProcess.ConvertToArgs(new string[1] { url }, optionSet) + "\n");
			youtubeDLProcess.OutputReceived += delegate(object o, DataReceivedEventArgs e)
			{
				Match match = rgxFile.Match(e.Data);
				if (match.Success)
				{
					outputFile = match.Groups[1].ToString().Trim(new char[1] { '"' });
					progress?.Report(new DownloadProgress(DownloadState.Success, 0f, null, null, null, 1, outputFile));
				}
				output?.Report(e.Data);
			};
			var (num, error) = await runner.RunThrottled(youtubeDLProcess, new string[1] { url }, optionSet, ct, progress);
			return new RunResult<string>(num == 0, error, outputFile);
		}

		public async Task<RunResult<string[]>> RunVideoPlaylistDownload(string url, int? start = 1, int? end = null, int[] items = null, string format = "bestvideo+bestaudio/best", VideoRecodeFormat recodeFormat = VideoRecodeFormat.None, CancellationToken ct = default(CancellationToken), IProgress<DownloadProgress> progress = null, IProgress<string> output = null, OptionSet overrideOptions = null)
		{
			OptionSet optionSet = GetDownloadOptions();
			optionSet.NoPlaylist = false;
			optionSet.PlaylistStart = start;
			optionSet.PlaylistEnd = end;
			if (items != null)
			{
				optionSet.PlaylistItems = string.Join(",", items);
			}
			optionSet.Format = format;
			optionSet.RecodeVideo = recodeFormat;
			if (overrideOptions != null)
			{
				optionSet = optionSet.OverrideOptions(overrideOptions);
			}
			List<string> outputFiles = new List<string>();
			YoutubeDLProcess youtubeDLProcess = CreateYoutubeDLProcess();
			output?.Report("Arguments: " + youtubeDLProcess.ConvertToArgs(new string[1] { url }, optionSet) + "\n");
			youtubeDLProcess.OutputReceived += delegate(object o, DataReceivedEventArgs e)
			{
				Match match = rgxFile.Match(e.Data);
				if (match.Success)
				{
					string text = match.Groups[1].ToString().Trim(new char[1] { '"' });
					outputFiles.Add(text);
					progress?.Report(new DownloadProgress(DownloadState.Success, 0f, null, null, null, 1, text));
				}
				output?.Report(e.Data);
			};
			var (num, error) = await runner.RunThrottled(youtubeDLProcess, new string[1] { url }, optionSet, ct, progress);
			return new RunResult<string[]>(num == 0, error, outputFiles.ToArray());
		}

		public async Task<RunResult<string>> RunAudioDownload(string url, AudioConversionFormat format = AudioConversionFormat.Best, CancellationToken ct = default(CancellationToken), IProgress<DownloadProgress> progress = null, IProgress<string> output = null, OptionSet overrideOptions = null)
		{
			OptionSet optionSet = GetDownloadOptions();
			optionSet.Format = "bestaudio/best";
			optionSet.ExtractAudio = true;
			optionSet.AudioFormat = format;
			if (overrideOptions != null)
			{
				optionSet = optionSet.OverrideOptions(overrideOptions);
			}
			string outputFile = string.Empty;
			new List<string>();
			YoutubeDLProcess youtubeDLProcess = CreateYoutubeDLProcess();
			output?.Report("Arguments: " + youtubeDLProcess.ConvertToArgs(new string[1] { url }, optionSet) + "\n");
			youtubeDLProcess.OutputReceived += delegate(object o, DataReceivedEventArgs e)
			{
				Match match = rgxFile.Match(e.Data);
				if (match.Success)
				{
					outputFile = match.Groups[1].ToString().Trim(new char[1] { '"' });
					progress?.Report(new DownloadProgress(DownloadState.Success, 0f, null, null, null, 1, outputFile));
				}
				output?.Report(e.Data);
			};
			var (num, error) = await runner.RunThrottled(youtubeDLProcess, new string[1] { url }, optionSet, ct, progress);
			return new RunResult<string>(num == 0, error, outputFile);
		}

		public async Task<RunResult<string[]>> RunAudioPlaylistDownload(string url, int? start = 1, int? end = null, int[] items = null, AudioConversionFormat format = AudioConversionFormat.Best, CancellationToken ct = default(CancellationToken), IProgress<DownloadProgress> progress = null, IProgress<string> output = null, OptionSet overrideOptions = null)
		{
			List<string> outputFiles = new List<string>();
			OptionSet optionSet = GetDownloadOptions();
			optionSet.NoPlaylist = false;
			optionSet.PlaylistStart = start;
			optionSet.PlaylistEnd = end;
			if (items != null)
			{
				optionSet.PlaylistItems = string.Join(",", items);
			}
			optionSet.Format = "bestaudio/best";
			optionSet.ExtractAudio = true;
			optionSet.AudioFormat = format;
			if (overrideOptions != null)
			{
				optionSet = optionSet.OverrideOptions(overrideOptions);
			}
			YoutubeDLProcess youtubeDLProcess = CreateYoutubeDLProcess();
			output?.Report("Arguments: " + youtubeDLProcess.ConvertToArgs(new string[1] { url }, optionSet) + "\n");
			youtubeDLProcess.OutputReceived += delegate(object o, DataReceivedEventArgs e)
			{
				Match match = rgxFile.Match(e.Data);
				if (match.Success)
				{
					string text = match.Groups[1].ToString().Trim(new char[1] { '"' });
					outputFiles.Add(text);
					progress?.Report(new DownloadProgress(DownloadState.Success, 0f, null, null, null, 1, text));
				}
				output?.Report(e.Data);
			};
			var (num, error) = await runner.RunThrottled(youtubeDLProcess, new string[1] { url }, optionSet, ct, progress);
			return new RunResult<string[]>(num == 0, error, outputFiles.ToArray());
		}

		protected virtual OptionSet GetDownloadOptions()
		{
			return new OptionSet
			{
				IgnoreErrors = IgnoreDownloadErrors,
				IgnoreConfig = true,
				NoPlaylist = true,
				Downloader = "m3u8:native",
				DownloaderArgs = "ffmpeg:-nostats -loglevel 0",
				Output = Path.Combine(OutputFolder, OutputFileTemplate),
				RestrictFilenames = RestrictFilenames,
				ForceOverwrites = OverwriteFiles,
				NoOverwrites = !OverwriteFiles,
				NoPart = true,
				FfmpegLocation = Utils.GetFullPath(FFmpegPath),
				Print = "after_move:outfile: %(filepath)s"
			};
		}

		private YoutubeDLProcess CreateYoutubeDLProcess()
		{
			return new YoutubeDLProcess(YoutubeDLPath)
			{
				PythonPath = PythonInterpreterPath
			};
		}
	}
	public class YoutubeDLProcess
	{
		private static readonly Regex rgxPlaylist = new Regex("Downloading video (\\d+) of (\\d+)", RegexOptions.Compiled);

		private static readonly Regex rgxProgress = new Regex("\\[download\\]\\s+(?:(?<percent>[\\d\\.]+)%(?:\\s+of\\s+\\~?\\s*(?<total>[\\d\\.\\w]+))?\\s+at\\s+(?:(?<speed>[\\d\\.\\w]+\\/s)|[\\w\\s]+)\\s+ETA\\s(?<eta>[\\d\\:]+))?", RegexOptions.Compiled);

		private static readonly Regex rgxPost = new Regex("\\[(\\w+)\\]\\s+", RegexOptions.Compiled);

		public string PythonPath { get; set; }

		public string ExecutablePath { get; set; }

		public event EventHandler<DataReceivedEventArgs> OutputReceived;

		public event EventHandler<DataReceivedEventArgs> ErrorReceived;

		public YoutubeDLProcess(string executablePath = "yt-dlp.exe")
		{
			ExecutablePath = executablePath;
		}

		internal string ConvertToArgs(string[] urls, OptionSet options)
		{
			return options.ToString() + " -- " + ((urls != null) ? string.Join(" ", urls.Select((string s) => "\"" + s + "\"")) : string.Empty);
		}

		internal void RedirectToError(DataReceivedEventArgs e)
		{
			this.ErrorReceived?.Invoke(this, e);
		}

		public async Task<int> RunAsync(string[] urls, OptionSet options)
		{
			return await RunAsync(urls, options, CancellationToken.None);
		}

		public async Task<int> RunAsync(string[] urls, OptionSet options, CancellationToken ct, IProgress<DownloadProgress> progress = null)
		{
			TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
			Process process = new Process();
			ProcessStartInfo processStartInfo = new ProcessStartInfo
			{
				CreateNoWindow = true,
				UseShellExecute = false,
				RedirectStandardOutput = true,
				RedirectStandardError = true,
				StandardOutputEncoding = Encoding.UTF8,
				StandardErrorEncoding = Encoding.UTF8
			};
			if (!string.IsNullOrEmpty(PythonPath))
			{
				processStartInfo.FileName = PythonPath;
				processStartInfo.Arguments = "\"" + ExecutablePath + "\" " + ConvertToArgs(urls, options);
			}
			else
			{
				processStartInfo.FileName = ExecutablePath;
				processStartInfo.Arguments = ConvertToArgs(urls, options);
			}
			process.EnableRaisingEvents = true;
			process.StartInfo = processStartInfo;
			TaskCompletionSource<bool> tcsOut = new TaskCompletionSource<bool>();
			bool isDownloading = false;
			process.OutputDataReceived += delegate(object o, DataReceivedEventArgs e)
			{
				if (e.Data == null)
				{
					tcsOut.SetResult(result: true);
				}
				else
				{
					Match match;
					if ((match = rgxProgress.Match(e.Data)).Success)
					{
						if (match.Groups.Count > 1 && match.Groups[1].Length > 0)
						{
							float progress2 = float.Parse(match.Groups[1].ToString(), CultureInfo.InvariantCulture) / 100f;
							Group group = match.Groups["total"];
							string totalDownloadSize = (group.Success ? group.Value : null);
							Group group2 = match.Groups["speed"];
							string downloadSpeed = (group2.Success ? group2.Value : null);
							Group group3 = match.Groups["eta"];
							string eta = (group3.Success ? group3.Value : null);
							progress?.Report(new DownloadProgress(DownloadState.Downloading, progress2, totalDownloadSize, downloadSpeed, eta));
						}
						else
						{
							progress?.Report(new DownloadProgress(DownloadState.Downloading));
						}
						isDownloading = true;
					}
					else if ((match = rgxPlaylist.Match(e.Data)).Success)
					{
						int index = int.Parse(match.Groups[1].Value);
						progress?.Report(new DownloadProgress(DownloadState.PreProcessing, 0f, null, null, null, index));
						isDownloading = false;
					}
					else if (isDownloading && (match = rgxPost.Match(e.Data)).Success)
					{
						progress?.Report(new DownloadProgress(DownloadState.PostProcessing, 1f));
						isDownloading = false;
					}
					this.OutputReceived?.Invoke(this, e);
				}
			};
			TaskCompletionSource<bool> tcsError = new TaskCompletionSource<bool>();
			process.ErrorDataReceived += delegate(object o, DataReceivedEventArgs e)
			{
				if (e.Data == null)
				{
					tcsError.SetResult(result: true);
				}
				else
				{
					progress?.Report(new DownloadProgress(DownloadState.Error, 0f, null, null, null, 1, e.Data));
					this.ErrorReceived?.Invoke(this, e);
				}
			};
			process.Exited += async delegate
			{
				await tcsOut.Task;
				await tcsError.Task;
				tcs.TrySetResult(process.ExitCode);
				process.Dispose();
			};
			ct.Register(delegate
			{
				if (!tcs.Task.IsCompleted)
				{
					tcs.TrySetCanceled();
				}
				try
				{
					if (!process.HasExited)
					{
						process.KillTree();
					}
				}
				catch
				{
				}
			});
			if (!(await Task.Run(() => process.Start())))
			{
				tcs.TrySetException(new InvalidOperationException("Failed to start yt-dlp process."));
			}
			process.BeginOutputReadLine();
			process.BeginErrorReadLine();
			progress?.Report(new DownloadProgress(DownloadState.PreProcessing));
			return await tcs.Task;
		}
	}
}
namespace YoutubeDLSharp.Options
{
	public enum DownloadMergeFormat
	{
		Unspecified,
		Mp4,
		Mkv,
		Ogg,
		Webm,
		Flv
	}
	public enum AudioConversionFormat
	{
		Best,
		Aac,
		Flac,
		Mp3,
		M4a,
		Opus,
		Vorbis,
		Wav
	}
	public enum VideoRecodeFormat
	{
		None,
		Mp4,
		Mkv,
		Ogg,
		Webm,
		Flv,
		Avi
	}
	public interface IOption
	{
		string DefaultOptionString { get; }

		string[] OptionStrings { get; }

		bool IsSet { get; }

		bool IsCustom { get; }

		void SetFromString(string s);

		IEnumerable<string> ToStringCollection();
	}
	public class MultiOption<T> : IOption
	{
		private MultiValue<T> value;

		public string DefaultOptionString => OptionStrings.Last();

		public string[] OptionStrings { get; }

		public bool IsSet { get; private set; }

		public bool IsCustom { get; }

		public MultiValue<T> Value
		{
			get
			{
				return value;
			}
			set
			{
				IsSet = !object.Equals(value, default(T));
				this.value = value;
			}
		}

		public MultiOption(params string[] optionStrings)
		{
			OptionStrings = optionStrings;
			IsSet = false;
		}

		public MultiOption(bool isCustom, params string[] optionStrings)
		{
			OptionStrings = optionStrings;
			IsSet = false;
			IsCustom = isCustom;
		}

		public void SetFromString(string s)
		{
			string[] array = s.Split(new char[1] { ' ' });
			string stringValue = s.Substring(array[0].Length).Trim().Trim(new char[1] { '"' });
			if (!OptionStrings.Contains(array[0]))
			{
				throw new ArgumentException("Given string does not match required format.");
			}
			T val = Utils.OptionValueFromString<T>(stringValue);
			if (!IsSet)
			{
				Value = val;
			}
			else
			{
				Value.Values.Add(val);
			}
		}

		public override string ToString()
		{
			return string.Join(" ", ToStringCollection());
		}

		public IEnumerable<string> ToStringCollection()
		{
			if (!IsSet)
			{
				return new string[1] { "" };
			}
			List<string> list = new List<string>();
			foreach (T value in Value.Values)
			{
				list.Add(DefaultOptionString + Utils.OptionValueToString(value));
			}
			return list;
		}
	}
	public class MultiValue<T>
	{
		private readonly List<T> values;

		public List<T> Values => values;

		public MultiValue(params T[] values)
		{
			this.values = values.ToList();
		}

		public static implicit operator MultiValue<T>(T value)
		{
			return new MultiValue<T>(value);
		}

		public static implicit operator MultiValue<T>(T[] values)
		{
			return new MultiValue<T>(values);
		}

		public static explicit operator T(MultiValue<T> value)
		{
			if (value.Values.Count == 1)
			{
				return value.Values[0];
			}
			throw new InvalidCastException($"Cannot cast sequence of values to {typeof(T)}.");
		}

		public static explicit operator T[](MultiValue<T> value)
		{
			return value.Values.ToArray();
		}
	}
	public class Option<T> : IOption
	{
		private T value;

		public string DefaultOptionString => OptionStrings.First();

		public string[] OptionStrings { get; }

		public bool IsSet { get; private set; }

		public T Value
		{
			get
			{
				return value;
			}
			set
			{
				IsSet = !object.Equals(value, default(T));
				this.value = value;
			}
		}

		public bool IsCustom { get; }

		public Option(params string[] optionStrings)
		{
			OptionStrings = optionStrings;
			IsSet = false;
		}

		public Option(bool isCustom, params string[] optionStrings)
		{
			OptionStrings = optionStrings;
			IsSet = false;
			IsCustom = isCustom;
		}

		public void SetFromString(string s)
		{
			string[] array = s.Split(new char[1] { ' ' });
			string stringValue = s.Substring(array[0].Length).Trim().Trim(new char[1] { '"' });
			if (!OptionStrings.Contains(array[0]))
			{
				throw new ArgumentException("Given string does not match required format.");
			}
			Value = Utils.OptionValueFromString<T>(stringValue);
		}

		public override string ToString()
		{
			if (!IsSet)
			{
				return string.Empty;
			}
			string text = Utils.OptionValueToString(Value);
			return DefaultOptionString + text;
		}

		public IEnumerable<string> ToStringCollection()
		{
			return new string[1] { ToString() };
		}
	}
	internal class OptionComparer : IEqualityComparer<IOption>
	{
		public bool Equals(IOption x, IOption y)
		{
			if (x != null)
			{
				if (y != null)
				{
					return x.ToString().Equals(y.ToString());
				}
				return false;
			}
			return y == null;
		}

		public int GetHashCode(IOption obj)
		{
			return obj.ToString().GetHashCode();
		}
	}
	public class OptionSet : ICloneable
	{
		private Option<string> username = new Option<string>("-u", "--username");

		private Option<string> password = new Option<string>("-p", "--password");

		private Option<string> twoFactor = new Option<string>("-2", "--twofactor");

		private Option<bool> netrc = new Option<bool>("-n", "--netrc");

		private Option<string> netrcLocation = new Option<string>("--netrc-location");

		private Option<string> netrcCmd = new Option<string>("--netrc-cmd");

		private Option<string> videoPassword = new Option<string>("--video-password");

		private Option<string> apMso = new Option<string>("--ap-mso");

		private Option<string> apUsername = new Option<string>("--ap-username");

		private Option<string> apPassword = new Option<string>("--ap-password");

		private Option<bool> apListMso = new Option<bool>("--ap-list-mso");

		private Option<string> clientCertificate = new Option<string>("--client-certificate");

		private Option<string> clientCertificateKey = new Option<string>("--client-certificate-key");

		private Option<string> clientCertificatePassword = new Option<string>("--client-certificate-password");

		private static readonly OptionComparer Comparer = new OptionComparer();

		public static readonly OptionSet Default = new OptionSet();

		private Option<bool> getDescription = new Option<bool>("--get-description");

		private Option<bool> getDuration = new Option<bool>("--get-duration");

		private Option<bool> getFilename = new Option<bool>("--get-filename");

		private Option<bool> getFormat = new Option<bool>("--get-format");

		private Option<bool> getId = new Option<bool>("--get-id");

		private Option<bool> getThumbnail = new Option<bool>("--get-thumbnail");

		private Option<bool> getTitle = new Option<bool>("-e", "--get-title");

		private Option<bool> getUrl = new Option<bool>("-g", "--get-url");

		private Option<string> matchTitle = new Option<string>("--match-title");

		private Option<string> rejectTitle = new Option<string>("--reject-title");

		private Option<long?> minViews = new Option<long?>("--min-views");

		private Option<long?> maxViews = new Option<long?>("--max-views");

		private Option<bool> breakOnReject = new Option<bool>("--break-on-reject");

		private Option<string> userAgent = new Option<string>("--user-agent");

		private Option<string> referer = new Option<string>("--referer");

		private Option<int?> playlistStart = new Option<int?>("--playlist-start");

		private Option<int?> playlistEnd = new Option<int?>("--playlist-end");

		private Option<bool> playlistReverse = new Option<bool>("--playlist-reverse");

		private Option<bool> noColors = new Option<bool>("--no-colors");

		private Option<bool> forceGenericExtractor = new Option<bool>("--force-generic-extractor");

		private Option<string> execBeforeDownload = new Option<string>("--exec-before-download");

		private Option<bool> noExecBeforeDownload = new Option<bool>("--no-exec-before-download");

		private Option<bool> allFormats = new Option<bool>("--all-formats");

		private Option<bool> allSubs = new Option<bool>("--all-subs");

		private Option<bool> printJson = new Option<bool>("--print-json");

		private Option<string> autonumberSize = new Option<string>("--autonumber-size");

		private Option<int?> autonumberStart = new Option<int?>("--autonumber-start");

		private Option<bool> id = new Option<bool>("--id");

		private Option<string> metadataFromTitle = new Option<string>("--metadata-from-title");

		private Option<bool> hlsPreferNative = new Option<bool>("--hls-prefer-native");

		private Option<bool> hlsPreferFfmpeg = new Option<bool>("--hls-prefer-ffmpeg");

		private Option<bool> listFormatsOld = new Option<bool>("--list-formats-old", "--no-list-formats-as-table");

		private Option<bool> listFormatsAsTable = new Option<bool>("--list-formats-as-table", "--no-list-formats-old");

		private Option<bool> youtubeSkipDashManifest = new Option<bool>("--youtube-skip-dash-manifest", "--no-youtube-include-dash-manifest");

		private Option<bool> youtubeSkipHlsManifest = new Option<bool>("--youtube-skip-hls-manifest", "--no-youtube-include-hls-manifest");

		private Option<bool> geoBypass = new Option<bool>("--geo-bypass");

		private Option<bool> noGeoBypass = new Option<bool>("--no-geo-bypass");

		private Option<string> geoBypassCountry = new Option<string>("--geo-bypass-country");

		private Option<string> geoBypassIpBlock = new Option<string>("--geo-bypass-ip-block");

		private Option<int?> concurrentFragments = new Option<int?>("-N", "--concurrent-fragments");

		private Option<long?> limitRate = new Option<long?>("-r", "--limit-rate");

		private Option<long?> throttledRate = new Option<long?>("--throttled-rate");

		private Option<int?> retries = new Option<int?>("-R", "--retries");

		private Option<int?> fileAccessRetries = new Option<int?>("--file-access-retries");

		private Option<int?> fragmentRetries = new Option<int?>("--fragment-retries");

		private MultiOption<string> retrySleep = new MultiOption<string>("--retry-sleep");

		private Option<bool> skipUnavailableFragments = new Option<bool>("--skip-unavailable-fragments", "--no-abort-on-unavailable-fragments");

		private Option<bool> abortOnUnavailableFragments = new Option<bool>("--abort-on-unavailable-fragments", "--no-skip-unavailable-fragments");

		private Option<bool> keepFragments = new Option<bool>("--keep-fragments");

		private Option<bool> noKeepFragments = new Option<bool>("--no-keep-fragments");

		private Option<long?> bufferSize = new Option<long?>("--buffer-size");

		private Option<bool> resizeBuffer = new Option<bool>("--resize-buffer");

		private Option<bool> noResizeBuffer = new Option<bool>("--no-resize-buffer");

		private Option<long?> httpChunkSize = new Option<long?>("--http-chunk-size");

		private Option<bool> playlistRandom = new Option<bool>("--playlist-random");

		private Option<bool> lazyPlaylist = new Option<bool>("--lazy-playlist");

		private Option<bool> noLazyPlaylist = new Option<bool>("--no-lazy-playlist");

		private Option<bool> xattrSetFilesize = new Option<bool>("--xattr-set-filesize");

		private Option<bool> hlsUseMpegts = new Option<bool>("--hls-use-mpegts");

		private Option<bool> noHlsUseMpegts = new Option<bool>("--no-hls-use-mpegts");

		private MultiOption<string> downloadSections = new MultiOption<string>("--download-sections");

		private MultiOption<string> downloader = new MultiOption<string>("--downloader", "--external-downloader");

		private MultiOption<string> downloaderArgs = new MultiOption<string>("--downloader-args", "--external-downloader-args");

		private Option<int?> extractorRetries = new Option<int?>("--extractor-retries");

		private Option<bool> allowDynamicMpd = new Option<bool>("--allow-dynamic-mpd", "--no-ignore-dynamic-mpd");

		private Option<bool> ignoreDynamicMpd = new Option<bool>("--ignore-dynamic-mpd", "--no-allow-dynamic-mpd");

		private Option<bool> hlsSplitDiscontinuity = new Option<bool>("--hls-split-discontinuity");

		private Option<bool> noHlsSplitDiscontinuity = new Option<bool>("--no-hls-split-discontinuity");

		private MultiOption<string> extractorArgs = new MultiOption<string>("--extractor-args");

		private Option<string> batchFile = new Option<string>("-a", "--batch-file");

		private Option<bool> noBatchFile = new Option<bool>("--no-batch-file");

		private MultiOption<string> paths = new MultiOption<string>("-P", "--paths");

		private Option<string> output = new Option<string>("-o", "--output");

		private Option<string> outputNaPlaceholder = new Option<string>("--output-na-placeholder");

		private Option<bool> restrictFilenames = new Option<bool>("--restrict-filenames");

		private Option<bool> noRestrictFilenames = new Option<bool>("--no-restrict-filenames");

		private Option<bool> windowsFilenames = new Option<bool>("--windows-filenames");

		private Option<bool> noWindowsFilenames = new Option<bool>("--no-windows-filenames");

		private Option<int?> trimFilenames = new Option<int?>("--trim-filenames");

		private Option<bool> noOverwrites = new Option<bool>("-w", "--no-overwrites");

		private Option<bool> forceOverwrites = new Option<bool>("--force-overwrites");

		private Option<bool> noForceOverwrites = new Option<bool>("--no-force-overwrites");

		private Option<bool> doContinue = new Option<bool>("-c", "--continue");

		private Option<bool> noContinue = new Option<bool>("--no-continue");

		private Option<bool> part = new Option<bool>("--part");

		private Option<bool> noPart = new Option<bool>("--no-part");

		private Option<bool> mtime = new Option<bool>("--mtime");

		private Option<bool> noMtime = new Option<bool>("--no-mtime");

		private Option<bool> writeDescription = new Option<bool>("--write-description");

		private Option<bool> noWriteDescription = new Option<bool>("--no-write-description");

		private Option<bool> writeInfoJson = new Option<bool>("--write-info-json");

		private Option<bool> noWriteInfoJson = new Option<bool>("--no-write-info-json");

		private Option<bool> writePlaylistMetafiles = new Option<bool>("--write-playlist-metafiles");

		private Option<bool> noWritePlaylistMetafiles = new Option<bool>("--no-write-playlist-metafiles");

		private Option<bool> cleanInfoJson = new Option<bool>("--clean-info-json");

		private Option<bool> noCleanInfoJson = new Option<bool>("--no-clean-info-json");

		private Option<bool> writeComments = new Option<bool>("--write-comments", "--get-comments");

		private Option<bool> noWriteComments = new Option<bool>("--no-write-comments", "--no-get-comments");

		private Option<string> loadInfoJson = new Option<string>("--load-info-json");

		private Option<string> cookies = new Option<string>("--cookies");

		private Option<bool> noCookies = new Option<bool>("--no-cookies");

		private Option<string> cookiesFromBrowser = new Option<string>("--cookies-from-browser");

		private Option<bool> noCookiesFromBrowser = new Option<bool>("--no-cookies-from-browser");

		private Option<string> cacheDir = new Option<string>("--cache-dir");

		private Option<bool> noCacheDir = new Option<bool>("--no-cache-dir");

		private Option<bool> removeCacheDir = new Option<bool>("--rm-cache-dir");

		private Option<bool> help = new Option<bool>("-h", "--help");

		private Option<bool> version = new Option<bool>("--version");

		private Option<bool> update = new Option<bool>("-U", "--update");

		private Option<bool> noUpdate = new Option<bool>("--no-update");

		private Option<string> updateTo = new Option<string>("--update-to");

		private Option<bool> ignoreErrors = new Option<bool>("-i", "--ignore-errors");

		private Option<bool> noAbortOnError = new Option<bool>("--no-abort-on-error");

		private Option<bool> abortOnError = new Option<bool>("--abort-on-error", "--no-ignore-errors");

		private Option<bool> dumpUserAgent = new Option<bool>("--dump-user-agent");

		private Option<bool> listExtractors = new Option<bool>("--list-extractors");

		private Option<bool> extractorDescriptions = new Option<bool>("--extractor-descriptions");

		private Option<string> useExtractors = new Option<string>("--use-extractors", "--ies");

		private Option<string> defaultSearch = new Option<string>("--default-search");

		private Option<bool> ignoreConfig = new Option<bool>("--ignore-config", "--no-config");

		private Option<bool> noConfigLocations = new Option<bool>("--no-config-locations");

		private MultiOption<string> configLocations = new MultiOption<string>("--config-locations");

		private MultiOption<string> pluginDirs = new MultiOption<string>("--plugin-dirs");

		private Option<bool> noPluginDirs = new Option<bool>("--no-plugin-dirs");

		private Option<bool> flatPlaylist = new Option<bool>("--flat-playlist");

		private Option<bool> noFlatPlaylist = new Option<bool>("--no-flat-playlist");

		private Option<bool> liveFromStart = new Option<bool>("--live-from-start");

		private Option<bool> noLiveFromStart = new Option<bool>("--no-live-from-start");

		private Option<string> waitForVideo = new Option<string>("--wait-for-video");

		private Option<bool> noWaitForVideo = new Option<bool>("--no-wait-for-video");

		private Option<bool> markWatched = new Option<bool>("--mark-watched");

		private Option<bool> noMarkWatched = new Option<bool>("--no-mark-watched");

		private MultiOption<string> color = new MultiOption<string>("--color");

		private Option<string> compatOptions = new Option<string>("--compat-options");

		private MultiOption<string> alias = new MultiOption<string>("--alias");

		private Option<string> geoVerificationProxy = new Option<string>("--geo-verification-proxy");

		private Option<string> xff = new Option<string>("--xff");

		private Option<bool> writeLink = new Option<bool>("--write-link");

		private Option<bool> writeUrlLink = new Option<bool>("--write-url-link");

		private Option<bool> writeWeblocLink = new Option<bool>("--write-webloc-link");

		private Option<bool> writeDesktopLink = new Option<bool>("--write-desktop-link");

		private Option<string> proxy = new Option<string>("--proxy");

		private Option<int?> socketTimeout = new Option<int?>("--socket-timeout");

		private Option<string> sourceAddress = new Option<string>("--source-address");

		private Option<string> impersonate = new Option<string>("--impersonate");

		private Option<bool> listImpersonateTargets = new Option<bool>("--list-impersonate-targets");

		private Option<bool> forceIPv4 = new Option<bool>("-4", "--force-ipv4");

		private Option<bool> forceIPv6 = new Option<bool>("-6", "--force-ipv6");

		private Option<bool> enableFileUrls = new Option<bool>("--enable-file-urls");

		private Option<bool> extractAudio = new Option<bool>("-x", "--extract-audio");

		private Option<AudioConversionFormat> audioFormat = new Option<AudioConversionFormat>("--audio-format");

		private Option<byte?> audioQuality = new Option<byte?>("--audio-quality");

		private Option<string> remuxVideo = new Option<string>("--remux-video");

		private Option<VideoRecodeFormat> recodeVideo = new Option<VideoRecodeFormat>("--recode-video");

		private MultiOption<string> postprocessorArgs = new MultiOption<string>("--postprocessor-args", "--ppa");

		private Option<bool> keepVideo = new Option<bool>("-k", "--keep-video");

		private Option<bool> noKeepVideo = new Option<bool>("--no-keep-video");

		private Option<bool> postOverwrites = new Option<bool>("--post-overwrites");

		private Option<bool> noPostOverwrites = new Option<bool>("--no-post-overwrites");

		private Option<bool> embedSubs = new Option<bool>("--embed-subs");

		private Option<bool> noEmbedSubs = new Option<bool>("--no-embed-subs");

		private Option<bool> embedThumbnail = new Option<bool>("--embed-thumbnail");

		private Option<bool> noEmbedThumbnail = new Option<bool>("--no-embed-thumbnail");

		private Option<bool> embedMetadata = new Option<bool>("--embed-metadata", "--add-metadata");

		private Option<bool> noEmbedMetadata = new Option<bool>("--no-embed-metadata", "--no-add-metadata");

		private Option<bool> embedChapters = new Option<bool>("--embed-chapters", "--add-chapters");

		private Option<bool> noEmbedChapters = new Option<bool>("--no-embed-chapters", "--no-add-chapters");

		private Option<bool> embedInfoJson = new Option<bool>("--embed-info-json");

		private Option<bool> noEmbedInfoJson = new Option<bool>("--no-embed-info-json");

		private Option<string> parseMetadata = new Option<string>("--parse-metadata");

		private MultiOption<string> replaceInMetadata = new MultiOption<string>("--replace-in-metadata");

		private Option<bool> xattrs = new Option<bool>("--xattrs");

		private Option<string> concatPlaylist = new Option<string>("--concat-playlist");

		private Option<string> fixup = new Option<string>("--fixup");

		private Option<string> ffmpegLocation = new Option<string>("--ffmpeg-location");

		private MultiOption<string> exec = new MultiOption<string>("--exec");

		private Option<bool> noExec = new Option<bool>("--no-exec");

		private Option<string> convertSubs = new Option<string>("--convert-subs");

		private Option<string> convertThumbnails = new Option<string>("--convert-thumbnails");

		private Option<bool> splitChapters = new Option<bool>("--split-chapters");

		private Option<bool> noSplitChapters = new Option<bool>("--no-split-chapters");

		private MultiOption<string> removeChapters = new MultiOption<string>("--remove-chapters");

		private Option<bool> noRemoveChapters = new Option<bool>("--no-remove-chapters");

		private Option<bool> forceKeyframesAtCuts = new Option<bool>("--force-keyframes-at-cuts");

		private Option<bool> noForceKeyframesAtCuts = new Option<bool>("--no-force-keyframes-at-cuts");

		private MultiOption<string> usePostprocessor = new MultiOption<string>("--use-postprocessor");

		private Option<string> sponsorblockMark = new Option<string>("--sponsorblock-mark");

		private Option<string> sponsorblockRemove = new Option<string>("--sponsorblock-remove");

		private Option<string> sponsorblockChapterTitle = new Option<string>("--sponsorblock-chapter-title");

		private Option<bool> noSponsorblock = new Option<bool>("--no-sponsorblock");

		private Option<string> sponsorblockApi = new Option<string>("--sponsorblock-api");

		private Option<bool> writeSubs = new Option<bool>("--write-subs");

		private Option<bool> noWriteSubs = new Option<bool>("--no-write-subs");

		private Option<bool> writeAutoSubs = new Option<bool>("--write-auto-subs", "--write-automatic-subs");

		private Option<bool> noWriteAutoSubs = new Option<bool>("--no-write-auto-subs", "--no-write-automatic-subs");

		private Option<bool> listSubs = new Option<bool>("--list-subs");

		private Option<string> subFormat = new Option<string>("--sub-format");

		private Option<string> subLangs = new Option<string>("--sub-langs");

		private Option<bool> writeThumbnail = new Option<bool>("--write-thumbnail");

		private Option<bool> noWriteThumbnail = new Option<bool>("--no-write-thumbnail");

		private Option<bool> writeAllThumbnails = new Option<bool>("--write-all-thumbnails");

		private Option<bool> listThumbnails = new Option<bool>("--list-thumbnails");

		private Option<bool> quiet = new Option<bool>("-q", "--quiet");

		private Option<bool> noQuiet = new Option<bool>("--no-quiet");

		private Option<bool> noWarnings = new Option<bool>("--no-warnings");

		private Option<bool> simulate = new Option<bool>("-s", "--simulate");

		private Option<bool> noSimulate = new Option<bool>("--no-simulate");

		private Option<bool> ignoreNoFormatsError = new Option<bool>("--ignore-no-formats-error");

		private Option<bool> noIgnoreNoFormatsError = new Option<bool>("--no-ignore-no-formats-error");

		private Option<bool> skipDownload = new Option<bool>("--skip-download", "--no-download");

		private MultiOption<string> print = new MultiOption<string>("-O", "--print");

		private MultiOption<string> printToFile = new MultiOption<string>("--print-to-file");

		private Option<bool> dumpJson = new Option<bool>("-j", "--dump-json");

		private Option<bool> dumpSingleJson = new Option<bool>("-J", "--dump-single-json");

		private Option<bool> forceWriteArchive = new Option<bool>("--force-write-archive", "--force-download-archive");

		private Option<bool> newline = new Option<bool>("--newline");

		private Option<bool> noProgress = new Option<bool>("--no-progress");

		private Option<bool> progress = new Option<bool>("--progress");

		private Option<bool> consoleTitle = new Option<bool>("--console-title");

		private Option<string> progressTemplate = new Option<string>("--progress-template");

		private Option<string> progressDelta = new Option<string>("--progress-delta");

		private Option<bool> verbose = new Option<bool>("-v", "--verbose");

		private Option<bool> dumpPages = new Option<bool>("--dump-pages");

		private Option<bool> writePages = new Option<bool>("--write-pages");

		private Option<bool> printTraffic = new Option<bool>("--print-traffic");

		private Option<string> format = new Option<string>("-f", "--format");

		private Option<string> formatSort = new Option<string>("-S", "--format-sort");

		private Option<bool> formatSortForce = new Option<bool>("--format-sort-force", "--S-force");

		private Option<bool> noFormatSortForce = new Option<bool>("--no-format-sort-force");

		private Option<bool> videoMultistreams = new Option<bool>("--video-multistreams");

		private Option<bool> noVideoMultistreams = new Option<bool>("--no-video-multistreams");

		private Option<bool> audioMultistreams = new Option<bool>("--audio-multistreams");

		private Option<bool> noAudioMultistreams = new Option<bool>("--no-audio-multistreams");

		private Option<bool> preferFreeFormats = new Option<bool>("--prefer-free-formats");

		private Option<bool> noPreferFreeFormats = new Option<bool>("--no-prefer-free-formats");

		private Option<bool> checkFormats = new Option<bool>("--check-formats");

		private Option<bool> checkAllFormats = new Option<bool>("--check-all-formats");

		private Option<bool> noCheckFormats = new Option<bool>("--no-check-formats");

		private Option<bool> listFormats = new Option<bool>("-F", "--list-formats");

		private Option<DownloadMergeFormat> mergeOutputFormat = new Option<DownloadMergeFormat>("--merge-output-format");

		private Option<string> playlistItems = new Option<string>("-I", "--playlist-items");

		private Option<string> minFilesize = new Option<string>("--min-filesize");

		private Option<string> maxFilesize = new Option<string>("--max-filesize");

		private Option<DateTime> date = new Option<DateTime>("--date");

		private Option<DateTime> dateBefore = new Option<DateTime>("--datebefore");

		private Option<DateTime> dateAfter = new Option<DateTime>("--dateafter");

		private MultiOption<string> matchFilters = new MultiOption<string>("--match-filters");

		private Option<bool> noMatchFilters = new Option<bool>("--no-match-filters");

		private Option<string> breakMatchFilters = new Option<string>("--break-match-filters");

		private Option<bool> noBreakMatchFilters = new Option<bool>("--no-break-match-filters");

		private Option<bool> noPlaylist = new Option<bool>("--no-playlist");

		private Option<bool> yesPlaylist = new Option<bool>("--yes-playlist");

		private Option<byte?> ageLimit = new Option<byte?>("--age-limit");

		private Option<string> downloadArchive = new Option<string>("--download-archive");

		private Option<bool> noDownloadArchive = new Option<bool>("--no-download-archive");

		private Option<int?> maxDownloads = new Option<int?>("--max-downloads");

		private Option<bool> breakOnExisting = new Option<bool>("--break-on-existing");

		private Option<bool> noBreakOnExisting = new Option<bool>("--no-break-on-existing");

		private Option<bool> breakPerInput = new Option<bool>("--break-per-input");

		private Option<bool> noBreakPerInput = new Option<bool>("--no-break-per-input");

		private Option<int?> skipPlaylistAfterErrors = new Option<int?>("--skip-playlist-after-errors");

		private Option<string> encoding = new Option<string>("--encoding");

		private Option<bool> legacyServerConnect = new Option<bool>("--legacy-server-connect");

		private Option<bool> noCheckCertificates = new Option<bool>("--no-check-certificates");

		private Option<bool> preferInsecure = new Option<bool>("--prefer-insecure");

		private MultiOption<string> addHeaders = new MultiOption<string>("--add-headers");

		private Option<bool> bidiWorkaround = new Option<bool>("--bidi-workaround");

		private Option<int?> sleepRequests = new Option<int?>("--sleep-requests");

		private Option<int?> sleepInterval = new Option<int?>("--sleep-interval", "--min-sleep-interval");

		private Option<int?> maxSleepInterval = new Option<int?>("--max-sleep-interval");

		private Option<int?> sleepSubtitles = new Option<int?>("--sleep-subtitles");

		public string Username
		{
			get
			{
				return username.Value;
			}
			set
			{
				username.Value = value;
			}
		}

		public string Password
		{
			get
			{
				return password.Value;
			}
			set
			{
				password.Value = value;
			}
		}

		public string TwoFactor
		{
			get
			{
				return twoFactor.Value;
			}
			set
			{
				twoFactor.Value = value;
			}
		}

		public bool Netrc
		{
			get
			{
				return netrc.Value;
			}
			set
			{
				netrc.Value = value;
			}
		}

		public string NetrcLocation
		{
			get
			{
				return netrcLocation.Value;
			}
			set
			{
				netrcLocation.Value = value;
			}
		}

		public string NetrcCmd
		{
			get
			{
				return netrcCmd.Value;
			}
			set
			{
				netrcCmd.Value = value;
			}
		}

		public string VideoPassword
		{
			get
			{
				return videoPassword.Value;
			}
			set
			{
				videoPassword.Value = value;
			}
		}

		public string ApMso
		{
			get
			{
				return apMso.Value;
			}
			set
			{
				apMso.Value = value;
			}
		}

		public string ApUsername
		{
			get
			{
				return apUsername.Value;
			}
			set
			{
				apUsername.Value = value;
			}
		}

		public string ApPassword
		{
			get
			{
				return apPassword.Value;
			}
			set
			{
				apPassword.Value = value;
			}
		}

		public bool ApListMso
		{
			get
			{
				return apListMso.Value;
			}
			set
			{
				apListMso.Value = value;
			}
		}

		public string ClientCertificate
		{
			get
			{
				return clientCertificate.Value;
			}
			set
			{
				clientCertificate.Value = value;
			}
		}

		public string ClientCertificateKey
		{
			get
			{
				return clientCertificateKey.Value;
			}
			set
			{
				clientCertificateKey.Value = value;
			}
		}

		public string ClientCertificatePassword
		{
			get
			{
				return clientCertificatePassword.Value;
			}
			set
			{
				clientCertificatePassword.Value = value;
			}
		}

		public IOption[] CustomOptions { get; set; } = new IOption[0];


		[Obsolete("Deprecated in favor of: --print description.")]
		public bool GetDescription
		{
			get
			{
				return getDescription.Value;
			}
			set
			{
				getDescription.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --print duration_string.")]
		public bool GetDuration
		{
			get
			{
				return getDuration.Value;
			}
			set
			{
				getDuration.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --print filename.")]
		public bool GetFilename
		{
			get
			{
				return getFilename.Value;
			}
			set
			{
				getFilename.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --print format.")]
		public bool GetFormat
		{
			get
			{
				return getFormat.Value;
			}
			set
			{
				getFormat.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --print id.")]
		public bool GetId
		{
			get
			{
				return getId.Value;
			}
			set
			{
				getId.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --print thumbnail.")]
		public bool GetThumbnail
		{
			get
			{
				return getThumbnail.Value;
			}
			set
			{
				getThumbnail.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --print title.")]
		public bool GetTitle
		{
			get
			{
				return getTitle.Value;
			}
			set
			{
				getTitle.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --print urls.")]
		public bool GetUrl
		{
			get
			{
				return getUrl.Value;
			}
			set
			{
				getUrl.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --match-filter \"title ~= (?i)REGEX\".")]
		public string MatchTitle
		{
			get
			{
				return matchTitle.Value;
			}
			set
			{
				matchTitle.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --match-filter \"title !~= (?i)REGEX\".")]
		public string RejectTitle
		{
			get
			{
				return rejectTitle.Value;
			}
			set
			{
				rejectTitle.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --match-filter \"view_count >=? COUNT\".")]
		public long? MinViews
		{
			get
			{
				return minViews.Value;
			}
			set
			{
				minViews.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --match-filter \"view_count <=? COUNT\".")]
		public long? MaxViews
		{
			get
			{
				return maxViews.Value;
			}
			set
			{
				maxViews.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: Use --break-match-filter.")]
		public bool BreakOnReject
		{
			get
			{
				return breakOnReject.Value;
			}
			set
			{
				breakOnReject.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --add-header \"User-Agent:UA\".")]
		public string UserAgent
		{
			get
			{
				return userAgent.Value;
			}
			set
			{
				userAgent.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --add-header \"Referer:URL\".")]
		public string Referer
		{
			get
			{
				return referer.Value;
			}
			set
			{
				referer.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: -I NUMBER:.")]
		public int? PlaylistStart
		{
			get
			{
				return playlistStart.Value;
			}
			set
			{
				playlistStart.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: -I :NUMBER.")]
		public int? PlaylistEnd
		{
			get
			{
				return playlistEnd.Value;
			}
			set
			{
				playlistEnd.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: -I ::-1.")]
		public bool PlaylistReverse
		{
			get
			{
				return playlistReverse.Value;
			}
			set
			{
				playlistReverse.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --color no_color.")]
		public bool NoColors
		{
			get
			{
				return noColors.Value;
			}
			set
			{
				noColors.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --ies generic,default.")]
		public bool ForceGenericExtractor
		{
			get
			{
				return forceGenericExtractor.Value;
			}
			set
			{
				forceGenericExtractor.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --exec \"before_dl:CMD\".")]
		public string ExecBeforeDownload
		{
			get
			{
				return execBeforeDownload.Value;
			}
			set
			{
				execBeforeDownload.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --no-exec.")]
		public bool NoExecBeforeDownload
		{
			get
			{
				return noExecBeforeDownload.Value;
			}
			set
			{
				noExecBeforeDownload.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: -f all.")]
		public bool AllFormats
		{
			get
			{
				return allFormats.Value;
			}
			set
			{
				allFormats.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --sub-langs all --write-subs.")]
		public bool AllSubs
		{
			get
			{
				return allSubs.Value;
			}
			set
			{
				allSubs.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: -j --no-simulate.")]
		public bool PrintJson
		{
			get
			{
				return printJson.Value;
			}
			set
			{
				printJson.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: Use string formatting, e.g. %(autonumber)03d.")]
		public string AutonumberSize
		{
			get
			{
				return autonumberSize.Value;
			}
			set
			{
				autonumberSize.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: Use internal field formatting like %(autonumber+NUMBER)s.")]
		public int? AutonumberStart
		{
			get
			{
				return autonumberStart.Value;
			}
			set
			{
				autonumberStart.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: -o \"%(id)s.%(ext)s\".")]
		public bool Id
		{
			get
			{
				return id.Value;
			}
			set
			{
				id.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --parse-metadata \"%(title)s:FORMAT\".")]
		public string MetadataFromTitle
		{
			get
			{
				return metadataFromTitle.Value;
			}
			set
			{
				metadataFromTitle.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --downloader \"m3u8:native\".")]
		public bool HlsPreferNative
		{
			get
			{
				return hlsPreferNative.Value;
			}
			set
			{
				hlsPreferNative.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --downloader \"m3u8:ffmpeg\".")]
		public bool HlsPreferFfmpeg
		{
			get
			{
				return hlsPreferFfmpeg.Value;
			}
			set
			{
				hlsPreferFfmpeg.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --compat-options list-formats (Alias: --no-list-formats-as-table).")]
		public bool ListFormatsOld
		{
			get
			{
				return listFormatsOld.Value;
			}
			set
			{
				listFormatsOld.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --compat-options -list-formats [Default] (Alias: --no-list-formats-old).")]
		public bool ListFormatsAsTable
		{
			get
			{
				return listFormatsAsTable.Value;
			}
			set
			{
				listFormatsAsTable.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --extractor-args \"youtube:skip=dash\" (Alias: --no-youtube-include-dash-manifest).")]
		public bool YoutubeSkipDashManifest
		{
			get
			{
				return youtubeSkipDashManifest.Value;
			}
			set
			{
				youtubeSkipDashManifest.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --extractor-args \"youtube:skip=hls\" (Alias: --no-youtube-include-hls-manifest).")]
		public bool YoutubeSkipHlsManifest
		{
			get
			{
				return youtubeSkipHlsManifest.Value;
			}
			set
			{
				youtubeSkipHlsManifest.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --xff \"default\".")]
		public bool GeoBypass
		{
			get
			{
				return geoBypass.Value;
			}
			set
			{
				geoBypass.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --xff \"never\".")]
		public bool NoGeoBypass
		{
			get
			{
				return noGeoBypass.Value;
			}
			set
			{
				noGeoBypass.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --xff CODE.")]
		public string GeoBypassCountry
		{
			get
			{
				return geoBypassCountry.Value;
			}
			set
			{
				geoBypassCountry.Value = value;
			}
		}

		[Obsolete("Deprecated in favor of: --xff IP_BLOCK.")]
		public string GeoBypassIpBlock
		{
			get
			{
				return geoBypassIpBlock.Value;
			}
			set
			{
				geoBypassIpBlock.Value = value;
			}
		}

		public int? ConcurrentFragments
		{
			get
			{
				return concurrentFragments.Value;
			}
			set
			{
				concurrentFragments.Value = value;
			}
		}

		public long? LimitRate
		{
			get
			{
				return limitRate.Value;
			}
			set
			{
				limitRate.Value = value;
			}
		}

		public long? ThrottledRate
		{
			get
			{
				return throttledRate.Value;
			}
			set
			{
				throttledRate.Value = value;
			}
		}

		public int? Retries
		{
			get
			{
				return retries.Value;
			}
			set
			{
				retries.Value = value;
			}
		}

		public int? FileAccessRetries
		{
			get
			{
				return fileAccessRetries.Value;
			}
			set
			{
				fileAccessRetries.Value = value;
			}
		}

		public int? FragmentRetries
		{
			get
			{
				return fragmentRetries.Value;
			}
			set
			{
				fragmentRetries.Value = value;
			}
		}

		public MultiValue<string> RetrySleep
		{
			get
			{
				return retrySleep.Value;
			}
			set
			{
				retrySleep.Value = value;
			}
		}

		public bool SkipUnavailableFragments
		{
			get
			{
				return skipUnavailableFragments.Value;
			}
			set
			{
				skipUnavailableFragments.Value = value;
			}
		}

		public bool AbortOnUnavailableFragments
		{
			get
			{
				return abortOnUnavailableFragments.Value;
			}
			set
			{
				abortOnUnavailableFragments.Value = value;
			}
		}

		public bool KeepFragments
		{
			get
			{
				return keepFragments.Value;
			}
			set
			{
				keepFragments.Value = value;
			}
		}

		public bool NoKeepFragments
		{
			get
			{
				return noKeepFragments.Value;
			}
			set
			{
				noKeepFragments.Value = value;
			}
		}

		public long? BufferSize
		{
			get
			{
				return bufferSize.Value;
			}
			set
			{
				bufferSize.Value = value;
			}
		}

		public bool ResizeBuffer
		{
			get
			{
				return resizeBuffer.Value;
			}
			set
			{
				resizeBuffer.Value = value;
			}
		}

		public bool NoResizeBuffer
		{
			get
			{
				return noResizeBuffer.Value;
			}
			set
			{
				noResizeBuffer.Value = value;
			}
		}

		public long? HttpChunkSize
		{
			get
			{
				return httpChunkSize.Value;
			}
			set
			{
				httpChunkSize.Value = value;
			}
		}

		public bool PlaylistRandom
		{
			get
			{
				return playlistRandom.Value;
			}
			set
			{
				playlistRandom.Value = value;
			}
		}

		public bool LazyPlaylist
		{
			get
			{
				return lazyPlaylist.Value;
			}
			set
			{
				lazyPlaylist.Value = value;
			}
		}

		public bool NoLazyPlaylist
		{
			get
			{
				return noLazyPlaylist.Value;
			}
			set
			{
				noLazyPlaylist.Value = value;
			}
		}

		public bool XattrSetFilesize
		{
			get
			{
				return xattrSetFilesize.Value;
			}
			set
			{
				xattrSetFilesize.Value = value;
			}
		}

		public bool HlsUseMpegts
		{
			get
			{
				return hlsUseMpegts.Value;
			}
			set
			{
				hlsUseMpegts.Value = value;
			}
		}

		public bool NoHlsUseMpegts
		{
			get
			{
				return noHlsUseMpegts.Value;
			}
			set
			{
				noHlsUseMpegts.Value = value;
			}
		}

		public MultiValue<string> DownloadSections
		{
			get
			{
				return downloadSections.Value;
			}
			set
			{
				downloadSections.Value = value;
			}
		}

		public MultiValue<string> Downloader
		{
			get
			{
				return downloader.Value;
			}
			set
			{
				downloader.Value = value;
			}
		}

		public MultiValue<string> DownloaderArgs
		{
			get
			{
				return downloaderArgs.Value;
			}
			set
			{
				downloaderArgs.Value = value;
			}
		}

		public int? ExtractorRetries
		{
			get
			{
				return extractorRetries.Value;
			}
			set
			{
				extractorRetries.Value = value;
			}
		}

		public bool AllowDynamicMpd
		{
			get
			{
				return allowDynamicMpd.Value;
			}
			set
			{
				allowDynamicMpd.Value = value;
			}
		}

		public bool IgnoreDynamicMpd
		{
			get
			{
				return ignoreDynamicMpd.Value;
			}
			set
			{
				ignoreDynamicMpd.Value = value;
			}
		}

		public bool HlsSplitDiscontinuity
		{
			get
			{
				return hlsSplitDiscontinuity.Value;
			}
			set
			{
				hlsSplitDiscontinuity.Value = value;
			}
		}

		public bool NoHlsSplitDiscontinuity
		{
			get
			{
				return noHlsSplitDiscontinuity.Value;
			}
			set
			{
				noHlsSplitDiscontinuity.Value = value;
			}
		}

		public MultiValue<string> ExtractorArgs
		{
			get
			{
				return extractorArgs.Value;
			}
			set
			{
				extractorArgs.Value = value;
			}
		}

		public string BatchFile
		{
			get
			{
				return batchFile.Value;
			}
			set
			{
				batchFile.Value = value;
			}
		}

		public bool NoBatchFile
		{
			get
			{
				return noBatchFile.Value;
			}
			set
			{
				noBatchFile.Value = value;
			}
		}

		public MultiValue<string> Paths
		{
			get
			{
				return paths.Value;
			}
			set
			{
				paths.Value = value;
			}
		}

		public string Output
		{
			get
			{
				return output.Value;
			}
			set
			{
				output.Value = value;
			}
		}

		public string OutputNaPlaceholder
		{
			get
			{
				return outputNaPlaceholder.Value;
			}
			set
			{
				outputNaPlaceholder.Value = value;
			}
		}

		public bool RestrictFilenames
		{
			get
			{
				return restrictFilenames.Value;
			}
			set
			{
				restrictFilenames.Value = value;
			}
		}

		public bool NoRestrictFilenames
		{
			get
			{
				return noRestrictFilenames.Value;
			}
			set
			{
				noRestrictFilenames.Value = value;
			}
		}

		public bool WindowsFilenames
		{
			get
			{
				return windowsFilenames.Value;
			}
			set
			{
				windowsFilenames.Value = value;
			}
		}

		public bool NoWindowsFilenames
		{
			get
			{
				return noWindowsFilenames.Value;
			}
			set
			{
				noWindowsFilenames.Value = value;
			}
		}

		public int? TrimFilenames
		{
			get
			{
				return trimFilenames.Value;
			}
			set
			{
				trimFilenames.Value = value;
			}
		}

		public bool NoOverwrites
		{
			get
			{
				return noOverwrites.Value;
			}
			set
			{
				noOverwrites.Value = value;
			}
		}

		public bool ForceOverwrites
		{
			get
			{
				return forceOverwrites.Value;
			}
			set
			{
				forceOverwrites.Value = value;
			}
		}

		public bool NoForceOverwrites
		{
			get
			{
				return noForceOverwrites.Value;
			}
			set
			{
				noForceOverwrites.Value = value;
			}
		}

		public bool Continue
		{
			get
			{
				return doContinue.Value;
			}
			set
			{
				doContinue.Value = value;
			}
		}

		public bool NoContinue
		{
			get
			{
				return noContinue.Value;
			}
			set
			{
				noContinue.Value = value;
			}
		}

		public bool Part
		{
			get
			{
				return part.Value;
			}
			set
			{
				part.Value = value;
			}
		}

		public bool NoPart
		{
			get
			{
				return noPart.Value;
			}
			set
			{
				noPart.Value = value;
			}
		}

		public bool Mtime
		{
			get
			{
				return mtime.Value;
			}
			set
			{
				mtime.Value = value;
			}
		}

		public bool NoMtime
		{
			get
			{
				return noMtime.Value;
			}
			set
			{
				noMtime.Value = value;
			}
		}

		public bool WriteDescription
		{
			get
			{
				return writeDescription.Value;
			}
			set
			{
				writeDescription.Value = value;
			}
		}

		public bool NoWriteDescription
		{
			get
			{
				return noWriteDescription.Value;
			}
			set
			{
				noWriteDescription.Value = value;
			}
		}

		public bool WriteInfoJson
		{
			get
			{
				return writeInfoJson.Value;
			}
			set
			{
				writeInfoJson.Value = value;
			}
		}

		public bool NoWriteInfoJson
		{
			get
			{
				return noWriteInfoJson.Value;
			}
			set
			{
				noWriteInfoJson.Value = value;
			}
		}

		public bool WritePlaylistMetafiles
		{
			get
			{
				return writePlaylistMetafiles.Value;
			}
			set
			{
				writePlaylistMetafiles.Value = value;
			}
		}

		public bool NoWritePlaylistMetafiles
		{
			get
			{
				return noWritePlaylistMetafiles.Value;
			}
			set
			{
				noWritePlaylistMetafiles.Value = value;
			}
		}

		public bool CleanInfoJson
		{
			get
			{
				return cleanInfoJson.Value;
			}
			set
			{
				cleanInfoJson.Value = value;
			}
		}

		public bool NoCleanInfoJson
		{
			get
			{
				return noCleanInfoJson.Value;
			}
			set
			{
				noCleanInfoJson.Value = value;
			}
		}

		public bool WriteComments
		{
			get
			{
				return writeComments.Value;
			}
			set
			{
				writeComments.Value = value;
			}
		}

		public bool NoWriteComments
		{
			get
			{
				return noWriteComments.Value;
			}
			set
			{
				noWriteComments.Value = value;
			}
		}

		public string LoadInfoJson
		{
			get
			{
				return loadInfoJson.Value;
			}
			set
			{
				loadInfoJson.Value = value;
			}
		}

		public string Cookies
		{
			get
			{
				return cookies.Value;
			}
			set
			{
				cookies.Value = value;
			}
		}

		public bool NoCookies
		{
			get
			{
				return noCookies.Value;
			}
			set
			{
				noCookies.Value = value;
			}
		}

		public string CookiesFromBrowser
		{
			get
			{
				return cookiesFromBrowser.Value;
			}
			set
			{
				cookiesFromBrowser.Value = value;
			}
		}

		public bool NoCookiesFromBrowser
		{
			get
			{
				return noCookiesFromBrowser.Value;
			}
			set
			{
				noCookiesFromBrowser.Value = value;
			}
		}

		public string CacheDir
		{
			get
			{
				return cacheDir.Value;
			}
			set
			{
				cacheDir.Value = value;
			}
		}

		public bool NoCacheDir
		{
			get
			{
				return noCacheDir.Value;
			}
			set
			{
				noCacheDir.Value = value;
			}
		}

		public bool RemoveCacheDir
		{
			get
			{
				return removeCacheDir.Value;
			}
			set
			{
				removeCacheDir.Value = value;
			}
		}

		public bool Help
		{
			get
			{
				return help.Value;
			}
			set
			{
				help.Value = value;
			}
		}

		public bool Version
		{
			get
			{
				return version.Value;
			}
			set
			{
				version.Value = value;
			}
		}

		public bool Update
		{
			get
			{
				return update.Value;
			}
			set
			{
				update.Value = value;
			}
		}

		public bool NoUpdate
		{
			get
			{
				return noUpdate.Value;
			}
			set
			{
				noUpdate.Value = value;
			}
		}

		public string UpdateTo
		{
			get
			{
				return updateTo.Value;
			}
			set
			{
				updateTo.Value = value;
			}
		}

		public bool IgnoreErrors
		{
			get
			{
				return ignoreErrors.Value;
			}
			set
			{
				ignoreErrors.Value = value;
			}
		}

		public bool NoAbortOnError
		{
			get
			{
				return noAbortOnError.Value;
			}
			set
			{
				noAbortOnError.Value = value;
			}
		}

		public bool AbortOnError
		{
			get
			{
				return abortOnError.Value;
			}
			set
			{
				abortOnError.Value = value;
			}
		}

		public bool DumpUserAgent
		{
			get
			{
				return dumpUserAgent.Value;
			}
			set
			{
				dumpUserAgent.Value = value;
			}
		}

		public bool ListExtractors
		{
			get
			{
				return listExtractors.Value;
			}
			set
			{
				listExtractors.Value = value;
			}
		}

		public bool ExtractorDescriptions
		{
			get
			{
				return extractorDescriptions.Value;
			}
			set
			{
				extractorDescriptions.Value = value;
			}
		}

		public string UseExtractors
		{
			get
			{
				return useExtractors.Value;
			}
			set
			{
				useExtractors.Value = value;
			}
		}

		public string DefaultSearch
		{
			get
			{
				return defaultSearch.Value;
			}
			set
			{
				defaultSearch.Value = value;
			}
		}

		public bool IgnoreConfig
		{
			get
			{
				return ignoreConfig.Value;
			}
			set
			{
				ignoreConfig.Value = value;
			}
		}

		public bool NoConfigLocations
		{
			get
			{
				return noConfigLocations.Value;
			}
			set
			{
				noConfigLocations.Value = value;
			}
		}

		public MultiValue<string> ConfigLocations
		{
			get
			{
				return configLocations.Value;
			}
			set
			{
				configLocations.Value = value;
			}
		}

		public MultiValue<string> PluginDirs
		{
			get
			{
				return pluginDirs.Value;
			}
			set
			{
				pluginDirs.Value = value;
			}
		}

		public bool NoPluginDirs
		{
			get
			{
				return noPluginDirs.Value;
			}
			set
			{
				noPluginDirs.Value = value;
			}
		}

		public bool FlatPlaylist
		{
			get
			{
				return flatPlaylist.Value;
			}
			set
			{
				flatPlaylist.Value = value;
			}
		}

		public bool NoFlatPlaylist
		{
			get
			{
				return noFlatPlaylist.Value;
			}
			set
			{
				noFlatPlaylist.Value = value;
			}
		}

		public bool LiveFromStart
		{
			get
			{
				return liveFromStart.Value;
			}
			set
			{
				liveFromStart.Value = value;
			}
		}

		public bool NoLiveFromStart
		{
			get
			{
				return noLiveFromStart.Value;
			}
			set
			{
				noLiveFromStart.Value = value;
			}
		}

		public string WaitForVideo
		{
			get
			{
				return waitForVideo.Value;
			}
			set
			{
				waitForVideo.Value = value;
			}
		}

		public bool NoWaitForVideo
		{
			get
			{
				return noWaitForVideo.Value;
			}
			set
			{
				noWaitForVideo.Value = value;
			}
		}

		public bool MarkWatched
		{
			get
			{
				return markWatched.Value;
			}
			set
			{
				markWatched.Value = value;
			}
		}

		public bool NoMarkWatched
		{
			get
			{
				return noMarkWatched.Value;
			}
			set
			{
				noMarkWatched.Value = value;
			}
		}

		public MultiValue<string> Color
		{
			get
			{
				return color.Value;
			}
			set
			{
				color.Value = value;
			}
		}

		public string CompatOptions
		{
			get
			{
				return compatOptions.Value;
			}
			set
			{
				compatOptions.Value = value;
			}
		}

		public MultiValue<string> Alias
		{
			get
			{
				return alias.Value;
			}
			set
			{
				alias.Value = value;
			}
		}

		public string GeoVerificationProxy
		{
			get
			{
				return geoVerificationProxy.Value;
			}
			set
			{
				geoVerificationProxy.Value = value;
			}
		}

		public string Xff
		{
			get
			{
				return xff.Value;
			}
			set
			{
				xff.Value = value;
			}
		}

		public bool WriteLink
		{
			get
			{
				return writeLink.Value;
			}
			set
			{
				writeLink.Value = value;
			}
		}

		public bool WriteUrlLink
		{
			get
			{
				return writeUrlLink.Value;
			}
			set
			{
				writeUrlLink.Value = value;
			}
		}

		public bool WriteWeblocLink
		{
			get
			{
				return writeWeblocLink.Value;
			}
			set
			{
				writeWeblocLink.Value = value;
			}
		}

		public bool WriteDesktopLink
		{
			get
			{
				return writeDesktopLink.Value;
			}
			set
			{
				writeDesktopLink.Value = value;
			}
		}

		public string Proxy
		{
			get
			{
				return proxy.Value;
			}
			set
			{
				proxy.Value = value;
			}
		}

		public int? SocketTimeout
		{
			get
			{
				return socketTimeout.Value;
			}
			set
			{
				socketTimeout.Value = value;
			}
		}

		public string SourceAddress
		{
			get
			{
				return sourceAddress.Value;
			}
			set
			{
				sourceAddress.Value = value;
			}
		}

		public string Impersonate
		{
			get
			{
				return impersonate.Value;
			}
			set
			{
				impersonate.Value = value;
			}
		}

		public bool ListImpersonateTargets
		{
			get
			{
				return listImpersonateTargets.Value;
			}
			set
			{
				listImpersonateTargets.Value = value;
			}
		}

		public bool ForceIPv4
		{
			get
			{
				return forceIPv4.Value;
			}
			set
			{
				forceIPv4.Value = value;
			}
		}

		public bool ForceIPv6
		{
			get
			{
				return forceIPv6.Value;
			}
			set
			{
				forceIPv6.Value = value;
			}
		}

		public bool EnableFileUrls
		{
			get
			{
				return enableFileUrls.Value;
			}
			set
			{
				enableFileUrls.Value = value;
			}
		}

		public bool ExtractAudio
		{
			get
			{
				return extractAudio.Value;
			}
			set
			{
				extractAudio.Value = value;
			}
		}

		public AudioConversionFormat AudioFormat
		{
			get
			{
				return audioFormat.Value;
			}
			set
			{
				audioFormat.Value = value;
			}
		}

		public byte? AudioQuality
		{
			get
			{
				return audioQuality.Value;
			}
			set
			{
				audioQuality.Value = value;
			}
		}

		public string RemuxVideo
		{
			get
			{
				return remuxVideo.Value;
			}
			set
			{
				remuxVideo.Value = value;
			}
		}

		public VideoRecodeFormat RecodeVideo
		{
			get
			{
				return recodeVideo.Value;
			}
			set
			{
				recodeVideo.Value = value;
			}
		}

		public MultiValue<string> PostprocessorArgs
		{
			get
			{
				return postprocessorArgs.Value;
			}
			set
			{
				postprocessorArgs.Value = value;
			}
		}

		public bool KeepVideo
		{
			get
			{
				return keepVideo.Value;
			}
			set
			{
				keepVideo.Value = value;
			}
		}

		public bool NoKeepVideo
		{
			get
			{
				return noKeepVideo.Value;
			}
			set
			{
				noKeepVideo.Value = value;
			}
		}

		public bool PostOverwrites
		{
			get
			{
				return postOverwrites.Value;
			}
			set
			{
				postOverwrites.Value = value;
			}
		}

		public bool NoPostOverwrites
		{
			get
			{
				return noPostOverwrites.Value;
			}
			set
			{
				noPostOverwrites.Value = value;
			}
		}

		public bool EmbedSubs
		{
			get
			{
				return embedSubs.Value;
			}
			set
			{
				embedSubs.Value = value;
			}
		}

		public bool NoEmbedSubs
		{
			get
			{
				return noEmbedSubs.Value;
			}
			set
			{
				noEmbedSubs.Value = value;
			}
		}

		public bool EmbedThumbnail
		{
			get
			{
				return embedThumbnail.Value;
			}
			set
			{
				embedThumbnail.Value = value;
			}
		}

		public bool NoEmbedThumbnail
		{
			get
			{
				return noEmbedThumbnail.Value;
			}
			set
			{
				noEmbedThumbnail.Value = value;
			}
		}

		public bool EmbedMetadata
		{
			get
			{
				return embedMetadata.Value;
			}
			set
			{
				embedMetadata.Value = value;
			}
		}

		public bool NoEmbedMetadata
		{
			get
			{
				return noEmbedMetadata.Value;
			}
			set
			{
				noEmbedMetadata.Value = value;
			}
		}

		public bool EmbedChapters
		{
			get
			{
				return embedChapters.Value;
			}
			set
			{
				embedChapters.Value = value;
			}
		}

		public bool NoEmbedChapters
		{
			get
			{
				return noEmbedChapters.Value;
			}
			set
			{
				noEmbedChapters.Value = value;
			}
		}

		public bool EmbedInfoJson
		{
			get
			{
				return embedInfoJson.Value;
			}
			set
			{
				embedInfoJson.Value = value;
			}
		}

		public bool NoEmbedInfoJson
		{
			get
			{
				return noEmbedInfoJson.Value;
			}
			set
			{
				noEmbedInfoJson.Value = value;
			}
		}

		public string ParseMetadata
		{
			get
			{
				return parseMetadata.Value;
			}
			set
			{
				parseMetadata.Value = value;
			}
		}

		public MultiValue<string> ReplaceInMetadata
		{
			get
			{
				return replaceInMetadata.Value;
			}
			set
			{
				replaceInMetadata.Value = value;
			}
		}

		public bool Xattrs
		{
			get
			{
				return xattrs.Value;
			}
			set
			{
				xattrs.Value = value;
			}
		}

		public string ConcatPlaylist
		{
			get
			{
				return concatPlaylist.Value;
			}
			set
			{
				concatPlaylist.Value = value;
			}
		}

		public string Fixup
		{
			get
			{
				return fixup.Value;
			}
			set
			{
				fixup.Value = value;
			}
		}

		public string FfmpegLocation
		{
			get
			{
				return ffmpegLocation.Value;
			}
			set
			{
				ffmpegLocation.Value = value;
			}
		}

		public MultiValue<string> Exec
		{
			get
			{
				return exec.Value;
			}
			set
			{
				exec.Value = value;
			}
		}

		public bool NoExec
		{
			get
			{
				return noExec.Value;
			}
			set
			{
				noExec.Value = value;
			}
		}

		public string ConvertSubs
		{
			get
			{
				return convertSubs.Value;
			}
			set
			{
				convertSubs.Value = value;
			}
		}

		public string ConvertThumbnails
		{
			get
			{
				return convertThumbnails.Value;
			}
			set
			{
				convertThumbnails.Value = value;
			}
		}

		public bool SplitChapters
		{
			get
			{
				return splitChapters.Value;
			}
			set
			{
				splitChapters.Value = value;
			}
		}

		public bool NoSplitChapters
		{
			get
			{
				return noSplitChapters.Value;
			}
			set
			{
				noSplitChapters.Value = value;
			}
		}

		public MultiValue<string> RemoveChapters
		{
			get
			{
				return removeChapters.Value;
			}
			set
			{
				removeChapters.Value = value;
			}
		}

		public bool NoRemoveChapters
		{
			get
			{
				return noRemoveChapters.Value;
			}
			set
			{
				noRemoveChapters.Value = value;
			}
		}

		public bool ForceKeyframesAtCuts
		{
			get
			{
				return forceKeyframesAtCuts.Value;
			}
			set
			{
				forceKeyframesAtCuts.Value = value;
			}
		}

		public bool NoForceKeyframesAtCuts
		{
			get
			{
				return noForceKeyframesAtCuts.Value;
			}
			set
			{
				noForceKeyframesAtCuts.Value = value;
			}
		}

		public MultiValue<string> UsePostprocessor
		{
			get
			{
				return usePostprocessor.Value;
			}
			set
			{
				usePostprocessor.Value = value;
			}
		}

		public string SponsorblockMark
		{
			get
			{
				return sponsorblockMark.Value;
			}
			set
			{
				sponsorblockMark.Value = value;
			}
		}

		public string SponsorblockRemove
		{
			get
			{
				return sponsorblockRemove.Value;
			}
			set
			{
				sponsorblockRemove.Value = value;
			}
		}

		public string SponsorblockChapterTitle
		{
			get
			{
				return sponsorblockChapterTitle.Value;
			}
			set
			{
				sponsorblockChapterTitle.Value = value;
			}
		}

		public bool NoSponsorblock
		{
			get
			{
				return noSponsorblock.Value;
			}
			set
			{
				noSponsorblock.Value = value;
			}
		}

		public string SponsorblockApi
		{
			get
			{
				return sponsorblockApi.Value;
			}
			set
			{
				sponsorblockApi.Value = value;
			}
		}

		public bool WriteSubs
		{
			get
			{
				return writeSubs.Value;
			}
			set
			{
				writeSubs.Value = value;
			}
		}

		public bool NoWriteSubs
		{
			get
			{
				return noWriteSubs.Value;
			}
			set
			{
				noWriteSubs.Value = value;
			}
		}

		public bool WriteAutoSubs
		{
			get
			{
				return writeAutoSubs.Value;
			}
			set
			{
				writeAutoSubs.Value = value;
			}
		}

		public bool NoWriteAutoSubs
		{
			get
			{
				return noWriteAutoSubs.Value;
			}
			set
			{
				noWriteAutoSubs.Value = value;
			}
		}

		public bool ListSubs
		{
			get
			{
				return listSubs.Value;
			}
			set
			{
				listSubs.Value = value;
			}
		}

		public string SubFormat
		{
			get
			{
				return subFormat.Value;
			}
			set
			{
				subFormat.Value = value;
			}
		}

		public string SubLangs
		{
			get
			{
				return subLangs.Value;
			}
			set
			{
				subLangs.Value = value;
			}
		}

		public bool WriteThumbnail
		{
			get
			{
				return writeThumbnail.Value;
			}
			set
			{
				writeThumbnail.Value = value;
			}
		}

		public bool NoWriteThumbnail
		{
			get
			{
				return noWriteThumbnail.Value;
			}
			set
			{
				noWriteThumbnail.Value = value;
			}
		}

		public bool WriteAllThumbnails
		{
			get
			{
				return writeAllThumbnails.Value;
			}
			set
			{
				writeAllThumbnails.Value = value;
			}
		}

		public bool ListThumbnails
		{
			get
			{
				return listThumbnails.Value;
			}
			set
			{
				listThumbnails.Value = value;
			}
		}

		public bool Quiet
		{
			get
			{
				return quiet.Value;
			}
			set
			{
				quiet.Value = value;
			}
		}

		public bool NoQuiet
		{
			get
			{
				return noQuiet.Value;
			}
			set
			{
				noQuiet.Value = value;
			}
		}

		public bool NoWarnings
		{
			get
			{
				return noWarnings.Value;
			}
			set
			{
				noWarnings.Value = value;
			}
		}

		public bool Simulate
		{
			get
			{
				return simulate.Value;
			}
			set
			{
				simulate.Value = value;
			}
		}

		public bool NoSimulate
		{
			get
			{
				return noSimulate.Value;
			}
			set
			{
				noSimulate.Value = value;
			}
		}

		public bool IgnoreNoFormatsError
		{
			get
			{
				return ignoreNoFormatsError.Value;
			}
			set
			{
				ignoreNoFormatsError.Value = value;
			}
		}

		public bool NoIgnoreNoFormatsError
		{
			get
			{
				return noIgnoreNoFormatsError.Value;
			}
			set
			{
				noIgnoreNoFormatsError.Value = value;
			}
		}

		public bool SkipDownload
		{
			get
			{
				return skipDownload.Value;
			}
			set
			{
				skipDownload.Value = value;
			}
		}

		public MultiValue<string> Print
		{
			get
			{
				return print.Value;
			}
			set
			{
				print.Value = value;
			}
		}

		public MultiValue<string> PrintToFile
		{
			get
			{
				return printToFile.Value;
			}
			set
			{
				printToFile.Value = value;
			}
		}

		public bool DumpJson
		{
			get
			{
				return dumpJson.Value;
			}
			set
			{
				dumpJson.Value = value;
			}
		}

		public bool DumpSingleJson
		{
			get
			{
				return dumpSingleJson.Value;
			}
			set
			{
				dumpSingleJson.Value = value;
			}
		}

		public bool ForceWriteArchive
		{
			get
			{
				return forceWriteArchive.Value;
			}
			set
			{
				forceWriteArchive.Value = value;
			}
		}

		public bool Newline
		{
			get
			{
				return newline.Value;
			}
			set
			{
				newline.Value = value;
			}
		}

		public bool NoProgress
		{
			get
			{
				return noProgress.Value;
			}
			set
			{
				noProgress.Value = value;
			}
		}

		public bool Progress
		{
			get
			{
				return progress.Value;
			}
			set
			{
				progress.Value = value;
			}
		}

		public bool ConsoleTitle
		{
			get
			{
				return consoleTitle.Value;
			}
			set
			{
				consoleTitle.Value = value;
			}
		}

		public string ProgressTemplate
		{
			get
			{
				return progressTemplate.Value;
			}
			set
			{
				progressTemplate.Value = value;
			}
		}

		public string ProgressDelta
		{
			get
			{
				return progressDelta.Value;
			}
			set
			{
				progressDelta.Value = value;
			}
		}

		public bool Verbose
		{
			get
			{
				return verbose.Value;
			}
			set
			{
				verbose.Value = value;
			}
		}

		public bool DumpPages
		{
			get
			{
				return dumpPages.Value;
			}
			set
			{
				dumpPages.Value = value;
			}
		}

		public bool WritePages
		{
			get
			{
				return writePages.Value;
			}
			set
			{
				writePages.Value = value;
			}
		}

		public bool PrintTraffic
		{
			get
			{
				return printTraffic.Value;
			}
			set
			{
				printTraffic.Value = value;
			}
		}

		public string Format
		{
			get
			{
				return format.Value;
			}
			set
			{
				format.Value = value;
			}
		}

		public string FormatSort
		{
			get
			{
				return formatSort.Value;
			}
			set
			{
				formatSort.Value = value;
			}
		}

		public bool FormatSortForce
		{
			get
			{
				return formatSortForce.Value;
			}
			set
			{
				formatSortForce.Value = value;
			}
		}

		public bool NoFormatSortForce
		{
			get
			{
				return noFormatSortForce.Value;
			}
			set
			{
				noFormatSortForce.Value = value;
			}
		}

		public bool VideoMultistreams
		{
			get
			{
				return videoMultistreams.Value;
			}
			set
			{
				videoMultistreams.Value = value;
			}
		}

		public bool NoVideoMultistreams
		{
			get
			{
				return noVideoMultistreams.Value;
			}
			set
			{
				noVideoMultistreams.Value = value;
			}
		}

		public bool AudioMultistreams
		{
			get
			{
				return audioMultistreams.Value;
			}
			set
			{
				audioMultistreams.Value = value;
			}
		}

		public bool NoAudioMultistreams
		{
			get
			{
				return noAudioMultistreams.Value;
			}
			set
			{
				noAudioMultistreams.Value = value;
			}
		}

		public bool PreferFreeFormats
		{
			get
			{
				return preferFreeFormats.Value;
			}
			set
			{
				preferFreeFormats.Value = value;
			}
		}

		public bool NoPreferFreeFormats
		{
			get
			{
				return noPreferFreeFormats.Value;
			}
			set
			{
				noPreferFreeFormats.Value = value;
			}
		}

		public bool CheckFormats
		{
			get
			{
				return checkFormats.Value;
			}
			set
			{
				checkFormats.Value = value;
			}
		}

		public bool CheckAllFormats
		{
			get
			{
				return checkAllFormats.Value;
			}
			set
			{
				checkAllFormats.Value = value;
			}
		}

		public bool NoCheckFormats
		{
			get
			{
				return noCheckFormats.Value;
			}
			set
			{
				noCheckFormats.Value = value;
			}
		}

		public bool ListFormats
		{
			get
			{
				return listFormats.Value;
			}
			set
			{
				listFormats.Value = value;
			}
		}

		public DownloadMergeFormat MergeOutputFormat
		{
			get
			{
				return mergeOutputFormat.Value;
			}
			set
			{
				mergeOutputFormat.Value = value;
			}
		}

		public string PlaylistItems
		{
			get
			{
				return playlistItems.Value;
			}
			set
			{
				playlistItems.Value = value;
			}
		}

		public string MinFilesize
		{
			get
			{
				return minFilesize.Value;
			}
			set
			{
				minFilesize.Value = value;
			}
		}

		public string MaxFilesize
		{
			get
			{
				return maxFilesize.Value;
			}
			set
			{
				maxFilesize.Value = value;
			}
		}

		public DateTime Date
		{
			get
			{
				return date.Value;
			}
			set
			{
				date.Value = value;
			}
		}

		public DateTime DateBefore
		{
			get
			{
				return dateBefore.Value;
			}
			set
			{
				dateBefore.Value = value;
			}
		}

		public DateTime DateAfter
		{
			get
			{
				return dateAfter.Value;
			}
			set
			{
				dateAfter.Value = value;
			}
		}

		public MultiValue<string> MatchFilters
		{
			get
			{
				return matchFilters.Value;
			}
			set
			{
				matchFilters.Value = value;
			}
		}

		public bool NoMatchFilters
		{
			get
			{
				return noMatchFilters.Value;
			}
			set
			{
				noMatchFilters.Value = value;
			}
		}

		public string BreakMatchFilters
		{
			get
			{
				return breakMatchFilters.Value;
			}
			set
			{
				breakMatchFilters.Value = value;
			}
		}

		public bool NoBreakMatchFilters
		{
			get
			{
				return noBreakMatchFilters.Value;
			}
			set
			{
				noBreakMatchFilters.Value = value;
			}
		}

		public bool NoPlaylist
		{
			get
			{
				return noPlaylist.Value;
			}
			set
			{
				noPlaylist.Value = value;
			}
		}

		public bool YesPlaylist
		{
			get
			{
				return yesPlaylist.Value;
			}
			set
			{
				yesPlaylist.Value = value;
			}
		}

		public byte? AgeLimit
		{
			get
			{
				return ageLimit.Value;
			}
			set
			{
				ageLimit.Value = value;
			}
		}

		public string DownloadArchive
		{
			get
			{
				return downloadArchive.Value;
			}
			set
			{
				downloadArchive.Value = value;
			}
		}

		public bool NoDownloadArchive
		{
			get
			{
				return noDownloadArchive.Value;
			}
			set
			{
				noDownloadArchive.Value = value;
			}
		}

		public int? MaxDownloads
		{
			get
			{
				return maxDownloads.Value;
			}
			set
			{
				maxDownloads.Value = value;
			}
		}

		public bool BreakOnExisting
		{
			get
			{
				return breakOnExisting.Value;
			}
			set
			{
				breakOnExisting.Value = value;
			}
		}

		public bool NoBreakOnExisting
		{
			get
			{
				return noBreakOnExisting.Value;
			}
			set
			{
				noBreakOnExisting.Value = value;
			}
		}

		public bool BreakPerInput
		{
			get
			{
				return breakPerInput.Value;
			}
			set
			{
				breakPerInput.Value = value;
			}
		}

		public bool NoBreakPerInput
		{
			get
			{
				return noBreakPerInput.Value;
			}
			set
			{
				noBreakPerInput.Value = value;
			}
		}

		public int? SkipPlaylistAfterErrors
		{
			get
			{
				return skipPlaylistAfterErrors.Value;
			}
			set
			{
				skipPlaylistAfterErrors.Value = value;
			}
		}

		public string Encoding
		{
			get
			{
				return encoding.Value;
			}
			set
			{
				encoding.Value = value;
			}
		}

		public bool LegacyServerConnect
		{
			get
			{
				return legacyServerConnect.Value;
			}
			set
			{
				legacyServerConnect.Value = value;
			}
		}

		public bool NoCheckCertificates
		{
			get
			{
				return noCheckCertificates.Value;
			}
			set
			{
				noCheckCertificates.Value = value;
			}
		}

		public bool PreferInsecure
		{
			get
			{
				return preferInsecure.Value;
			}
			set
			{
				preferInsecure.Value = value;
			}
		}

		public MultiValue<string> AddHeaders
		{
			get
			{
				return addHeaders.Value;
			}
			set
			{
				addHeaders.Value = value;
			}
		}

		public bool BidiWorkaround
		{
			get
			{
				return bidiWorkaround.Value;
			}
			set
			{
				bidiWorkaround.Value = value;
			}
		}

		public int? SleepRequests
		{
			get
			{
				return sleepRequests.Value;
			}
			set
			{
				sleepRequests.Value = value;
			}
		}

		public int? SleepInterval
		{
			get
			{
				return sleepInterval.Value;
			}
			set
			{
				sleepInterval.Value = value;
			}
		}

		public int? MaxSleepInterval
		{
			get
			{
				return maxSleepInterval.Value;
			}
			set
			{
				maxSleepInterval.Value = value;
			}
		}

		public int? SleepSubtitles
		{
			get
			{
				return sleepSubtitles.Value;
			}
			set
			{
				sleepSubtitles.Value = value;
			}
		}

		public void WriteConfigFile(string path)
		{
			File.WriteAllLines(path, GetOptionFlags());
		}

		public override string ToString()
		{
			return " " + string.Join(" ", GetOptionFlags());
		}

		public IEnumerable<string> GetOptionFlags()
		{
			return from value in GetKnownOptions().Concat(CustomOptions).SelectMany((IOption opt) => opt.ToStringCollection())
				where !string.IsNullOrWhiteSpace(value)
				select value;
		}

		internal IEnumerable<IOption> GetKnownOptions()
		{
			return (from p in GetType().GetRuntimeFields()
				where p.FieldType.IsGenericType && p.FieldType.GetInterfaces().Contains(typeof(IOption))
				select p.GetValue(this)).Cast<IOption>();
		}

		public OptionSet OverrideOptions(OptionSet overrideOptions, bool forceOverride = false)
		{
			OptionSet optionSet = (OptionSet)Clone();
			optionSet.CustomOptions = optionSet.CustomOptions.Concat(overrideOptions.CustomOptions).Distinct(Comparer).ToArray();
			foreach (FieldInfo item in from p in overrideOptions.GetType().GetRuntimeFields()
				where p.FieldType.IsGenericType && p.FieldType.GetInterfaces().Contains(typeof(IOption))
				select p)
			{
				IOption option = (IOption)item.GetValue(overrideOptions);
				if (forceOverride || option.IsSet)
				{
					optionSet.GetType().GetField(item.Name, BindingFlags.Instance | BindingFlags.NonPublic).SetValue(optionSet, option);
				}
			}
			return optionSet;
		}

		public static OptionSet FromString(IEnumerable<string> lines)
		{
			OptionSet optionSet = new OptionSet();
			IOption[] customOptions = (from option in GetOptions(lines, optionSet.GetKnownOptions())
				where option.IsCustom
				select option).ToArray();
			optionSet.CustomOptions = customOptions;
			return optionSet;
		}

		private static IEnumerable<IOption> GetOptions(IEnumerable<string> lines, IEnumerable<IOption> options)
		{
			IEnumerable<IOption> knownOptions = options.ToList();
			foreach (string line in lines)
			{
				string text = line.Trim();
				if (!text.StartsWith("#") && !string.IsNullOrWhiteSpace(text))
				{
					string[] array = text.Split(new char[1] { ' ' });
					string flag = array[0];
					IOption option = knownOptions.FirstOrDefault((IOption o) => o.OptionStrings.Contains(flag));
					IOption option3;
					if (array.Length <= 1)
					{
						IOption option2 = new Option<bool>(true, flag);
						option3 = option2;
					}
					else
					{
						IOption option2 = new Option<string>(true, flag);
						option3 = option2;
					}
					IOption option4 = option3;
					IOption option5 = option ?? option4;
					option5.SetFromString(text);
					yield return option5;
				}
			}
		}

		public static OptionSet LoadConfigFile(string path)
		{
			return FromString(File.ReadAllLines(path));
		}

		public object Clone()
		{
			return FromString(GetOptionFlags());
		}

		public void AddCustomOption<T>(string optionString, T value)
		{
			Option<T> option = new Option<T>(true, optionString);
			option.Value = value;
			CustomOptions = CustomOptions.Concat(new Option<T>[1] { option }).ToArray();
		}

		public void SetCustomOption<T>(string optionString, T value)
		{
			foreach (IOption item in CustomOptions.Where((IOption o) => o.OptionStrings.Contains(optionString)))
			{
				if (item is Option<T> option)
				{
					option.Value = value;
					continue;
				}
				throw new ArgumentException($"Value passed to option '{optionString}' has invalid type '{value.GetType()}'.");
			}
		}

		public void DeleteCustomOption(string optionString)
		{
			CustomOptions = CustomOptions.Where((IOption o) => !o.OptionStrings.Contains(optionString)).ToArray();
		}
	}
	internal static class Utils
	{
		internal static T OptionValueFromString<T>(string stringValue)
		{
			if (typeof(T) == typeof(bool))
			{
				return (T)(object)true;
			}
			if (typeof(T) == typeof(Enum))
			{
				string value = CultureInfo.InvariantCulture.TextInfo.ToTitleCase(stringValue);
				return (T)Enum.Parse(typeof(T), value);
			}
			if (typeof(T) == typeof(DateTime))
			{
				return (T)(object)DateTime.ParseExact(stringValue, "yyyyMMdd", null);
			}
			return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(stringValue);
		}

		internal static string OptionValueToString<T>(T value)
		{
			if (value is bool)
			{
				return string.Empty;
			}
			if (value is Enum)
			{
				return " \"" + value.ToString().ToLower() + "\"";
			}
			if (value is DateTime)
			{
				object obj = value;
				return " " + ((DateTime)((obj is DateTime) ? obj : null)).ToString("yyyyMMdd");
			}
			if (value is string)
			{
				return $" \"{value}\"";
			}
			T val = value;
			return " " + val;
		}
	}
}
namespace YoutubeDLSharp.Metadata
{
	public class ChapterData
	{
		[JsonProperty("start_time")]
		public float? StartTime { get; set; }

		[JsonProperty("end_time")]
		public float? EndTime { get; set; }

		[JsonProperty("title")]
		public string Title { get; set; }
	}
	public class CommentData
	{
		[JsonProperty("id")]
		public string ID { get; set; }

		[JsonProperty("author")]
		public string Author { get; set; }

		[JsonProperty("author_id")]
		public string AuthorID { get; set; }

		[JsonProperty("author_thumbnail")]
		public string AuthorThumbnail { get; set; }

		[JsonProperty("html")]
		public string Html { get; set; }

		[JsonProperty("text")]
		public string Text { get; set; }

		[JsonProperty("timestamp")]
		[JsonConverter(typeof(UnixTimestampConverter))]
		public DateTime Timestamp { get; set; }

		[JsonProperty("parent")]
		public string Parent { get; set; }

		[JsonProperty("like_count")]
		public int? LikeCount { get; set; }

		[JsonProperty("dislike_count")]
		public int? DislikeCount { get; set; }

		[JsonProperty("is_favorited")]
		public bool? IsFavorited { get; set; }

		[JsonProperty("author_is_uploader")]
		public bool? AuthorIsUploader { get; set; }
	}
	public class FormatData
	{
		[JsonProperty("url")]
		public string Url { get; 

Mods/RealRadio/YtDlp.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Threading;
using System.Threading.Tasks;
using HashUtility;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using YoutubeDLSharp;
using YoutubeDLSharp.Metadata;
using YoutubeDLSharp.Options;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("YtDlp")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+1cd90b6bdac1f314159cb7e67c99a8412d514dd2")]
[assembly: AssemblyProduct("YtDlp")]
[assembly: AssemblyTitle("YtDlp")]
[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;
		}
	}
}
public class YtDlpException : Exception
{
	public string[] Errors { get; set; }

	public YtDlpException(string[] errors)
	{
		Errors = errors;
		base..ctor("The YtDlp process exited with errors:\n\t" + ConcatErrors(errors));
	}

	private static string ConcatErrors(string[] errors)
	{
		return string.Join("\n\t", errors);
	}
}
public class YtDlpVideoDownloadException : YtDlpException
{
	public YtDlpVideoDownloadException(string[] errors)
		: base(errors)
	{
	}
}
public class YtDlpFetchMetaDataException : YtDlpException
{
	public YtDlpFetchMetaDataException(string[] errors)
		: base(errors)
	{
	}
}
public class YtDlpDownloadPlaylistUrlsException : YtDlpException
{
	public YtDlpDownloadPlaylistUrlsException(string[] errors)
		: base(errors)
	{
	}
}
public class YtDlp
{
	private YoutubeDL youtubeDL;

	private readonly string cachePath;

	private readonly string binariesPath;

	private readonly string audioFilesPath;

	private readonly string ytDlpCachePath;

	private Task? downloadBinariesTask;

	private bool binariesDownloaded;

	private object downloadMetaLock = new object();

	private object downloadAudioFileLock = new object();

	private Dictionary<string, Task<VideoData>> downloadMetaTasks = new Dictionary<string, Task<VideoData>>();

	private Dictionary<string, Task<string>> downloadAudioFileTasks = new Dictionary<string, Task<string>>();

	public YtDlp(string cachePath, byte maxNumberOfProcesses = 4)
	{
		//IL_006e: 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_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Expected O, but got Unknown
		this.cachePath = cachePath;
		binariesPath = Path.Combine(cachePath, "bin");
		audioFilesPath = Path.Combine(cachePath, "audio");
		ytDlpCachePath = Path.Combine(cachePath, "yt-dlp");
		youtubeDL = new YoutubeDL(maxNumberOfProcesses)
		{
			FFmpegPath = Path.Combine(binariesPath, Utils.FfmpegBinaryName),
			YoutubeDLPath = Path.Combine(binariesPath, Utils.YtDlpBinaryName),
			OutputFolder = Path.Combine(cachePath, "audio")
		};
		if (!Directory.Exists(binariesPath))
		{
			Directory.CreateDirectory(binariesPath);
		}
		if (!Directory.Exists(audioFilesPath))
		{
			Directory.CreateDirectory(audioFilesPath);
		}
		if (!Directory.Exists(ytDlpCachePath))
		{
			Directory.CreateDirectory(ytDlpCachePath);
		}
		downloadBinariesTask = DownloadBinaries();
	}

	public async Task DownloadBinaries()
	{
		if (downloadBinariesTask != null)
		{
			await downloadBinariesTask;
		}
		else if (!binariesDownloaded)
		{
			await Task.Run(async delegate
			{
				await Utils.DownloadBinaries(true, binariesPath);
				binariesDownloaded = true;
			});
		}
	}

	public Task<string> DownloadAudioFile(string url, CancellationToken cancellationToken, IProgress<DownloadProgress>? progress = null, IProgress<string>? output = null)
	{
		string url2 = url;
		IProgress<DownloadProgress> progress2 = progress;
		IProgress<string> output2 = output;
		lock (downloadAudioFileLock)
		{
			if (downloadAudioFileTasks.TryGetValue(url2, out Task<string> value))
			{
				return value;
			}
			Task<string> task = Task.Run(async delegate
			{
				_ = 1;
				try
				{
					await DownloadBinaries();
					uint num = HashUrl(url2);
					string path = $"{num}.m4a";
					if (File.Exists(Path.Combine(audioFilesPath, path)))
					{
						return Path.Combine(audioFilesPath, path);
					}
					OptionSet val = new OptionSet
					{
						CacheDir = ytDlpCachePath,
						AudioQuality = (byte)5,
						Output = Path.Combine(audioFilesPath, path),
						Progress = true,
						Format = "ba[acodec^=aac]/ba[acodec^=mp4a.40.]/ba/b",
						NoWarnings = true
					};
					RunResult<string> val2 = await youtubeDL.RunAudioDownload(url2, (AudioConversionFormat)4, cancellationToken, progress2, output2, val);
					if (!val2.Success)
					{
						throw new YtDlpVideoDownloadException(val2.ErrorOutput);
					}
					return val2.Data;
				}
				finally
				{
					lock (downloadAudioFileLock)
					{
						downloadAudioFileTasks.Remove(url2);
					}
				}
			});
			downloadAudioFileTasks[url2] = task;
			return task;
		}
	}

	public Task<VideoData> DownloadMetaData(string url, CancellationToken cancellationToken)
	{
		string url2 = url;
		lock (downloadMetaLock)
		{
			if (downloadMetaTasks.TryGetValue(url2, out Task<VideoData> value))
			{
				return value;
			}
			Task<VideoData> task = Task.Run<VideoData>(async delegate
			{
				_ = 5;
				try
				{
					await DownloadBinaries();
					uint num = HashUrl(url2);
					string filePath = Path.Combine(audioFilesPath, $"{num}.json");
					RunResult<VideoData> result2;
					if (!File.Exists(Path.Combine(audioFilesPath, $"{num}.json")))
					{
						result2 = await youtubeDL.RunVideoDataFetch(url2, cancellationToken, true, false, (OptionSet)null);
						if (!result2.Success)
						{
							throw new YtDlpFetchMetaDataException(result2.ErrorOutput);
						}
						await File.WriteAllTextAsync(filePath, JsonConvert.SerializeObject((object)result2.Data));
					}
					else
					{
						VideoData videoData;
						try
						{
							videoData = JsonConvert.DeserializeObject<VideoData>(await File.ReadAllTextAsync(filePath));
						}
						catch
						{
							result2 = await youtubeDL.RunVideoDataFetch(url2, cancellationToken, true, false, (OptionSet)null);
							if (!result2.Success)
							{
								throw new YtDlpFetchMetaDataException(result2.ErrorOutput);
							}
							await File.WriteAllTextAsync(filePath, JsonConvert.SerializeObject((object)result2.Data));
							videoData = result2.Data;
						}
						result2 = new RunResult<VideoData>(true, Array.Empty<string>(), videoData);
					}
					return result2.Data;
				}
				finally
				{
					lock (downloadMetaLock)
					{
						downloadMetaTasks.Remove(url2);
					}
				}
			});
			downloadMetaTasks[url2] = task;
			return task;
		}
	}

	public async Task UpdateCachedMetaData(string url, VideoData metaData)
	{
		uint num = HashUrl(url);
		await File.WriteAllTextAsync(Path.Combine(audioFilesPath, $"{num}.json"), JsonConvert.SerializeObject((object)metaData));
	}

	private uint HashUrl(string url)
	{
		Uri uri = new Uri(url);
		url = uri.Host + uri.PathAndQuery;
		return StringHashing.GetStableHashCode(uri.PathAndQuery);
	}

	public async Task<VideoData[]> DownloadPlaylistUrls(string[] urls, CancellationToken token)
	{
		OptionSet val = new OptionSet
		{
			FlatPlaylist = true,
			DumpJson = true,
			Simulate = true
		};
		RunResult<string[]> val2 = await youtubeDL.RunWithOptions(urls, val, token);
		if (!val2.Success)
		{
			throw new YtDlpDownloadPlaylistUrlsException(val2.ErrorOutput);
		}
		List<VideoData> list = new List<VideoData>();
		string[] data = val2.Data;
		foreach (string text in data)
		{
			try
			{
				VideoData val3 = JsonConvert.DeserializeObject<VideoData>(text);
				if ((int)val3.ResultType == 3 && (!val3.Title.StartsWith("[") || !val3.Title.EndsWith("]") || !val3.Title.Contains("video", StringComparison.OrdinalIgnoreCase)))
				{
					list.Add(val3);
				}
			}
			catch
			{
			}
		}
		return list.ToArray();
	}
}