Decompiled source of WL VLC Cinema v1.2.1

BepInEx/plugins/wlVLC/LibVLCSharp.dll

Decompiled a month ago
#define TRACE
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
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 System.Threading.Tasks;
using LibVLCSharp.Shared.Helpers;
using LibVLCSharp.Shared.Structures;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("LibVLCSharp.Forms")]
[assembly: InternalsVisibleTo("LibVLCSharp.MAUI")]
[assembly: InternalsVisibleTo("LibVLCSharp.Uno")]
[assembly: TargetFramework(".NETFramework,Version=v4.0", FrameworkDisplayName = ".NET Framework 4")]
[assembly: AssemblyCompany("VideoLAN")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("LibVLCSharp is a cross-platform audio and video API for .NET platforms based on VideoLAN's LibVLC Library. It provides a comprehensive multimedia API that can be used across mobile, server and desktop to render video and output audio. Mono, .NET Framework and .NET Core runtimes are supported.\n\nThis package contains the core features of LibVLCSharp (libvlc loading and initialization, .NET-friendly classes to ease the use of libvlc...). All other `LibVLCSharp.*` packages depend on this one.\nFeatures:\n- Play every media file formats, every codec and every streaming protocols\n- Run on every platform, from desktop (Windows, Linux, Mac) to mobile (Android, iOS) and TVs\n- Hardware and efficient decoding on every platform, up to 8K\n- Network browsing for distant filesystems (SMB, FTP, SFTP, NFS...) and servers (UPnP, DLNA)\n- Playback of Audio CD, DVD and Bluray with menu navigation\n- Support for HDR, including tonemapping for SDR streams\n- Audio passthrough with SPDIF and HDMI, including for Audio HD codecs, like DD+, TrueHD or DTS-HD\n- Support for video and audio filters\n- Support for 360 video and 3D audio playback, including Ambisonics\n- Able to cast and stream to distant renderers, like Chromecast and UPnP renderers.\n\nThis package also contains the views for the following platforms:\n\n- Android\n- iOS\n- Mac\n- tvOS\n- UWP\n\nIf you need Xamarin.Forms support, see LibVLCSharp.Forms. \n\nLibVLC needs to be installed separately, see VideoLAN.LibVLC.* packages.")]
[assembly: AssemblyFileVersion("3.9.4.0")]
[assembly: AssemblyInformationalVersion("3.9.4+f08446b3fda43c7801b156a581fac8962bbf5466")]
[assembly: AssemblyProduct("LibVLCSharp")]
[assembly: AssemblyTitle("LibVLCSharp")]
[assembly: NeutralResourcesLanguage("en")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("3.9.4.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[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]
	[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 LibVLCSharp.Shared
{
	internal static class Constants
	{
		internal const string LibraryName = "libvlc";

		internal const string CoreLibraryName = "libvlccore";

		internal const string LibrariesRepositoryFolderName = "libvlc";

		internal const string Msvcrt = "msvcrt";

		internal const string Libc = "libc";

		internal const string LibSystem = "libSystem";

		internal const string Kernel32 = "kernel32";

		internal const string WindowsLibraryExtension = ".dll";

		internal const string MacLibraryExtension = ".dylib";

		internal const string Lib = "lib";

		internal const string LibVLC = "libvlc";
	}
	internal static class ArchitectureNames
	{
		internal const string Win64 = "win-x64";

		internal const string Win86 = "win-x86";

		internal const string MacOS64 = "osx-x64";
	}
	[Flags]
	internal enum ErrorModes : uint
	{
		SYSTEM_DEFAULT = 0u,
		SEM_FAILCRITICALERRORS = 1u,
		SEM_NOALIGNMENTFAULTEXCEPT = 4u,
		SEM_NOGPFAULTERRORBOX = 2u,
		SEM_NOOPENFILEERRORBOX = 0x8000u
	}
	public static class Core
	{
		[StructLayout(LayoutKind.Sequential, Size = 1)]
		private struct Native
		{
			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_get_version")]
			internal static extern IntPtr LibVLCVersion();

			[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
			internal static extern IntPtr LoadLibraryW(string dllToLoad);

			[DllImport("libSystem", EntryPoint = "dlopen")]
			internal static extern IntPtr Dlopen(string libraryPath, int mode = 1);

			[DllImport("kernel32", SetLastError = true)]
			internal static extern ErrorModes SetErrorMode(ErrorModes uMode);
		}

		private static bool _libvlcLoaded;

		private static IntPtr LibvlcHandle;

		private static IntPtr LibvlccoreHandle;

		private static string LibraryExtension
		{
			get
			{
				if (!PlatformHelper.IsWindows)
				{
					return ".dylib";
				}
				return ".dll";
			}
		}

		internal static bool LibVLCLoaded
		{
			get
			{
				if (!_libvlcLoaded)
				{
					return LibvlcHandle != IntPtr.Zero;
				}
				return true;
			}
			set
			{
				_libvlcLoaded = value;
			}
		}

		private static void EnsureVersionsMatch()
		{
			int num = int.Parse(Native.LibVLCVersion().FromUtf8()?.Split(new char[1] { '.' }).FirstOrDefault() ?? "0");
			int? num2 = Assembly.GetExecutingAssembly().GetName().Version?.Major;
			if (num != num2)
			{
				throw new VLCException($"Version mismatch between LibVLC {num} and LibVLCSharp {num2}. " + "They must share the same major version number");
			}
		}

		private static string LibVLCPath(string dir)
		{
			return Path.Combine(dir, "libvlc" + LibraryExtension);
		}

		private static string LibVLCCorePath(string dir)
		{
			return Path.Combine(dir, "libvlccore" + LibraryExtension);
		}

		private static void Log(string message)
		{
			Trace.WriteLine(message);
		}

		private static List<(string libvlccore, string libvlc)> ComputeLibVLCSearchPaths()
		{
			List<(string, string)> list = new List<(string, string)>();
			string path = ((!PlatformHelper.IsMac) ? (PlatformHelper.IsX64BitProcess ? "win-x64" : "win-x86") : Path.Combine("osx-x64", "lib"));
			string location = typeof(LibVLC).Assembly.Location;
			string dir = Path.Combine(Path.GetDirectoryName(location), "libvlc", path);
			string item = LibVLCCorePath(dir);
			string item2 = LibVLCPath(dir);
			list.Add((item, item2));
			string text = Assembly.GetEntryAssembly()?.Location ?? Assembly.GetExecutingAssembly()?.Location;
			if (!string.IsNullOrEmpty(text))
			{
				string dir2 = Path.Combine(Path.GetDirectoryName(text), "libvlc", path);
				string item3 = string.Empty;
				if (PlatformHelper.IsWindows)
				{
					item3 = LibVLCCorePath(dir2);
				}
				string item4 = LibVLCPath(dir2);
				list.Add((item3, item4));
			}
			string item5 = LibVLCPath(Path.GetDirectoryName(location));
			list.Add((string.Empty, item5));
			if (PlatformHelper.IsMac)
			{
				string item6 = Path.Combine(Path.Combine(Path.GetDirectoryName(location), "lib"), "libvlc" + LibraryExtension);
				string item7 = LibVLCCorePath(Path.Combine(Path.GetDirectoryName(location), "lib"));
				list.Add((item7, item6));
			}
			return list;
		}

		private static void LoadLibVLC(string? libvlcDirectoryPath = null)
		{
			if (!string.IsNullOrEmpty(libvlcDirectoryPath))
			{
				string text = LibVLCCorePath(libvlcDirectoryPath);
				if (!LoadNativeLibrary(text, out LibvlccoreHandle))
				{
					Log("Failed to load required native libraries at " + text);
					return;
				}
				string text2 = LibVLCPath(libvlcDirectoryPath);
				if (!LoadNativeLibrary(text2, out LibvlcHandle))
				{
					Log("Failed to load required native libraries at " + text2);
				}
				return;
			}
			List<(string, string)> list = ComputeLibVLCSearchPaths();
			foreach (var (nativeLibraryPath, nativeLibraryPath2) in list)
			{
				LoadNativeLibrary(nativeLibraryPath, out LibvlccoreHandle);
				if (LoadNativeLibrary(nativeLibraryPath2, out LibvlcHandle))
				{
					break;
				}
			}
			if (LibVLCLoaded)
			{
				return;
			}
			throw new VLCException("Failed to load required native libraries. " + Environment.NewLine + "Have you installed the latest LibVLC package from nuget for your target platform?" + Environment.NewLine + "Search paths include " + string.Join("; ", list.Select<(string, string), string>(((string libvlccore, string libvlc) p) => p.libvlc + "," + p.libvlccore)));
		}

		internal static void EnsureLoaded()
		{
			if (!LibVLCLoaded)
			{
				Initialize();
			}
		}

		private static bool LoadNativeLibrary(string nativeLibraryPath, out IntPtr handle)
		{
			handle = IntPtr.Zero;
			Log("Loading " + nativeLibraryPath);
			if (!File.Exists(nativeLibraryPath))
			{
				Log("Cannot find " + nativeLibraryPath);
				return false;
			}
			if (PlatformHelper.IsMac)
			{
				handle = Native.Dlopen(nativeLibraryPath);
			}
			else
			{
				handle = Native.LoadLibraryW(nativeLibraryPath);
			}
			return handle != IntPtr.Zero;
		}

		public static void Initialize(string? libvlcDirectoryPath = null)
		{
			DisableMessageErrorBox();
			InitializeDesktop(libvlcDirectoryPath);
			EnsureVersionsMatch();
			LibVLCLoaded = true;
		}

		private static void DisableMessageErrorBox()
		{
			if (PlatformHelper.IsWindows)
			{
				Native.SetErrorMode(Native.SetErrorMode(ErrorModes.SYSTEM_DEFAULT) | ErrorModes.SEM_FAILCRITICALERRORS | ErrorModes.SEM_NOOPENFILEERRORBOX);
			}
		}

		private static void InitializeDesktop(string? libvlcDirectoryPath = null)
		{
			if (PlatformHelper.IsLinux)
			{
				if (!string.IsNullOrEmpty(libvlcDirectoryPath))
				{
					throw new InvalidOperationException("Using libvlcDirectoryPath is not supported on the Linux platform. The recommended way is to have the libvlc librairies in /usr/lib. Use LD_LIBRARY_PATH if you need more customization");
				}
			}
			else
			{
				LoadLibVLC(libvlcDirectoryPath);
			}
		}
	}
	public class Dialog
	{
		[StructLayout(LayoutKind.Sequential, Size = 1)]
		private struct Native
		{
			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_dialog_post_login")]
			internal static extern int LibVLCDialogPostLogin(IntPtr dialogId, IntPtr username, IntPtr password, bool store);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_dialog_post_action")]
			internal static extern int LibVLCDialogPostAction(IntPtr dialogId, int actionIndex);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_dialog_dismiss")]
			internal static extern int LibVLCDialogDismiss(IntPtr dialogId);
		}

		private IntPtr _id;

		private Dialog(IntPtr id)
		{
			if (id == IntPtr.Zero)
			{
				throw new ArgumentNullException("id");
			}
			_id = id;
		}

		internal Dialog(DialogId id)
			: this(id.NativeReference)
		{
		}

		public bool PostLogin(string? username, string? password, bool store)
		{
			if (_id == IntPtr.Zero)
			{
				throw new VLCException("Calling method on dismissed Dialog instance");
			}
			if (username == null)
			{
				username = string.Empty;
			}
			if (password == null)
			{
				password = string.Empty;
			}
			IntPtr usernamePtr = username.ToUtf8();
			IntPtr passwordPtr = password.ToUtf8();
			bool result = MarshalUtils.PerformInteropAndFree(() => Native.LibVLCDialogPostLogin(_id, usernamePtr, passwordPtr, store), usernamePtr, passwordPtr) == 0;
			_id = IntPtr.Zero;
			return result;
		}

		public bool PostAction(int actionIndex)
		{
			if (_id == IntPtr.Zero)
			{
				throw new VLCException("Calling method on dismissed Dialog instance");
			}
			bool result = Native.LibVLCDialogPostAction(_id, actionIndex) == 0;
			_id = IntPtr.Zero;
			return result;
		}

		public bool Dismiss()
		{
			if (_id == IntPtr.Zero)
			{
				return false;
			}
			bool result = Native.LibVLCDialogDismiss(_id) == 0;
			_id = IntPtr.Zero;
			return result;
		}
	}
	internal readonly struct DialogId
	{
		internal IntPtr NativeReference { get; }

		internal DialogId(IntPtr nativeReference)
		{
			NativeReference = nativeReference;
		}
	}
	public enum DialogQuestionType
	{
		Normal,
		Warning,
		Critical
	}
	public delegate Task DisplayError(string? title, string? text);
	public delegate Task DisplayLogin(Dialog dialog, string? title, string? text, string? defaultUsername, bool askStore, CancellationToken token);
	public delegate Task DisplayQuestion(Dialog dialog, string? title, string? text, DialogQuestionType type, string? cancelText, string? firstActionText, string? secondActionText, CancellationToken token);
	public delegate Task DisplayProgress(Dialog dialog, string? title, string? text, bool indeterminate, float position, string? cancelText, CancellationToken token);
	public delegate Task UpdateProgress(Dialog dialog, float position, string? text);
	public class Equalizer : Internal
	{
		[StructLayout(LayoutKind.Sequential, Size = 1)]
		private struct Native
		{
			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_audio_equalizer_new")]
			internal static extern IntPtr LibVLCAudioEqualizerNew();

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_audio_equalizer_release")]
			internal static extern void LibVLCAudioEqualizerRelease(IntPtr equalizer);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_audio_equalizer_new_from_preset")]
			internal static extern IntPtr LibVLCAudioEqualizerNewFromPreset(uint index);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_audio_equalizer_set_preamp")]
			internal static extern int LibVLCAudioEqualizerSetPreamp(IntPtr equalizer, float preamp);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_audio_equalizer_get_preamp")]
			internal static extern float LibVLCAudioEqualizerGetPreamp(IntPtr equalizer);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_audio_equalizer_set_amp_at_index")]
			internal static extern int LibVLCAudioEqualizerSetAmpAtIndex(IntPtr equalizer, float amp, uint band);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_audio_equalizer_get_amp_at_index")]
			internal static extern float LibVLCAudioEqualizerGetAmpAtIndex(IntPtr equalizer, uint band);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_audio_equalizer_get_preset_count")]
			internal static extern uint LibVLCAudioEqualizerGetPresetCount();

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_audio_equalizer_get_preset_name")]
			internal static extern IntPtr LibVLCAudioEqualizerGetPresetName(uint index);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_audio_equalizer_get_band_count")]
			internal static extern uint LibVLCAudioEqualizerGetBandCount();

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_audio_equalizer_get_band_frequency")]
			internal static extern float LibVLCAudioEqualizerGetBandFrequency(uint index);
		}

		public float Preamp => Native.LibVLCAudioEqualizerGetPreamp(base.NativeReference);

		public uint PresetCount => Native.LibVLCAudioEqualizerGetPresetCount();

		public uint BandCount => Native.LibVLCAudioEqualizerGetBandCount();

		public Equalizer()
			: base(Native.LibVLCAudioEqualizerNew, Native.LibVLCAudioEqualizerRelease)
		{
		}

		public Equalizer(uint index)
			: base(() => Native.LibVLCAudioEqualizerNewFromPreset(index), Native.LibVLCAudioEqualizerRelease)
		{
		}

		public bool SetPreamp(float preamp)
		{
			return Native.LibVLCAudioEqualizerSetPreamp(base.NativeReference, preamp) == 0;
		}

		public bool SetAmp(float amp, uint band)
		{
			return Native.LibVLCAudioEqualizerSetAmpAtIndex(base.NativeReference, amp, band) == 0;
		}

		public float Amp(uint band)
		{
			return Native.LibVLCAudioEqualizerGetAmpAtIndex(base.NativeReference, band);
		}

		public string? PresetName(uint index)
		{
			return Native.LibVLCAudioEqualizerGetPresetName(index).FromUtf8();
		}

		public float BandFrequency(uint index)
		{
			return Native.LibVLCAudioEqualizerGetBandFrequency(index);
		}
	}
	internal abstract class EventManager
	{
		[StructLayout(LayoutKind.Sequential, Size = 1)]
		internal readonly struct Native
		{
			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_event_attach")]
			internal static extern int LibVLCEventAttach(IntPtr eventManager, EventType eventType, InternalEventCallback eventCallback, IntPtr userData);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_event_detach")]
			internal static extern void LibVLCEventDetach(IntPtr eventManager, EventType eventType, InternalEventCallback eventCallback, IntPtr userData);
		}

		internal class EventTypeManager : IDisposable
		{
			internal Action<IntPtr> EventHandler { get; }

			internal GCHandle Handle { get; }

			internal int HandlerCount { get; set; }

			internal EventTypeManager(Action<IntPtr> eventHandler)
			{
				EventHandler = eventHandler;
				Handle = GCHandle.Alloc(this);
			}

			public void Dispose()
			{
				Handle.Free();
			}
		}

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void InternalEventCallback(IntPtr evt, IntPtr userData);

		internal IntPtr NativeReference;

		private readonly Dictionary<EventType, EventTypeManager> _eventManagers = new Dictionary<EventType, EventTypeManager>();

		private static readonly InternalEventCallback EventCallbackHandle = EventCallback;

		protected internal EventManager(IntPtr ptr)
		{
			if (ptr == IntPtr.Zero)
			{
				throw new NullReferenceException("ptr");
			}
			NativeReference = ptr;
		}

		private bool AttachNativeEvent(EventType eventType, EventTypeManager eventManager)
		{
			return Native.LibVLCEventAttach(NativeReference, eventType, EventCallbackHandle, GCHandle.ToIntPtr(eventManager.Handle)) == 0;
		}

		private void DetachNativeEvent(EventType eventType, EventTypeManager eventManager)
		{
			Native.LibVLCEventDetach(NativeReference, eventType, EventCallbackHandle, GCHandle.ToIntPtr(eventManager.Handle));
		}

		protected void Attach(EventType eventType, Action<IntPtr> eventHandler)
		{
			lock (_eventManagers)
			{
				if (!_eventManagers.TryGetValue(eventType, out EventTypeManager value))
				{
					value = new EventTypeManager(eventHandler);
					if (!AttachNativeEvent(eventType, value))
					{
						value.Dispose();
						throw new VLCException($"Could not attach event {eventType}");
					}
					_eventManagers.Add(eventType, value);
				}
				value.HandlerCount++;
			}
		}

		protected void Detach(EventType eventType)
		{
			lock (_eventManagers)
			{
				if (_eventManagers.TryGetValue(eventType, out EventTypeManager value))
				{
					value.HandlerCount--;
					if (value.HandlerCount == 0)
					{
						DetachNativeEvent(eventType, value);
						value.Dispose();
						_eventManagers.Remove(eventType);
					}
				}
			}
		}

		[MonoPInvokeCallback(typeof(InternalEventCallback))]
		private static void EventCallback(IntPtr evt, IntPtr userData)
		{
			MarshalUtils.GetInstance<EventTypeManager>(userData)?.EventHandler(evt);
		}

		protected internal LibVLCEvent RetrieveEvent(IntPtr eventPtr)
		{
			return MarshalUtils.PtrToStructure<LibVLCEvent>(eventPtr);
		}

		protected internal void OnEventUnhandled(object sender, EventType eventType)
		{
			throw new InvalidOperationException("eventType eventType unhandled by type " + sender.GetType().Name);
		}

		protected internal abstract void AttachEvent<T>(EventType eventType, EventHandler<T> eventHandler) where T : EventArgs;

		protected internal abstract void DetachEvent<T>(EventType eventType, EventHandler<T> eventHandler) where T : EventArgs;
	}
	internal class MediaDiscovererEventManager : EventManager
	{
		private EventHandler<EventArgs>? _mediaDiscovererStarted;

		private EventHandler<EventArgs>? _mediaDiscovererStopped;

		public MediaDiscovererEventManager(IntPtr ptr)
			: base(ptr)
		{
		}

		protected internal override void AttachEvent<T>(EventType eventType, EventHandler<T> eventHandler)
		{
			switch (eventType)
			{
			case EventType.MediaDiscovererStarted:
				_mediaDiscovererStarted = (EventHandler<EventArgs>)Delegate.Combine(_mediaDiscovererStarted, eventHandler as EventHandler<EventArgs>);
				Attach(eventType, OnStarted);
				break;
			case EventType.MediaDiscovererStopped:
				_mediaDiscovererStopped = (EventHandler<EventArgs>)Delegate.Combine(_mediaDiscovererStopped, eventHandler as EventHandler<EventArgs>);
				Attach(eventType, OnStopped);
				break;
			default:
				OnEventUnhandled(this, eventType);
				break;
			}
		}

		protected internal override void DetachEvent<T>(EventType eventType, EventHandler<T> eventHandler)
		{
			switch (eventType)
			{
			case EventType.MediaDiscovererStarted:
				_mediaDiscovererStarted = (EventHandler<EventArgs>)Delegate.Remove(_mediaDiscovererStarted, eventHandler as EventHandler<EventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaDiscovererStopped:
				_mediaDiscovererStopped = (EventHandler<EventArgs>)Delegate.Remove(_mediaDiscovererStopped, eventHandler as EventHandler<EventArgs>);
				Detach(eventType);
				break;
			default:
				OnEventUnhandled(this, eventType);
				break;
			}
		}

		private void OnStarted(IntPtr ptr)
		{
			_mediaDiscovererStarted?.Invoke(this, EventArgs.Empty);
		}

		private void OnStopped(IntPtr ptr)
		{
			_mediaDiscovererStopped?.Invoke(this, EventArgs.Empty);
		}
	}
	internal class MediaEventManager : EventManager
	{
		private EventHandler<MediaMetaChangedEventArgs>? _mediaMetaChanged;

		private EventHandler<MediaParsedChangedEventArgs>? _mediaParsedChanged;

		private EventHandler<MediaSubItemAddedEventArgs>? _mediaSubItemAdded;

		private EventHandler<MediaDurationChangedEventArgs>? _mediaDurationChanged;

		private EventHandler<MediaFreedEventArgs>? _mediaFreed;

		private EventHandler<MediaStateChangedEventArgs>? _mediaStateChanged;

		private EventHandler<MediaSubItemTreeAddedEventArgs>? _mediaSubItemTreeAdded;

		public MediaEventManager(IntPtr ptr)
			: base(ptr)
		{
		}

		protected internal override void AttachEvent<T>(EventType eventType, EventHandler<T> eventHandler)
		{
			switch (eventType)
			{
			case EventType.MediaMetaChanged:
				_mediaMetaChanged = (EventHandler<MediaMetaChangedEventArgs>)Delegate.Combine(_mediaMetaChanged, eventHandler as EventHandler<MediaMetaChangedEventArgs>);
				Attach(eventType, OnMetaChanged);
				break;
			case EventType.MediaParsedChanged:
				_mediaParsedChanged = (EventHandler<MediaParsedChangedEventArgs>)Delegate.Combine(_mediaParsedChanged, eventHandler as EventHandler<MediaParsedChangedEventArgs>);
				Attach(eventType, OnParsedChanged);
				break;
			case EventType.MediaSubItemAdded:
				_mediaSubItemAdded = (EventHandler<MediaSubItemAddedEventArgs>)Delegate.Combine(_mediaSubItemAdded, eventHandler as EventHandler<MediaSubItemAddedEventArgs>);
				Attach(eventType, OnSubItemAdded);
				break;
			case EventType.MediaDurationChanged:
				_mediaDurationChanged = (EventHandler<MediaDurationChangedEventArgs>)Delegate.Combine(_mediaDurationChanged, eventHandler as EventHandler<MediaDurationChangedEventArgs>);
				Attach(eventType, OnDurationChanged);
				break;
			case EventType.MediaFreed:
				_mediaFreed = (EventHandler<MediaFreedEventArgs>)Delegate.Combine(_mediaFreed, eventHandler as EventHandler<MediaFreedEventArgs>);
				Attach(eventType, OnMediaFreed);
				break;
			case EventType.MediaStateChanged:
				_mediaStateChanged = (EventHandler<MediaStateChangedEventArgs>)Delegate.Combine(_mediaStateChanged, eventHandler as EventHandler<MediaStateChangedEventArgs>);
				Attach(eventType, OnMediaStateChanged);
				break;
			case EventType.MediaSubItemTreeAdded:
				_mediaSubItemTreeAdded = (EventHandler<MediaSubItemTreeAddedEventArgs>)Delegate.Combine(_mediaSubItemTreeAdded, eventHandler as EventHandler<MediaSubItemTreeAddedEventArgs>);
				Attach(eventType, OnSubItemTreeAdded);
				break;
			default:
				OnEventUnhandled(this, eventType);
				break;
			}
		}

		protected internal override void DetachEvent<T>(EventType eventType, EventHandler<T> eventHandler)
		{
			switch (eventType)
			{
			case EventType.MediaMetaChanged:
				_mediaMetaChanged = (EventHandler<MediaMetaChangedEventArgs>)Delegate.Remove(_mediaMetaChanged, eventHandler as EventHandler<MediaMetaChangedEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaParsedChanged:
				_mediaParsedChanged = (EventHandler<MediaParsedChangedEventArgs>)Delegate.Remove(_mediaParsedChanged, eventHandler as EventHandler<MediaParsedChangedEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaSubItemAdded:
				_mediaSubItemAdded = (EventHandler<MediaSubItemAddedEventArgs>)Delegate.Remove(_mediaSubItemAdded, eventHandler as EventHandler<MediaSubItemAddedEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaDurationChanged:
				_mediaDurationChanged = (EventHandler<MediaDurationChangedEventArgs>)Delegate.Remove(_mediaDurationChanged, eventHandler as EventHandler<MediaDurationChangedEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaFreed:
				_mediaFreed = (EventHandler<MediaFreedEventArgs>)Delegate.Remove(_mediaFreed, eventHandler as EventHandler<MediaFreedEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaStateChanged:
				_mediaStateChanged = (EventHandler<MediaStateChangedEventArgs>)Delegate.Remove(_mediaStateChanged, eventHandler as EventHandler<MediaStateChangedEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaSubItemTreeAdded:
				_mediaSubItemTreeAdded = (EventHandler<MediaSubItemTreeAddedEventArgs>)Delegate.Remove(_mediaSubItemTreeAdded, eventHandler as EventHandler<MediaSubItemTreeAddedEventArgs>);
				Detach(eventType);
				break;
			default:
				OnEventUnhandled(this, eventType);
				break;
			}
		}

		private void OnSubItemTreeAdded(IntPtr ptr)
		{
			_mediaSubItemTreeAdded?.Invoke(this, new MediaSubItemTreeAddedEventArgs(RetrieveEvent(ptr).Union.MediaSubItemTreeAdded.MediaInstance));
		}

		private void OnMediaStateChanged(IntPtr ptr)
		{
			_mediaStateChanged?.Invoke(this, new MediaStateChangedEventArgs(RetrieveEvent(ptr).Union.MediaStateChanged.NewState));
		}

		private void OnMediaFreed(IntPtr ptr)
		{
			_mediaFreed?.Invoke(this, new MediaFreedEventArgs(RetrieveEvent(ptr).Union.MediaFreed.MediaInstance));
		}

		private void OnDurationChanged(IntPtr ptr)
		{
			_mediaDurationChanged?.Invoke(this, new MediaDurationChangedEventArgs(RetrieveEvent(ptr).Union.MediaDurationChanged.NewDuration));
		}

		private void OnSubItemAdded(IntPtr ptr)
		{
			_mediaSubItemAdded?.Invoke(this, new MediaSubItemAddedEventArgs(RetrieveEvent(ptr).Union.MediaSubItemAdded.NewChild));
		}

		private void OnParsedChanged(IntPtr ptr)
		{
			_mediaParsedChanged?.Invoke(this, new MediaParsedChangedEventArgs(RetrieveEvent(ptr).Union.MediaParsedChanged.NewStatus));
		}

		private void OnMetaChanged(IntPtr ptr)
		{
			_mediaMetaChanged?.Invoke(this, new MediaMetaChangedEventArgs(RetrieveEvent(ptr).Union.MediaMetaChanged.MetaType));
		}
	}
	internal class MediaListEventManager : EventManager
	{
		private EventHandler<MediaListItemAddedEventArgs>? _mediaListItemAdded;

		private EventHandler<MediaListWillAddItemEventArgs>? _mediaListWillAddItem;

		private EventHandler<MediaListItemDeletedEventArgs>? _mediaListItemDeleted;

		private EventHandler<MediaListWillDeleteItemEventArgs>? _mediaListWillDeleteItem;

		private EventHandler<EventArgs>? _mediaListEndReached;

		public MediaListEventManager(IntPtr ptr)
			: base(ptr)
		{
		}

		protected internal override void AttachEvent<T>(EventType eventType, EventHandler<T> eventHandler)
		{
			switch (eventType)
			{
			case EventType.MediaListItemAdded:
				_mediaListItemAdded = (EventHandler<MediaListItemAddedEventArgs>)Delegate.Combine(_mediaListItemAdded, eventHandler as EventHandler<MediaListItemAddedEventArgs>);
				Attach(eventType, OnItemAdded);
				break;
			case EventType.MediaListWillAddItem:
				_mediaListWillAddItem = (EventHandler<MediaListWillAddItemEventArgs>)Delegate.Combine(_mediaListWillAddItem, eventHandler as EventHandler<MediaListWillAddItemEventArgs>);
				Attach(eventType, OnWillAddItem);
				break;
			case EventType.MediaListItemDeleted:
				_mediaListItemDeleted = (EventHandler<MediaListItemDeletedEventArgs>)Delegate.Combine(_mediaListItemDeleted, eventHandler as EventHandler<MediaListItemDeletedEventArgs>);
				Attach(eventType, OnItemDeleted);
				break;
			case EventType.MediaListViewWillDeleteItem:
				_mediaListWillDeleteItem = (EventHandler<MediaListWillDeleteItemEventArgs>)Delegate.Combine(_mediaListWillDeleteItem, eventHandler as EventHandler<MediaListWillDeleteItemEventArgs>);
				Attach(eventType, OnWillDeleteItem);
				break;
			case EventType.MediaListEndReached:
				_mediaListEndReached = (EventHandler<EventArgs>)Delegate.Combine(_mediaListEndReached, eventHandler as EventHandler<EventArgs>);
				Attach(eventType, OnEndReached);
				break;
			default:
				OnEventUnhandled(this, eventType);
				break;
			}
		}

		protected internal override void DetachEvent<T>(EventType eventType, EventHandler<T> eventHandler)
		{
			switch (eventType)
			{
			case EventType.MediaListItemAdded:
				_mediaListItemAdded = (EventHandler<MediaListItemAddedEventArgs>)Delegate.Remove(_mediaListItemAdded, eventHandler as EventHandler<MediaListItemAddedEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaListWillAddItem:
				_mediaListWillAddItem = (EventHandler<MediaListWillAddItemEventArgs>)Delegate.Remove(_mediaListWillAddItem, eventHandler as EventHandler<MediaListWillAddItemEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaListItemDeleted:
				_mediaListItemDeleted = (EventHandler<MediaListItemDeletedEventArgs>)Delegate.Remove(_mediaListItemDeleted, eventHandler as EventHandler<MediaListItemDeletedEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaListViewWillDeleteItem:
				_mediaListWillDeleteItem = (EventHandler<MediaListWillDeleteItemEventArgs>)Delegate.Remove(_mediaListWillDeleteItem, eventHandler as EventHandler<MediaListWillDeleteItemEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaListEndReached:
				_mediaListEndReached = (EventHandler<EventArgs>)Delegate.Remove(_mediaListEndReached, eventHandler as EventHandler<EventArgs>);
				Detach(eventType);
				break;
			default:
				OnEventUnhandled(this, eventType);
				break;
			}
		}

		private void OnItemAdded(IntPtr ptr)
		{
			LibVLCEvent.MediaListItemAdded mediaListItemAdded = RetrieveEvent(ptr).Union.MediaListItemAdded;
			_mediaListItemAdded?.Invoke(this, new MediaListItemAddedEventArgs(new Media(mediaListItemAdded.MediaInstance), mediaListItemAdded.Index));
		}

		private void OnWillAddItem(IntPtr ptr)
		{
			LibVLCEvent.MediaListWillAddItem mediaListWillAddItem = RetrieveEvent(ptr).Union.MediaListWillAddItem;
			_mediaListWillAddItem?.Invoke(this, new MediaListWillAddItemEventArgs(new Media(mediaListWillAddItem.MediaInstance), mediaListWillAddItem.Index));
		}

		private void OnItemDeleted(IntPtr ptr)
		{
			LibVLCEvent.MediaListItemDeleted mediaListItemDeleted = RetrieveEvent(ptr).Union.MediaListItemDeleted;
			_mediaListItemDeleted?.Invoke(this, new MediaListItemDeletedEventArgs(new Media(mediaListItemDeleted.MediaInstance), mediaListItemDeleted.Index));
		}

		private void OnWillDeleteItem(IntPtr ptr)
		{
			LibVLCEvent.MediaListWillDeleteItem mediaListWillDeleteItem = RetrieveEvent(ptr).Union.MediaListWillDeleteItem;
			_mediaListWillDeleteItem?.Invoke(this, new MediaListWillDeleteItemEventArgs(new Media(mediaListWillDeleteItem.MediaInstance), mediaListWillDeleteItem.Index));
		}

		private void OnEndReached(IntPtr ptr)
		{
			_mediaListEndReached?.Invoke(this, EventArgs.Empty);
		}
	}
	public class MediaPlayerChangedEventArgs : EventArgs
	{
		public MediaPlayer? OldMediaPlayer { get; }

		public MediaPlayer? NewMediaPlayer { get; }

		public MediaPlayerChangedEventArgs(MediaPlayer? oldMediaPlayer, MediaPlayer? newMediaPlayer)
		{
			OldMediaPlayer = oldMediaPlayer;
			NewMediaPlayer = newMediaPlayer;
		}
	}
	public class MediaPlayerChangingEventArgs : EventArgs
	{
		public MediaPlayer? OldMediaPlayer { get; }

		public MediaPlayer? NewMediaPlayer { get; }

		public MediaPlayerChangingEventArgs(MediaPlayer? oldMediaPlayer, MediaPlayer? newMediaPlayer)
		{
			OldMediaPlayer = oldMediaPlayer;
			NewMediaPlayer = newMediaPlayer;
		}
	}
	internal class MediaPlayerEventManager : EventManager
	{
		private EventHandler<MediaPlayerPositionChangedEventArgs>? _mediaPlayerPositionChanged;

		private EventHandler<MediaPlayerMediaChangedEventArgs>? _mediaPlayerMediaChanged;

		private EventHandler<EventArgs>? _mediaPlayerNothingSpecial;

		private EventHandler<EventArgs>? _mediaPlayerOpening;

		private EventHandler<MediaPlayerBufferingEventArgs>? _mediaPlayerBuffering;

		private EventHandler<EventArgs>? _mediaPlayerPlaying;

		private EventHandler<EventArgs>? _mediaPlayerPaused;

		private EventHandler<EventArgs>? _mediaPlayerStopped;

		private EventHandler<EventArgs>? _mediaPlayerForward;

		private EventHandler<EventArgs>? _mediaPlayerBackward;

		private EventHandler<EventArgs>? _mediaPlayerEndReached;

		private EventHandler<EventArgs>? _mediaPlayerEncounteredError;

		private EventHandler<MediaPlayerTimeChangedEventArgs>? _mediaPlayerTimeChanged;

		private EventHandler<MediaPlayerSeekableChangedEventArgs>? _mediaPlayerSeekableChanged;

		private EventHandler<MediaPlayerPausableChangedEventArgs>? _mediaPlayerPausableChanged;

		private EventHandler<MediaPlayerTitleChangedEventArgs>? _mediaPlayerTitleChanged;

		private EventHandler<MediaPlayerChapterChangedEventArgs>? _mediaPlayerChapterChanged;

		private EventHandler<MediaPlayerSnapshotTakenEventArgs>? _mediaPlayerSnapshotTaken;

		private EventHandler<MediaPlayerLengthChangedEventArgs>? _mediaPlayerLengthChanged;

		private EventHandler<MediaPlayerVoutEventArgs>? _mediaPlayerVout;

		private EventHandler<MediaPlayerScrambledChangedEventArgs>? _mediaPlayerScrambledChanged;

		private EventHandler<MediaPlayerESAddedEventArgs>? _mediaPlayerESAdded;

		private EventHandler<MediaPlayerESDeletedEventArgs>? _mediaPlayerESDeleted;

		private EventHandler<MediaPlayerESSelectedEventArgs>? _mediaPlayerESSelected;

		private EventHandler<MediaPlayerAudioDeviceEventArgs>? _mediaPlayerAudioDevice;

		private EventHandler<EventArgs>? _mediaPlayerCorked;

		private EventHandler<EventArgs>? _mediaPlayerUncorked;

		private EventHandler<EventArgs>? _mediaPlayerMuted;

		private EventHandler<EventArgs>? _mediaPlayerUnmuted;

		private EventHandler<MediaPlayerVolumeChangedEventArgs>? _mediaPlayerVolumeChanged;

		public MediaPlayerEventManager(IntPtr ptr)
			: base(ptr)
		{
		}

		protected internal override void AttachEvent<T>(EventType eventType, EventHandler<T> eventHandler)
		{
			switch (eventType)
			{
			case EventType.MediaPlayerPositionChanged:
				_mediaPlayerPositionChanged = (EventHandler<MediaPlayerPositionChangedEventArgs>)Delegate.Combine(_mediaPlayerPositionChanged, eventHandler as EventHandler<MediaPlayerPositionChangedEventArgs>);
				Attach(eventType, OnPositionChanged);
				break;
			case EventType.MediaPlayerMediaChanged:
				_mediaPlayerMediaChanged = (EventHandler<MediaPlayerMediaChangedEventArgs>)Delegate.Combine(_mediaPlayerMediaChanged, eventHandler as EventHandler<MediaPlayerMediaChangedEventArgs>);
				Attach(eventType, OnMediaChanged);
				break;
			case EventType.MediaPlayerNothingSpecial:
				_mediaPlayerNothingSpecial = (EventHandler<EventArgs>)Delegate.Combine(_mediaPlayerNothingSpecial, eventHandler as EventHandler<EventArgs>);
				Attach(eventType, OnNothingSpecial);
				break;
			case EventType.MediaPlayerOpening:
				_mediaPlayerOpening = (EventHandler<EventArgs>)Delegate.Combine(_mediaPlayerOpening, eventHandler as EventHandler<EventArgs>);
				Attach(eventType, OnOpening);
				break;
			case EventType.MediaPlayerBuffering:
				_mediaPlayerBuffering = (EventHandler<MediaPlayerBufferingEventArgs>)Delegate.Combine(_mediaPlayerBuffering, eventHandler as EventHandler<MediaPlayerBufferingEventArgs>);
				Attach(eventType, OnBuffering);
				break;
			case EventType.MediaPlayerPlaying:
				_mediaPlayerPlaying = (EventHandler<EventArgs>)Delegate.Combine(_mediaPlayerPlaying, eventHandler as EventHandler<EventArgs>);
				Attach(eventType, OnPlaying);
				break;
			case EventType.MediaPlayerPaused:
				_mediaPlayerPaused = (EventHandler<EventArgs>)Delegate.Combine(_mediaPlayerPaused, eventHandler as EventHandler<EventArgs>);
				Attach(eventType, OnPaused);
				break;
			case EventType.MediaPlayerStopped:
				_mediaPlayerStopped = (EventHandler<EventArgs>)Delegate.Combine(_mediaPlayerStopped, eventHandler as EventHandler<EventArgs>);
				Attach(eventType, OnStopped);
				break;
			case EventType.MediaPlayerForward:
				_mediaPlayerForward = (EventHandler<EventArgs>)Delegate.Combine(_mediaPlayerForward, eventHandler as EventHandler<EventArgs>);
				Attach(eventType, OnForward);
				break;
			case EventType.MediaPlayerBackward:
				_mediaPlayerBackward = (EventHandler<EventArgs>)Delegate.Combine(_mediaPlayerBackward, eventHandler as EventHandler<EventArgs>);
				Attach(eventType, OnBackward);
				break;
			case EventType.MediaPlayerEndReached:
				_mediaPlayerEndReached = (EventHandler<EventArgs>)Delegate.Combine(_mediaPlayerEndReached, eventHandler as EventHandler<EventArgs>);
				Attach(eventType, OnEndReached);
				break;
			case EventType.MediaPlayerEncounteredError:
				_mediaPlayerEncounteredError = (EventHandler<EventArgs>)Delegate.Combine(_mediaPlayerEncounteredError, eventHandler as EventHandler<EventArgs>);
				Attach(eventType, OnEncounteredError);
				break;
			case EventType.MediaPlayerTimeChanged:
				_mediaPlayerTimeChanged = (EventHandler<MediaPlayerTimeChangedEventArgs>)Delegate.Combine(_mediaPlayerTimeChanged, eventHandler as EventHandler<MediaPlayerTimeChangedEventArgs>);
				Attach(eventType, OnTimeChanged);
				break;
			case EventType.MediaPlayerSeekableChanged:
				_mediaPlayerSeekableChanged = (EventHandler<MediaPlayerSeekableChangedEventArgs>)Delegate.Combine(_mediaPlayerSeekableChanged, eventHandler as EventHandler<MediaPlayerSeekableChangedEventArgs>);
				Attach(eventType, OnSeekableChanged);
				break;
			case EventType.MediaPlayerPausableChanged:
				_mediaPlayerPausableChanged = (EventHandler<MediaPlayerPausableChangedEventArgs>)Delegate.Combine(_mediaPlayerPausableChanged, eventHandler as EventHandler<MediaPlayerPausableChangedEventArgs>);
				Attach(eventType, OnPausableChanged);
				break;
			case EventType.MediaPlayerTitleChanged:
				_mediaPlayerTitleChanged = (EventHandler<MediaPlayerTitleChangedEventArgs>)Delegate.Combine(_mediaPlayerTitleChanged, eventHandler as EventHandler<MediaPlayerTitleChangedEventArgs>);
				Attach(eventType, OnTitleChanged);
				break;
			case EventType.MediaPlayerChapterChanged:
				_mediaPlayerChapterChanged = (EventHandler<MediaPlayerChapterChangedEventArgs>)Delegate.Combine(_mediaPlayerChapterChanged, eventHandler as EventHandler<MediaPlayerChapterChangedEventArgs>);
				Attach(eventType, OnChapterChanged);
				break;
			case EventType.MediaPlayerSnapshotTaken:
				_mediaPlayerSnapshotTaken = (EventHandler<MediaPlayerSnapshotTakenEventArgs>)Delegate.Combine(_mediaPlayerSnapshotTaken, eventHandler as EventHandler<MediaPlayerSnapshotTakenEventArgs>);
				Attach(eventType, OnSnapshotTaken);
				break;
			case EventType.MediaPlayerLengthChanged:
				_mediaPlayerLengthChanged = (EventHandler<MediaPlayerLengthChangedEventArgs>)Delegate.Combine(_mediaPlayerLengthChanged, eventHandler as EventHandler<MediaPlayerLengthChangedEventArgs>);
				Attach(eventType, OnLengthChanged);
				break;
			case EventType.MediaPlayerVout:
				_mediaPlayerVout = (EventHandler<MediaPlayerVoutEventArgs>)Delegate.Combine(_mediaPlayerVout, eventHandler as EventHandler<MediaPlayerVoutEventArgs>);
				Attach(eventType, OnVout);
				break;
			case EventType.MediaPlayerScrambledChanged:
				_mediaPlayerScrambledChanged = (EventHandler<MediaPlayerScrambledChangedEventArgs>)Delegate.Combine(_mediaPlayerScrambledChanged, eventHandler as EventHandler<MediaPlayerScrambledChangedEventArgs>);
				Attach(eventType, OnScrambledChanged);
				break;
			case EventType.MediaPlayerESAdded:
				_mediaPlayerESAdded = (EventHandler<MediaPlayerESAddedEventArgs>)Delegate.Combine(_mediaPlayerESAdded, eventHandler as EventHandler<MediaPlayerESAddedEventArgs>);
				Attach(eventType, OnESAdded);
				break;
			case EventType.MediaPlayerESDeleted:
				_mediaPlayerESDeleted = (EventHandler<MediaPlayerESDeletedEventArgs>)Delegate.Combine(_mediaPlayerESDeleted, eventHandler as EventHandler<MediaPlayerESDeletedEventArgs>);
				Attach(eventType, OnESDeleted);
				break;
			case EventType.MediaPlayerESSelected:
				_mediaPlayerESSelected = (EventHandler<MediaPlayerESSelectedEventArgs>)Delegate.Combine(_mediaPlayerESSelected, eventHandler as EventHandler<MediaPlayerESSelectedEventArgs>);
				Attach(eventType, OnESSelected);
				break;
			case EventType.MediaPlayerAudioDevice:
				_mediaPlayerAudioDevice = (EventHandler<MediaPlayerAudioDeviceEventArgs>)Delegate.Combine(_mediaPlayerAudioDevice, eventHandler as EventHandler<MediaPlayerAudioDeviceEventArgs>);
				Attach(eventType, OnAudioDevice);
				break;
			case EventType.MediaPlayerCorked:
				_mediaPlayerCorked = (EventHandler<EventArgs>)Delegate.Combine(_mediaPlayerCorked, eventHandler as EventHandler<EventArgs>);
				Attach(eventType, OnCorked);
				break;
			case EventType.MediaPlayerUncorked:
				_mediaPlayerUncorked = (EventHandler<EventArgs>)Delegate.Combine(_mediaPlayerUncorked, eventHandler as EventHandler<EventArgs>);
				Attach(eventType, OnUncorked);
				break;
			case EventType.MediaPlayerMuted:
				_mediaPlayerMuted = (EventHandler<EventArgs>)Delegate.Combine(_mediaPlayerMuted, eventHandler as EventHandler<EventArgs>);
				Attach(eventType, OnMuted);
				break;
			case EventType.MediaPlayerUnmuted:
				_mediaPlayerUnmuted = (EventHandler<EventArgs>)Delegate.Combine(_mediaPlayerUnmuted, eventHandler as EventHandler<EventArgs>);
				Attach(eventType, OnUnmuted);
				break;
			case EventType.MediaPlayerAudioVolume:
				_mediaPlayerVolumeChanged = (EventHandler<MediaPlayerVolumeChangedEventArgs>)Delegate.Combine(_mediaPlayerVolumeChanged, eventHandler as EventHandler<MediaPlayerVolumeChangedEventArgs>);
				Attach(eventType, OnVolumeChanged);
				break;
			default:
				OnEventUnhandled(this, eventType);
				break;
			}
		}

		protected internal override void DetachEvent<T>(EventType eventType, EventHandler<T> eventHandler)
		{
			switch (eventType)
			{
			case EventType.MediaPlayerPositionChanged:
				_mediaPlayerPositionChanged = (EventHandler<MediaPlayerPositionChangedEventArgs>)Delegate.Remove(_mediaPlayerPositionChanged, eventHandler as EventHandler<MediaPlayerPositionChangedEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerMediaChanged:
				_mediaPlayerMediaChanged = (EventHandler<MediaPlayerMediaChangedEventArgs>)Delegate.Remove(_mediaPlayerMediaChanged, eventHandler as EventHandler<MediaPlayerMediaChangedEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerNothingSpecial:
				_mediaPlayerNothingSpecial = (EventHandler<EventArgs>)Delegate.Remove(_mediaPlayerNothingSpecial, eventHandler as EventHandler<EventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerOpening:
				_mediaPlayerOpening = (EventHandler<EventArgs>)Delegate.Remove(_mediaPlayerOpening, eventHandler as EventHandler<EventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerBuffering:
				_mediaPlayerBuffering = (EventHandler<MediaPlayerBufferingEventArgs>)Delegate.Remove(_mediaPlayerBuffering, eventHandler as EventHandler<MediaPlayerBufferingEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerPlaying:
				_mediaPlayerPlaying = (EventHandler<EventArgs>)Delegate.Remove(_mediaPlayerPlaying, eventHandler as EventHandler<EventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerPaused:
				_mediaPlayerPaused = (EventHandler<EventArgs>)Delegate.Remove(_mediaPlayerPaused, eventHandler as EventHandler<EventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerStopped:
				_mediaPlayerStopped = (EventHandler<EventArgs>)Delegate.Remove(_mediaPlayerStopped, eventHandler as EventHandler<EventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerForward:
				_mediaPlayerForward = (EventHandler<EventArgs>)Delegate.Remove(_mediaPlayerForward, eventHandler as EventHandler<EventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerBackward:
				_mediaPlayerBackward = (EventHandler<EventArgs>)Delegate.Remove(_mediaPlayerBackward, eventHandler as EventHandler<EventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerEndReached:
				_mediaPlayerEndReached = (EventHandler<EventArgs>)Delegate.Remove(_mediaPlayerEndReached, eventHandler as EventHandler<EventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerEncounteredError:
				_mediaPlayerEncounteredError = (EventHandler<EventArgs>)Delegate.Remove(_mediaPlayerEncounteredError, eventHandler as EventHandler<EventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerTimeChanged:
				_mediaPlayerTimeChanged = (EventHandler<MediaPlayerTimeChangedEventArgs>)Delegate.Remove(_mediaPlayerTimeChanged, eventHandler as EventHandler<MediaPlayerTimeChangedEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerSeekableChanged:
				_mediaPlayerSeekableChanged = (EventHandler<MediaPlayerSeekableChangedEventArgs>)Delegate.Remove(_mediaPlayerSeekableChanged, eventHandler as EventHandler<MediaPlayerSeekableChangedEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerPausableChanged:
				_mediaPlayerPausableChanged = (EventHandler<MediaPlayerPausableChangedEventArgs>)Delegate.Remove(_mediaPlayerPausableChanged, eventHandler as EventHandler<MediaPlayerPausableChangedEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerTitleChanged:
				_mediaPlayerTitleChanged = (EventHandler<MediaPlayerTitleChangedEventArgs>)Delegate.Remove(_mediaPlayerTitleChanged, eventHandler as EventHandler<MediaPlayerTitleChangedEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerChapterChanged:
				_mediaPlayerChapterChanged = (EventHandler<MediaPlayerChapterChangedEventArgs>)Delegate.Remove(_mediaPlayerChapterChanged, eventHandler as EventHandler<MediaPlayerChapterChangedEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerSnapshotTaken:
				_mediaPlayerSnapshotTaken = (EventHandler<MediaPlayerSnapshotTakenEventArgs>)Delegate.Remove(_mediaPlayerSnapshotTaken, eventHandler as EventHandler<MediaPlayerSnapshotTakenEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerLengthChanged:
				_mediaPlayerLengthChanged = (EventHandler<MediaPlayerLengthChangedEventArgs>)Delegate.Remove(_mediaPlayerLengthChanged, eventHandler as EventHandler<MediaPlayerLengthChangedEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerVout:
				_mediaPlayerVout = (EventHandler<MediaPlayerVoutEventArgs>)Delegate.Remove(_mediaPlayerVout, eventHandler as EventHandler<MediaPlayerVoutEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerScrambledChanged:
				_mediaPlayerScrambledChanged = (EventHandler<MediaPlayerScrambledChangedEventArgs>)Delegate.Remove(_mediaPlayerScrambledChanged, eventHandler as EventHandler<MediaPlayerScrambledChangedEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerESAdded:
				_mediaPlayerESAdded = (EventHandler<MediaPlayerESAddedEventArgs>)Delegate.Remove(_mediaPlayerESAdded, eventHandler as EventHandler<MediaPlayerESAddedEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerESDeleted:
				_mediaPlayerESDeleted = (EventHandler<MediaPlayerESDeletedEventArgs>)Delegate.Remove(_mediaPlayerESDeleted, eventHandler as EventHandler<MediaPlayerESDeletedEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerESSelected:
				_mediaPlayerESSelected = (EventHandler<MediaPlayerESSelectedEventArgs>)Delegate.Remove(_mediaPlayerESSelected, eventHandler as EventHandler<MediaPlayerESSelectedEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerAudioDevice:
				_mediaPlayerAudioDevice = (EventHandler<MediaPlayerAudioDeviceEventArgs>)Delegate.Remove(_mediaPlayerAudioDevice, eventHandler as EventHandler<MediaPlayerAudioDeviceEventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerCorked:
				_mediaPlayerCorked = (EventHandler<EventArgs>)Delegate.Remove(_mediaPlayerCorked, eventHandler as EventHandler<EventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerUncorked:
				_mediaPlayerUncorked = (EventHandler<EventArgs>)Delegate.Remove(_mediaPlayerUncorked, eventHandler as EventHandler<EventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerMuted:
				_mediaPlayerMuted = (EventHandler<EventArgs>)Delegate.Remove(_mediaPlayerMuted, eventHandler as EventHandler<EventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerUnmuted:
				_mediaPlayerUnmuted = (EventHandler<EventArgs>)Delegate.Remove(_mediaPlayerUnmuted, eventHandler as EventHandler<EventArgs>);
				Detach(eventType);
				break;
			case EventType.MediaPlayerAudioVolume:
				_mediaPlayerVolumeChanged = (EventHandler<MediaPlayerVolumeChangedEventArgs>)Delegate.Remove(_mediaPlayerVolumeChanged, eventHandler as EventHandler<MediaPlayerVolumeChangedEventArgs>);
				Detach(eventType);
				break;
			default:
				OnEventUnhandled(this, eventType);
				break;
			}
		}

		private void OnMediaChanged(IntPtr ptr)
		{
			_mediaPlayerMediaChanged?.Invoke(this, new MediaPlayerMediaChangedEventArgs(RetrieveEvent(ptr).Union.MediaPlayerMediaChanged.NewMedia));
		}

		private void OnNothingSpecial(IntPtr ptr)
		{
			_mediaPlayerNothingSpecial?.Invoke(this, EventArgs.Empty);
		}

		private void OnOpening(IntPtr ptr)
		{
			_mediaPlayerOpening?.Invoke(this, EventArgs.Empty);
		}

		private void OnBuffering(IntPtr ptr)
		{
			_mediaPlayerBuffering?.Invoke(this, new MediaPlayerBufferingEventArgs(RetrieveEvent(ptr).Union.MediaPlayerBuffering.NewCache));
		}

		private void OnPlaying(IntPtr ptr)
		{
			_mediaPlayerPlaying?.Invoke(this, EventArgs.Empty);
		}

		private void OnPaused(IntPtr ptr)
		{
			_mediaPlayerPaused?.Invoke(this, EventArgs.Empty);
		}

		private void OnStopped(IntPtr ptr)
		{
			_mediaPlayerStopped?.Invoke(this, EventArgs.Empty);
		}

		private void OnForward(IntPtr ptr)
		{
			_mediaPlayerForward?.Invoke(this, EventArgs.Empty);
		}

		private void OnBackward(IntPtr ptr)
		{
			_mediaPlayerBackward?.Invoke(this, EventArgs.Empty);
		}

		private void OnEndReached(IntPtr ptr)
		{
			_mediaPlayerEndReached?.Invoke(this, EventArgs.Empty);
		}

		private void OnEncounteredError(IntPtr ptr)
		{
			_mediaPlayerEncounteredError?.Invoke(this, EventArgs.Empty);
		}

		private void OnTimeChanged(IntPtr ptr)
		{
			_mediaPlayerTimeChanged?.Invoke(this, new MediaPlayerTimeChangedEventArgs(RetrieveEvent(ptr).Union.MediaPlayerTimeChanged.NewTime));
		}

		private void OnPositionChanged(IntPtr ptr)
		{
			_mediaPlayerPositionChanged?.Invoke(this, new MediaPlayerPositionChangedEventArgs(RetrieveEvent(ptr).Union.MediaPlayerPositionChanged.NewPosition));
		}

		private void OnSeekableChanged(IntPtr ptr)
		{
			_mediaPlayerSeekableChanged?.Invoke(this, new MediaPlayerSeekableChangedEventArgs(RetrieveEvent(ptr).Union.MediaPlayerSeekableChanged.NewSeekable));
		}

		private void OnPausableChanged(IntPtr ptr)
		{
			_mediaPlayerPausableChanged?.Invoke(this, new MediaPlayerPausableChangedEventArgs(RetrieveEvent(ptr).Union.MediaPlayerPausableChanged.NewPausable));
		}

		private void OnTitleChanged(IntPtr ptr)
		{
			_mediaPlayerTitleChanged?.Invoke(this, new MediaPlayerTitleChangedEventArgs(RetrieveEvent(ptr).Union.MediaPlayerTitleChanged.NewTitle));
		}

		private void OnChapterChanged(IntPtr ptr)
		{
			_mediaPlayerChapterChanged?.Invoke(this, new MediaPlayerChapterChangedEventArgs(RetrieveEvent(ptr).Union.MediaPlayerChapterChanged.NewChapter));
		}

		private void OnSnapshotTaken(IntPtr ptr)
		{
			IntPtr filename = RetrieveEvent(ptr).Union.MediaPlayerSnapshotTaken.Filename;
			_mediaPlayerSnapshotTaken?.Invoke(this, new MediaPlayerSnapshotTakenEventArgs(filename.FromUtf8()));
		}

		private void OnLengthChanged(IntPtr ptr)
		{
			_mediaPlayerLengthChanged?.Invoke(this, new MediaPlayerLengthChangedEventArgs(RetrieveEvent(ptr).Union.MediaPlayerLengthChanged.NewLength));
		}

		private void OnVout(IntPtr ptr)
		{
			_mediaPlayerVout?.Invoke(this, new MediaPlayerVoutEventArgs(RetrieveEvent(ptr).Union.MediaPlayerVoutChanged.NewCount));
		}

		private void OnScrambledChanged(IntPtr ptr)
		{
			_mediaPlayerScrambledChanged?.Invoke(this, new MediaPlayerScrambledChangedEventArgs(RetrieveEvent(ptr).Union.MediaPlayerScrambledChanged.NewScrambled));
		}

		private LibVLCEvent.EsChanged GetEsChanged(IntPtr ptr)
		{
			return RetrieveEvent(ptr).Union.EsChanged;
		}

		private void OnESAdded(IntPtr ptr)
		{
			LibVLCEvent.EsChanged esChanged = GetEsChanged(ptr);
			_mediaPlayerESAdded?.Invoke(this, new MediaPlayerESAddedEventArgs(esChanged.Id, esChanged.Type));
		}

		private void OnESDeleted(IntPtr ptr)
		{
			LibVLCEvent.EsChanged esChanged = GetEsChanged(ptr);
			_mediaPlayerESDeleted?.Invoke(this, new MediaPlayerESDeletedEventArgs(esChanged.Id, esChanged.Type));
		}

		private void OnESSelected(IntPtr ptr)
		{
			LibVLCEvent.EsChanged esChanged = GetEsChanged(ptr);
			_mediaPlayerESSelected?.Invoke(this, new MediaPlayerESSelectedEventArgs(esChanged.Id, esChanged.Type));
		}

		private void OnAudioDevice(IntPtr ptr)
		{
			IntPtr device = RetrieveEvent(ptr).Union.AudioDeviceChanged.Device;
			_mediaPlayerAudioDevice?.Invoke(this, new MediaPlayerAudioDeviceEventArgs(device.FromUtf8()));
		}

		private void OnCorked(IntPtr ptr)
		{
			_mediaPlayerCorked?.Invoke(this, EventArgs.Empty);
		}

		private void OnUncorked(IntPtr ptr)
		{
			_mediaPlayerUncorked?.Invoke(this, EventArgs.Empty);
		}

		private void OnMuted(IntPtr ptr)
		{
			_mediaPlayerMuted?.Invoke(this, EventArgs.Empty);
		}

		private void OnUnmuted(IntPtr ptr)
		{
			_mediaPlayerUnmuted?.Invoke(this, EventArgs.Empty);
		}

		private void OnVolumeChanged(IntPtr ptr)
		{
			_mediaPlayerVolumeChanged?.Invoke(this, new MediaPlayerVolumeChangedEventArgs(RetrieveEvent(ptr).Union.MediaPlayerVolumeChanged.Volume));
		}
	}
	internal class RendererDiscovererEventManager : EventManager
	{
		private EventHandler<RendererDiscovererItemAddedEventArgs>? _itemAdded;

		private EventHandler<RendererDiscovererItemDeletedEventArgs>? _itemDeleted;

		internal RendererDiscovererEventManager(IntPtr ptr)
			: base(ptr)
		{
		}

		protected internal override void AttachEvent<T>(EventType eventType, EventHandler<T> eventHandler)
		{
			switch (eventType)
			{
			case EventType.RendererDiscovererItemAdded:
				_itemAdded = (EventHandler<RendererDiscovererItemAddedEventArgs>)Delegate.Combine(_itemAdded, eventHandler as EventHandler<RendererDiscovererItemAddedEventArgs>);
				Attach(eventType, OnItemAdded);
				break;
			case EventType.RendererDiscovererItemDeleted:
				_itemDeleted = (EventHandler<RendererDiscovererItemDeletedEventArgs>)Delegate.Combine(_itemDeleted, eventHandler as EventHandler<RendererDiscovererItemDeletedEventArgs>);
				Attach(eventType, OnItemDeleted);
				break;
			default:
				OnEventUnhandled(this, eventType);
				break;
			}
		}

		protected internal override void DetachEvent<T>(EventType eventType, EventHandler<T> eventHandler)
		{
			switch (eventType)
			{
			case EventType.RendererDiscovererItemAdded:
				_itemAdded = (EventHandler<RendererDiscovererItemAddedEventArgs>)Delegate.Remove(_itemAdded, eventHandler as EventHandler<RendererDiscovererItemAddedEventArgs>);
				Detach(eventType);
				break;
			case EventType.RendererDiscovererItemDeleted:
				_itemDeleted = (EventHandler<RendererDiscovererItemDeletedEventArgs>)Delegate.Remove(_itemDeleted, eventHandler as EventHandler<RendererDiscovererItemDeletedEventArgs>);
				Detach(eventType);
				break;
			default:
				OnEventUnhandled(this, eventType);
				break;
			}
		}

		private void OnItemDeleted(IntPtr args)
		{
			LibVLCEvent.RendererDiscovererItemDeleted rendererDiscovererItemDeleted = RetrieveEvent(args).Union.RendererDiscovererItemDeleted;
			_itemDeleted?.Invoke(this, new RendererDiscovererItemDeletedEventArgs(new RendererItem(rendererDiscovererItemDeleted.item)));
		}

		private void OnItemAdded(IntPtr args)
		{
			LibVLCEvent.RendererDiscovererItemAdded rendererDiscovererItemAdded = RetrieveEvent(args).Union.RendererDiscovererItemAdded;
			_itemAdded?.Invoke(this, new RendererDiscovererItemAddedEventArgs(new RendererItem(rendererDiscovererItemAdded.item)));
		}
	}
	public class PlatformHelper
	{
		public static bool IsWindows => Environment.OSVersion.Platform == PlatformID.Win32NT;

		public static bool IsLinux => Environment.OSVersion.Platform == PlatformID.Unix;

		public static bool IsLinuxDesktop => IsLinux;

		public static bool IsMac => false;

		public static bool IsX64BitProcess => IntPtr.Size == 8;
	}
	public abstract class Internal : IDisposable
	{
		protected readonly Action<IntPtr> Release;

		protected bool IsDisposed;

		public IntPtr NativeReference { get; private set; }

		protected Internal(Func<IntPtr> create, Action<IntPtr> release)
		{
			Release = release;
			IntPtr intPtr = create();
			if (intPtr == IntPtr.Zero)
			{
				OnNativeInstanciationError();
			}
			NativeReference = intPtr;
		}

		public void Dispose()
		{
			Dispose(disposing: true);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (!IsDisposed && !(NativeReference == IntPtr.Zero))
			{
				Release(NativeReference);
				NativeReference = IntPtr.Zero;
				IsDisposed = true;
			}
		}

		internal virtual void OnNativeInstanciationError()
		{
			throw new VLCException("Failed to perform instanciation on the native side. Make sure you installed the correct VideoLAN.LibVLC.[YourPlatform] package in your platform specific project");
		}
	}
	internal interface IVideoControl : IVideoView
	{
		double Width { get; }

		double Height { get; }

		event EventHandler SizeChanged;
	}
	public interface IVideoView
	{
		MediaPlayer? MediaPlayer { get; set; }
	}
	public class LibVLC : Internal
	{
		[StructLayout(LayoutKind.Explicit)]
		internal struct Native
		{
			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_new")]
			internal static extern IntPtr LibVLCNew(int argc, IntPtr[] argv);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_release")]
			internal static extern void LibVLCRelease(IntPtr libVLC);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_add_intf")]
			internal static extern int LibVLCAddInterface(IntPtr libVLC, IntPtr name);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_set_exit_handler")]
			internal static extern void LibVLCSetExitHandler(IntPtr libVLC, IntPtr cb, IntPtr opaque);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_set_user_agent")]
			internal static extern void LibVLCSetUserAgent(IntPtr libVLC, IntPtr name, IntPtr http);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_set_app_id")]
			internal static extern void LibVLCSetAppId(IntPtr libVLC, IntPtr id, IntPtr version, IntPtr icon);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_log_unset")]
			internal static extern void LibVLCLogUnset(IntPtr libVLC);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_log_set_file")]
			internal static extern void LibVLCLogSetFile(IntPtr libVLC, IntPtr stream);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "libvlc_log_get_context")]
			internal static extern void LibVLCLogGetContext(IntPtr ctx, out IntPtr module, out IntPtr file, out UIntPtr line);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_log_set")]
			internal static extern void LibVLCLogSet(IntPtr libVLC, InternalLogCallback cb, IntPtr data);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_module_description_list_release")]
			internal static extern void LibVLCModuleDescriptionListRelease(IntPtr moduleDescriptionList);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_audio_filter_list_get")]
			internal static extern IntPtr LibVLCAudioFilterListGet(IntPtr libVLC);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_video_filter_list_get")]
			internal static extern IntPtr LibVLCVideoFilterListGet(IntPtr libVLC);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_audio_output_list_get")]
			internal static extern IntPtr LibVLCAudioOutputListGet(IntPtr libVLC);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_audio_output_list_release")]
			internal static extern void LibVLCAudioOutputListRelease(IntPtr list);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_audio_output_device_list_get")]
			internal static extern IntPtr LibVLCAudioOutputDeviceListGet(IntPtr libVLC, IntPtr aout);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_audio_output_device_list_release")]
			internal static extern void LibVLCAudioOutputDeviceListRelease(IntPtr list);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_media_discoverer_list_get")]
			internal static extern UIntPtr LibVLCMediaDiscovererListGet(IntPtr libVLC, MediaDiscovererCategory category, out IntPtr pppServices);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_media_discoverer_list_release")]
			internal static extern void LibVLCMediaDiscovererListRelease(IntPtr ppServices, UIntPtr count);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_dialog_set_callbacks")]
			internal static extern void LibVLCDialogSetCallbacks(IntPtr libVLC, DialogCallbacks callbacks, IntPtr data);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_renderer_discoverer_list_get")]
			internal static extern UIntPtr LibVLCRendererDiscovererGetList(IntPtr libVLC, out IntPtr discovererList);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_renderer_discoverer_list_release")]
			internal static extern void LibVLCRendererDiscovererReleaseList(IntPtr discovererList, UIntPtr count);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_retain")]
			internal static extern void LibVLCRetain(IntPtr libVLC);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_get_version")]
			internal static extern IntPtr LibVLCVersion();

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_get_changeset")]
			internal static extern IntPtr LibVLCChangeset();

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_errmsg")]
			internal static extern IntPtr LibVLCErrorMessage();

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_clearerr")]
			internal static extern void LibVLCClearError();

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_get_compiler")]
			internal static extern IntPtr LibVLCGetCompiler();

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_clock")]
			internal static extern long LibVLCClock();
		}

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void InternalExitCallback(IntPtr libVLCHandle);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void InternalLogCallback(IntPtr data, LogLevel logLevel, IntPtr logContext, IntPtr format, IntPtr args);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void InternalDisplayErrorCallback(IntPtr data, IntPtr title, IntPtr text);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void InternalDisplayLoginCallback(IntPtr data, IntPtr dialogId, IntPtr title, IntPtr text, IntPtr defaultUsername, bool askStore);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void InternalDisplayQuestionCallback(IntPtr data, IntPtr dialogId, IntPtr title, IntPtr text, DialogQuestionType type, IntPtr cancelText, IntPtr firstActionText, IntPtr secondActionText);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void InternalDisplayProgressCallback(IntPtr data, IntPtr dialogId, IntPtr title, IntPtr text, bool indeterminate, float position, IntPtr cancelText);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void InternalCancelCallback(IntPtr data, IntPtr dialogId);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		internal delegate void InternalUpdateProgressCallback(IntPtr data, IntPtr dialogId, float position, IntPtr text);

		internal readonly struct DialogCallbacks
		{
			internal readonly IntPtr DisplayError;

			internal readonly IntPtr DisplayLogin;

			internal readonly IntPtr DisplayQuestion;

			internal readonly IntPtr DisplayProgress;

			internal readonly IntPtr Cancel;

			internal readonly IntPtr UpdateProgress;

			internal DialogCallbacks(InternalDisplayErrorCallback displayError, InternalDisplayLoginCallback displayLogin, InternalDisplayQuestionCallback displayQuestion, InternalDisplayProgressCallback displayProgress, InternalCancelCallback cancel, InternalUpdateProgressCallback updateProgress)
			{
				DisplayError = Marshal.GetFunctionPointerForDelegate((Delegate)displayError);
				DisplayLogin = Marshal.GetFunctionPointerForDelegate((Delegate)displayLogin);
				DisplayQuestion = Marshal.GetFunctionPointerForDelegate((Delegate)displayQuestion);
				DisplayProgress = Marshal.GetFunctionPointerForDelegate((Delegate)displayProgress);
				Cancel = Marshal.GetFunctionPointerForDelegate((Delegate)cancel);
				UpdateProgress = Marshal.GetFunctionPointerForDelegate((Delegate)updateProgress);
			}
		}

		private readonly object _logLock = new object();

		private EventHandler<LogEventArgs>? _log;

		private IntPtr _logFileHandle;

		private GCHandle _gcHandle;

		internal ExitCallback? _exitCallback;

		private int _logSubscriberCount;

		private DisplayError? _error;

		private DisplayLogin? _login;

		private DisplayQuestion? _question;

		private DisplayProgress? _displayProgress;

		private UpdateProgress? _updateProgress;

		private readonly Dictionary<IntPtr, CancellationTokenSource> _cts = new Dictionary<IntPtr, CancellationTokenSource>();

		private static readonly InternalExitCallback ExitCallbackHandle = ExitCallback;

		private static readonly InternalLogCallback LogCallbackHandle = LogCallback;

		private static readonly InternalDisplayErrorCallback DisplayErrorCallbackHandle = DisplayErrorCallback;

		private static readonly InternalDisplayLoginCallback DisplayLoginCallbackHandle = DisplayLoginCallback;

		private static readonly InternalDisplayQuestionCallback DisplayQuestionCallbackHandle = DisplayQuestionCallback;

		private static readonly InternalDisplayProgressCallback DisplayProgressCallbackHandle = DisplayProgressCallback;

		private static readonly InternalCancelCallback CancelCallbackHandle = CancelCallback;

		private static readonly InternalUpdateProgressCallback UpdateProgressCallbackHandle = UpdateProgressCallback;

		private static readonly DialogCallbacks DialogCb = new DialogCallbacks(DisplayErrorCallbackHandle, DisplayLoginCallbackHandle, DisplayQuestionCallbackHandle, DisplayProgressCallbackHandle, CancelCallbackHandle, UpdateProgressCallbackHandle);

		public ModuleDescription[] AudioFilters => MarshalUtils.Retrieve(() => Native.LibVLCAudioFilterListGet(base.NativeReference), MarshalUtils.PtrToStructure<ModuleDescriptionStructure>, (ModuleDescriptionStructure s) => s.Build(), (ModuleDescriptionStructure module) => module.Next, Native.LibVLCModuleDescriptionListRelease);

		public ModuleDescription[] VideoFilters => MarshalUtils.Retrieve(() => Native.LibVLCVideoFilterListGet(base.NativeReference), MarshalUtils.PtrToStructure<ModuleDescriptionStructure>, (ModuleDescriptionStructure s) => s.Build(), (ModuleDescriptionStructure module) => module.Next, Native.LibVLCModuleDescriptionListRelease);

		public AudioOutputDescription[] AudioOutputs => MarshalUtils.Retrieve(() => Native.LibVLCAudioOutputListGet(base.NativeReference), (IntPtr ptr) => MarshalUtils.PtrToStructure<AudioOutputDescriptionStructure>(ptr), (AudioOutputDescriptionStructure s) => s.Build(), (AudioOutputDescriptionStructure s) => s.Next, Native.LibVLCAudioOutputListRelease);

		public bool DialogHandlersSet => _error != null;

		public RendererDescription[] RendererList => MarshalUtils.Retrieve(base.NativeReference, delegate(IntPtr nativeRef, out IntPtr array)
		{
			return Native.LibVLCRendererDiscovererGetList(nativeRef, out array);
		}, MarshalUtils.PtrToStructure<RendererDescriptionStructure>, (RendererDescriptionStructure m) => m.Build(), Native.LibVLCRendererDiscovererReleaseList);

		public string Version => Native.LibVLCVersion().FromUtf8();

		public string Changeset => Native.LibVLCChangeset().FromUtf8();

		public string? LastLibVLCError => Native.LibVLCErrorMessage().FromUtf8();

		public string LibVLCCompiler => Native.LibVLCGetCompiler().FromUtf8();

		public long Clock => Native.LibVLCClock();

		public event EventHandler<LogEventArgs> Log
		{
			add
			{
				lock (_logLock)
				{
					_log = (EventHandler<LogEventArgs>)Delegate.Combine(_log, value);
					if (_logSubscriberCount == 0)
					{
						Native.LibVLCLogSet(base.NativeReference, LogCallbackHandle, GCHandle.ToIntPtr(_gcHandle));
					}
					_logSubscriberCount++;
				}
			}
			remove
			{
				lock (_logLock)
				{
					_log = (EventHandler<LogEventArgs>)Delegate.Remove(_log, value);
					if (_logSubscriberCount > 0)
					{
						_logSubscriberCount--;
					}
					if (_logSubscriberCount == 0)
					{
						Native.LibVLCLogUnset(base.NativeReference);
					}
				}
			}
		}

		protected bool Equals(LibVLC other)
		{
			return base.NativeReference.Equals((object?)(nint)other.NativeReference);
		}

		public override bool Equals(object? obj)
		{
			if (obj == null)
			{
				return false;
			}
			if (this == obj)
			{
				return true;
			}
			if (obj.GetType() != GetType())
			{
				return false;
			}
			return Equals((LibVLC)obj);
		}

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

		public LibVLC(params string[] options)
			: base(() => MarshalUtils.CreateWithOptions(PatchOptions(options), Native.LibVLCNew), Native.LibVLCRelease)
		{
			_gcHandle = GCHandle.Alloc(this);
		}

		public LibVLC(bool enableDebugLogs, params string[] options)
			: base(() => MarshalUtils.CreateWithOptions(PatchOptions(options, enableDebugLogs), Native.LibVLCNew), Native.LibVLCRelease)
		{
			_gcHandle = GCHandle.Alloc(this);
		}

		public LibVLC(bool enableDebugLogs, bool useDefaultLibVLCOptions, params string[] options)
			: base(() => MarshalUtils.CreateWithOptions(PatchOptions(options, enableDebugLogs, useDefaultLibVLCOptions), Native.LibVLCNew), Native.LibVLCRelease)
		{
			_gcHandle = GCHandle.Alloc(this);
		}

		private static string[] PatchOptions(string[] options, bool enableDebugLogs = false, bool useDefaultLibVLCOptions = true)
		{
			if (options == null)
			{
				options = new string[0];
			}
			if (enableDebugLogs)
			{
				options = options.Concat(new string[1] { "--verbose=2" }).ToArray();
			}
			return options;
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				UnsetDialogHandlers();
				Native.LibVLCLogUnset(base.NativeReference);
				_gcHandle.Free();
				_exitCallback = null;
				_log = null;
			}
			base.Dispose(disposing);
		}

		public static bool operator ==(LibVLC? libvlc1, LibVLC? libvlc2)
		{
			IntPtr? intPtr = libvlc1?.NativeReference;
			IntPtr? intPtr2 = libvlc2?.NativeReference;
			if (intPtr.HasValue != intPtr2.HasValue)
			{
				return false;
			}
			if (!intPtr.HasValue)
			{
				return true;
			}
			return intPtr.GetValueOrDefault() == intPtr2.GetValueOrDefault();
		}

		public static bool operator !=(LibVLC? libvlc1, LibVLC? libvlc2)
		{
			IntPtr? intPtr = libvlc1?.NativeReference;
			IntPtr? intPtr2 = libvlc2?.NativeReference;
			if (intPtr.HasValue != intPtr2.HasValue)
			{
				return true;
			}
			if (!intPtr.HasValue)
			{
				return false;
			}
			return intPtr.GetValueOrDefault() != intPtr2.GetValueOrDefault();
		}

		public bool AddInterface(string? name)
		{
			IntPtr namePtr = name.ToUtf8();
			return MarshalUtils.PerformInteropAndFree(() => Native.LibVLCAddInterface(base.NativeReference, namePtr) == 0, namePtr);
		}

		public void SetExitHandler(ExitCallback cb)
		{
			_exitCallback = cb;
			if (cb == null)
			{
				Native.LibVLCSetExitHandler(base.NativeReference, IntPtr.Zero, IntPtr.Zero);
			}
			else
			{
				Native.LibVLCSetExitHandler(base.NativeReference, Marshal.GetFunctionPointerForDelegate((Delegate)ExitCallbackHandle), GCHandle.ToIntPtr(_gcHandle));
			}
		}

		public void SetUserAgent(string name, string http)
		{
			IntPtr nameUtf8 = name.ToUtf8();
			IntPtr httpUtf8 = http.ToUtf8();
			MarshalUtils.PerformInteropAndFree(delegate
			{
				Native.LibVLCSetUserAgent(base.NativeReference, nameUtf8, httpUtf8);
			}, nameUtf8, httpUtf8);
		}

		public void SetAppId(string? id, string? version, string? icon)
		{
			IntPtr idUtf8 = id.ToUtf8();
			IntPtr versionUtf8 = version.ToUtf8();
			IntPtr iconUtf8 = icon.ToUtf8();
			MarshalUtils.PerformInteropAndFree(delegate
			{
				Native.LibVLCSetAppId(base.NativeReference, idUtf8, versionUtf8, iconUtf8);
			}, idUtf8, versionUtf8, iconUtf8);
		}

		public bool CloseLogFile()
		{
			if (_logFileHandle == IntPtr.Zero)
			{
				return true;
			}
			return MarshalUtils.Close(_logFileHandle);
		}

		public void SetLogFile(string filename)
		{
			if (string.IsNullOrEmpty(filename))
			{
				throw new NullReferenceException("filename");
			}
			_logFileHandle = NativeFilePtr(filename);
			Native.LibVLCLogSetFile(base.NativeReference, _logFileHandle);
		}

		private IntPtr NativeFilePtr(string filename)
		{
			if (!MarshalUtils.Open(filename, out var fileHandle))
			{
				throw new VLCException("Could not get FILE * for log_set_file");
			}
			return fileHandle;
		}

		public AudioOutputDevice[] AudioOutputDevices(string audioOutputName)
		{
			return MarshalUtils.Retrieve(delegate
			{
				IntPtr audioOutputNameUtf8 = audioOutputName.ToUtf8();
				return MarshalUtils.PerformInteropAndFree(() => Native.LibVLCAudioOutputDeviceListGet(base.NativeReference, audioOutputNameUtf8), audioOutputNameUtf8);
			}, MarshalUtils.PtrToStructure<AudioOutputDeviceStructure>, (AudioOutputDeviceStructure s) => s.Build(), (AudioOutputDeviceStructure device) => device.Next, Native.LibVLCAudioOutputDeviceListRelease);
		}

		public MediaDiscovererDescription[] MediaDiscoverers(MediaDiscovererCategory discovererCategory)
		{
			return MarshalUtils.Retrieve(base.NativeReference, discovererCategory, delegate(IntPtr nativeRef, MediaDiscovererCategory enumType, out IntPtr array)
			{
				return Native.LibVLCMediaDiscovererListGet(nativeRef, enumType, out array);
			}, MarshalUtils.PtrToStructure<MediaDiscovererDescriptionStructure>, (MediaDiscovererDescriptionStructure m) => m.Build(), Native.LibVLCMediaDiscovererListRelease);
		}

		public void SetDialogHandlers(DisplayError error, DisplayLogin login, DisplayQuestion question, DisplayProgress displayProgress, UpdateProgress updateProgress)
		{
			_error = error ?? throw new ArgumentNullException("error");
			_login = login ?? throw new ArgumentNullException("login");
			_question = question ?? throw new ArgumentNullException("question");
			_displayProgress = displayProgress ?? throw new ArgumentNullException("displayProgress");
			_updateProgress = updateProgress ?? throw new ArgumentNullException("updateProgress");
			Native.LibVLCDialogSetCallbacks(base.NativeReference, DialogCb, GCHandle.ToIntPtr(_gcHandle));
		}

		public void UnsetDialogHandlers()
		{
			if (DialogHandlersSet)
			{
				Native.LibVLCDialogSetCallbacks(base.NativeReference, default(DialogCallbacks), IntPtr.Zero);
				_error = null;
				_login = null;
				_question = null;
				_displayProgress = null;
				_updateProgress = null;
			}
		}

		private void OnDisplayError(string? title, string? text)
		{
			_error?.Invoke(title, text);
		}

		private void OnDisplayLogin(IntPtr dialogId, string? title, string? text, string? defaultUsername, bool askStore)
		{
			if (_login != null)
			{
				CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
				Dialog dialog = new Dialog(new DialogId(dialogId));
				_cts[dialogId] = cancellationTokenSource;
				_login(dialog, title, text, defaultUsername, askStore, cancellationTokenSource.Token);
			}
		}

		private void OnDisplayQuestion(IntPtr dialogId, string? title, string? text, DialogQuestionType type, string? cancelText, string? firstActionText, string? secondActionText)
		{
			if (_question != null)
			{
				CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
				Dialog dialog = new Dialog(new DialogId(dialogId));
				_cts[dialogId] = cancellationTokenSource;
				_question(dialog, title, text, type, cancelText, firstActionText, secondActionText, cancellationTokenSource.Token);
			}
		}

		private void OnDisplayProgress(IntPtr dialogId, string? title, string? text, bool indeterminate, float position, string? cancelText)
		{
			if (_displayProgress != null)
			{
				CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
				Dialog dialog = new Dialog(new DialogId(dialogId));
				_cts[dialogId] = cancellationTokenSource;
				_displayProgress(dialog, title, text, indeterminate, position, cancelText, cancellationTokenSource.Token);
			}
		}

		private void OnCancel(IntPtr dialogId)
		{
			if (_cts.TryGetValue(dialogId, out CancellationTokenSource value))
			{
				value.Cancel();
				_cts.Remove(dialogId);
			}
		}

		private void OnUpdateProgress(IntPtr dialogId, float position, string? text)
		{
			if (_updateProgress != null)
			{
				Dialog dialog = new Dialog(new DialogId(dialogId));
				_updateProgress(dialog, position, text);
			}
		}

		private static void GetLogContext(IntPtr logContext, out string? module, out string? file, out uint? line)
		{
			Native.LibVLCLogGetContext(logContext, out var module2, out var file2, out var line2);
			line = ((line2 == UIntPtr.Zero) ? ((uint?)null) : new uint?(line2.ToUInt32()));
			module = module2.FromUtf8();
			file = file2.FromUtf8();
		}

		internal void Retain()
		{
			Native.LibVLCRetain(base.NativeReference);
		}

		public void ClearLibVLCError()
		{
			Native.LibVLCClearError();
		}

		[MonoPInvokeCallback(typeof(InternalExitCallback))]
		private static void ExitCallback(IntPtr libVLCHandle)
		{
			MarshalUtils.GetInstance<LibVLC>(libVLCHandle)?._exitCallback?.Invoke();
		}

		[MonoPInvokeCallback(typeof(InternalLogCallback))]
		private static void LogCallback(IntPtr libVLCHandle, LogLevel logLevel, IntPtr logContext, IntPtr format, IntPtr args)
		{
			LibVLC libVLC = MarshalUtils.GetInstance<LibVLC>(libVLCHandle);
			string message;
			string module;
			string file;
			uint? line;
			try
			{
				message = MarshalUtils.GetLogMessage(format, args);
				GetLogContext(logContext, out module, out file, out line);
				Task.Factory.StartNew(logAction);
			}
			catch
			{
			}
			void logAction()
			{
				libVLC?._log?.Invoke(null, new LogEventArgs(logLevel, message, module, file, line));
			}
		}

		[MonoPInvokeCallback(typeof(InternalDisplayErrorCallback))]
		private static void DisplayErrorCallback(IntPtr libVLCHandle, IntPtr title, IntPtr text)
		{
			MarshalUtils.GetInstance<LibVLC>(libVLCHandle)?.OnDisplayError(title.FromUtf8(), text.FromUtf8());
		}

		[MonoPInvokeCallback(typeof(InternalDisplayLoginCallback))]
		private static void DisplayLoginCallback(IntPtr libVLCHandle, IntPtr dialogId, IntPtr title, IntPtr text, IntPtr defaultUsername, bool askStore)
		{
			MarshalUtils.GetInstance<LibVLC>(libVLCHandle)?.OnDisplayLogin(dialogId, title.FromUtf8(), text.FromUtf8(), defaultUsername.FromUtf8(), askStore);
		}

		[MonoPInvokeCallback(typeof(InternalDisplayQuestionCallback))]
		private static void DisplayQuestionCallback(IntPtr libVLCHandle, IntPtr dialogId, IntPtr title, IntPtr text, DialogQuestionType type, IntPtr cancelText, IntPtr firstActionText, IntPtr secondActionText)
		{
			MarshalUtils.GetInstance<LibVLC>(libVLCHandle)?.OnDisplayQuestion(dialogId, title.FromUtf8(), text.FromUtf8(), type, cancelText.FromUtf8(), firstActionText.FromUtf8(), secondActionText.FromUtf8());
		}

		[MonoPInvokeCallback(typeof(InternalDisplayProgressCallback))]
		private static void DisplayProgressCallback(IntPtr libVLCHandle, IntPtr dialogId, IntPtr title, IntPtr text, bool indeterminate, float position, IntPtr cancelText)
		{
			MarshalUtils.GetInstance<LibVLC>(libVLCHandle)?.OnDisplayProgress(dialogId, title.FromUtf8(), text.FromUtf8(), indeterminate, position, cancelText.FromUtf8());
		}

		[MonoPInvokeCallback(typeof(InternalCancelCallback))]
		private static void CancelCallback(IntPtr libVLCHandle, IntPtr dialogId)
		{
			MarshalUtils.GetInstance<LibVLC>(libVLCHandle)?.OnCancel(dialogId);
		}

		[MonoPInvokeCallback(typeof(InternalUpdateProgressCallback))]
		private static void UpdateProgressCallback(IntPtr libVLCHandle, IntPtr dialogId, float position, IntPtr text)
		{
			MarshalUtils.GetInstance<LibVLC>(libVLCHandle)?.OnUpdateProgress(dialogId, position, text.FromUtf8());
		}
	}
	public enum LogLevel
	{
		Debug = 0,
		Notice = 2,
		Warning = 3,
		Error = 4
	}
	[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
	public delegate void ExitCallback();
	internal enum EventType
	{
		MediaMetaChanged = 0,
		MediaSubItemAdded = 1,
		MediaDurationChanged = 2,
		MediaParsedChanged = 3,
		MediaFreed = 4,
		MediaStateChanged = 5,
		MediaSubItemTreeAdded = 6,
		MediaPlayerMediaChanged = 256,
		MediaPlayerNothingSpecial = 257,
		MediaPlayerOpening = 258,
		MediaPlayerBuffering = 259,
		MediaPlayerPlaying = 260,
		MediaPlayerPaused = 261,
		MediaPlayerStopped = 262,
		MediaPlayerForward = 263,
		MediaPlayerBackward = 264,
		MediaPlayerEndReached = 265,
		MediaPlayerEncounteredError = 266,
		MediaPlayerTimeChanged = 267,
		MediaPlayerPositionChanged = 268,
		MediaPlayerSeekableChanged = 269,
		MediaPlayerPausableChanged = 270,
		MediaPlayerTitleChanged = 271,
		MediaPlayerSnapshotTaken = 272,
		MediaPlayerLengthChanged = 273,
		MediaPlayerVout = 274,
		MediaPlayerScrambledChanged = 275,
		MediaPlayerESAdded = 276,
		MediaPlayerESDeleted = 277,
		MediaPlayerESSelected = 278,
		MediaPlayerCorked = 279,
		MediaPlayerUncorked = 280,
		MediaPlayerMuted = 281,
		MediaPlayerUnmuted = 282,
		MediaPlayerAudioVolume = 283,
		MediaPlayerAudioDevice = 284,
		MediaPlayerChapterChanged = 285,
		MediaListItemAdded = 512,
		MediaListWillAddItem = 513,
		MediaListItemDeleted = 514,
		MediaListWillDeleteItem = 515,
		MediaListEndReached = 516,
		MediaListViewItemAdded = 768,
		MediaListViewWillAddItem = 769,
		MediaListViewItemDeleted = 770,
		MediaListViewWillDeleteItem = 771,
		MediaListPlayerPlayed = 1024,
		MediaListPlayerNextItemSet = 1025,
		MediaListPlayerStopped = 1026,
		MediaDiscovererStarted = 1280,
		MediaDiscovererStopped = 1281,
		RendererDiscovererItemAdded = 1282,
		RendererDiscovererItemDeleted = 1283,
		VlmMediaAdded = 1536,
		VlmMediaRemoved = 1537,
		VlmMediaChanged = 1538,
		VlmMediaInstanceStarted = 1539,
		VlmMediaInstanceStopped = 1540,
		VlmMediaInstanceStatusInit = 1541,
		VlmMediaInstanceStatusOpening = 1542,
		VlmMediaInstanceStatusPlaying = 1543,
		VlmMediaInstanceStatusPause = 1544,
		VlmMediaInstanceStatusEnd = 1545,
		VlmMediaInstanceStatusError = 1546
	}
	internal readonly struct LibVLCEvent
	{
		[StructLayout(LayoutKind.Explicit)]
		internal readonly struct EventUnion
		{
			[FieldOffset(0)]
			internal readonly MediaMetaChanged MediaMetaChanged;

			[FieldOffset(0)]
			internal readonly MediaSubItemAdded MediaSubItemAdded;

			[FieldOffset(0)]
			internal readonly MediaDurationChanged MediaDurationChanged;

			[FieldOffset(0)]
			internal readonly MediaParsedChanged MediaParsedChanged;

			[FieldOffset(0)]
			internal readonly MediaFreed MediaFreed;

			[FieldOffset(0)]
			internal readonly MediaStateChanged MediaStateChanged;

			[FieldOffset(0)]
			internal readonly MediaSubItemTreeAdded MediaSubItemTreeAdded;

			[FieldOffset(0)]
			internal readonly MediaPlayerBuffering MediaPlayerBuffering;

			[FieldOffset(0)]
			internal readonly MediaPlayerChapterChanged MediaPlayerChapterChanged;

			[FieldOffset(0)]
			internal readonly MediaPlayerPositionChanged MediaPlayerPositionChanged;

			[FieldOffset(0)]
			internal readonly MediaPlayerTimeChanged MediaPlayerTimeChanged;

			[FieldOffset(0)]
			internal readonly MediaPlayerTitleChanged MediaPlayerTitleChanged;

			[FieldOffset(0)]
			internal readonly MediaPlayerSeekableChanged MediaPlayerSeekableChanged;

			[FieldOffset(0)]
			internal readonly MediaPlayerPausableChanged MediaPlayerPausableChanged;

			[FieldOffset(0)]
			internal readonly MediaPlayerScrambledChanged MediaPlayerScrambledChanged;

			[FieldOffset(0)]
			internal readonly MediaPlayerVoutChanged MediaPlayerVoutChanged;

			[FieldOffset(0)]
			internal readonly MediaListItemAdded MediaListItemAdded;

			[FieldOffset(0)]
			internal readonly MediaListWillAddItem MediaListWillAddItem;

			[FieldOffset(0)]
			internal readonly MediaListItemDeleted MediaListItemDeleted;

			[FieldOffset(0)]
			internal readonly MediaListWillDeleteItem MediaListWillDeleteItem;

			[FieldOffset(0)]
			internal readonly MediaListPlayerNextItemSet MediaListPlayerNextItemSet;

			[FieldOffset(0)]
			internal readonly MediaPlayerSnapshotTaken MediaPlayerSnapshotTaken;

			[FieldOffset(0)]
			internal readonly MediaPlayerLengthChanged MediaPlayerLengthChanged;

			[FieldOffset(0)]
			internal readonly VlmMediaEvent VlmMediaEvent;

			[FieldOffset(0)]
			internal readonly MediaPlayerMediaChanged MediaPlayerMediaChanged;

			[FieldOffset(0)]
			internal readonly EsChanged EsChanged;

			[FieldOffset(0)]
			internal readonly VolumeChanged MediaPlayerVolumeChanged;

			[FieldOffset(0)]
			internal readonly AudioDeviceChanged AudioDeviceChanged;

			[FieldOffset(0)]
			internal readonly RendererDiscovererItemAdded RendererDiscovererItemAdded;

			[FieldOffset(0)]
			internal readonly RendererDiscovererItemDeleted RendererDiscovererItemDeleted;
		}

		internal readonly struct MediaMetaChanged
		{
			internal readonly MetadataType MetaType;
		}

		internal readonly struct MediaSubItemAdded
		{
			internal readonly IntPtr NewChild;
		}

		internal readonly struct MediaDurationChanged
		{
			internal readonly long NewDuration;
		}

		internal readonly struct MediaParsedChanged
		{
			internal readonly MediaParsedStatus NewStatus;
		}

		internal readonly struct MediaFreed
		{
			internal readonly IntPtr MediaInstance;
		}

		internal readonly struct MediaStateChanged
		{
			internal readonly VLCState NewState;
		}

		internal readonly struct MediaSubItemTreeAdded
		{
			internal readonly IntPtr MediaInstance;
		}

		internal readonly struct MediaPlayerBuffering
		{
			internal readonly float NewCache;
		}

		internal readonly struct MediaPlayerChapterChanged
		{
			internal readonly int NewChapter;
		}

		internal readonly struct MediaPlayerPositionChanged
		{
			internal readonly float NewPosition;
		}

		internal readonly struct MediaPlayerTimeChanged
		{
			internal readonly long NewTime;
		}

		internal readonly struct MediaPlayerTitleChanged
		{
			internal readonly int NewTitle;
		}

		internal readonly struct MediaPlayerSeekableChanged
		{
			internal readonly int NewSeekable;
		}

		internal readonly struct MediaPlayerPausableChanged
		{
			internal readonly int NewPausable;
		}

		internal readonly struct MediaPlayerScrambledChanged
		{
			internal readonly int NewScrambled;
		}

		internal readonly struct MediaPlayerVoutChanged
		{
			internal readonly int NewCount;
		}

		internal readonly struct MediaPlayerSnapshotTaken
		{
			internal readonly IntPtr Filename;
		}

		internal readonly struct MediaPlayerLengthChanged
		{
			internal readonly long NewLength;
		}

		internal readonly struct EsChanged
		{
			internal readonly TrackType Type;

			internal readonly int Id;
		}

		internal readonly struct AudioDeviceChanged
		{
			internal readonly IntPtr Device;
		}

		internal readonly struct MediaPlayerMediaChanged
		{
			internal readonly IntPtr NewMedia;
		}

		internal readonly struct VolumeChanged
		{
			internal readonly float Volume;
		}

		internal readonly struct MediaListItemAdded
		{
			internal readonly IntPtr MediaInstance;

			internal readonly int Index;
		}

		internal readonly struct MediaListWillAddItem
		{
			internal readonly IntPtr MediaInstance;

			internal readonly int Index;
		}

		internal readonly struct MediaListItemDeleted
		{
			internal readonly IntPtr MediaInstance;

			internal readonly int Index;
		}

		internal readonly struct MediaListWillDeleteItem
		{
			internal readonly IntPtr MediaInstance;

			internal readonly int Index;
		}

		internal readonly struct MediaListPlayerNextItemSet
		{
			internal readonly IntPtr MediaInstance;
		}

		internal readonly struct VlmMediaEvent
		{
			internal readonly IntPtr MediaName;

			internal readonly IntPtr InstanceName;
		}

		internal readonly struct RendererDiscovererItemAdded
		{
			internal readonly IntPtr item;
		}

		internal readonly struct RendererDiscovererItemDeleted
		{
			internal readonly IntPtr item;
		}

		internal readonly EventType Type;

		internal readonly IntPtr Sender;

		internal readonly EventUnion Union;
	}
	public class MediaMetaChangedEventArgs : EventArgs
	{
		public readonly MetadataType MetadataType;

		internal MediaMetaChangedEventArgs(MetadataType metadataType)
		{
			MetadataType = metadataType;
		}
	}
	public class MediaParsedChangedEventArgs : EventArgs
	{
		public readonly MediaParsedStatus ParsedStatus;

		internal MediaParsedChangedEventArgs(MediaParsedStatus parsedStatus)
		{
			ParsedStatus = parsedStatus;
		}
	}
	public class MediaSubItemAddedEventArgs : EventArgs
	{
		public readonly Media SubItem;

		internal MediaSubItemAddedEventArgs(IntPtr mediaPtr)
		{
			SubItem = new Media(mediaPtr);
		}
	}
	public class MediaDurationChangedEventArgs : EventArgs
	{
		public readonly long Duration;

		internal MediaDurationChangedEventArgs(long duration)
		{
			Duration = duration;
		}
	}
	public class MediaFreedEventArgs : EventArgs
	{
		public readonly Media Media;

		internal MediaFreedEventArgs(IntPtr mediaPtr)
		{
			Media = new Media(mediaPtr);
		}
	}
	public class MediaStateChangedEventArgs : EventArgs
	{
		public readonly VLCState State;

		internal MediaStateChangedEventArgs(VLCState state)
		{
			State = state;
		}
	}
	public class MediaSubItemTreeAddedEventArgs : EventArgs
	{
		public readonly Media SubItem;

		internal MediaSubItemTreeAddedEventArgs(IntPtr subItemPtr)
		{
			SubItem = new Media(subItemPtr);
		}
	}
	public class MediaPlayerMediaChangedEventArgs : EventArgs
	{
		public readonly Media Media;

		internal MediaPlayerMediaChangedEventArgs(IntPtr mediaPtr)
		{
			Media = new Media(mediaPtr);
		}
	}
	public class MediaPlayerBufferingEventArgs : EventArgs
	{
		public readonly float Cache;

		internal MediaPlayerBufferingEventArgs(float cache)
		{
			Cache = cache;
		}
	}
	public class MediaPlayerTimeChangedEventArgs : EventArgs
	{
		public readonly long Time;

		internal MediaPlayerTimeChangedEventArgs(long time)
		{
			Time = time;
		}
	}
	public class MediaPlayerPositionChangedEventArgs : EventArgs
	{
		public readonly float Position;

		internal MediaPlayerPositionChangedEventArgs(float position)
		{
			Position = position;
		}
	}
	public class MediaPlayerSeekableChangedEventArgs : EventArgs
	{
		public readonly int Seekable;

		internal MediaPlayerSeekableChangedEventArgs(int seekable)
		{
			Seekable = seekable;
		}
	}
	public class MediaPlayerPausableChangedEventArgs : EventArgs
	{
		public readonly int Pausable;

		internal MediaPlayerPausableChangedEventArgs(int pausable)
		{
			Pausable = pausable;
		}
	}
	public class MediaPlayerTitleChangedEventArgs : EventArgs
	{
		public readonly int Title;

		internal MediaPlayerTitleChangedEventArgs(int title)
		{
			Title = title;
		}
	}
	public class MediaPlayerChapterChangedEventArgs : EventArgs
	{
		public readonly int Chapter;

		internal MediaPlayerChapterChangedEventArgs(int chapter)
		{
			Chapter = chapter;
		}
	}
	public class MediaPlayerSnapshotTakenEventArgs : EventArgs
	{
		public readonly string Filename;

		internal MediaPlayerSnapshotTakenEventArgs(string filename)
		{
			Filename = filename;
		}
	}
	public class MediaPlayerLengthChangedEventArgs : EventArgs
	{
		public readonly long Length;

		internal MediaPlayerLengthChangedEventArgs(long length)
		{
			Length = length;
		}
	}
	public class MediaPlayerVoutEventArgs : EventArgs
	{
		public readonly int Count;

		internal MediaPlayerVoutEventArgs(int count)
		{
			Count = count;
		}
	}
	public class MediaPlayerScrambledChangedEventArgs : EventArgs
	{
		public readonly int Scrambled;

		internal MediaPlayerScrambledChangedEventArgs(int scrambled)
		{
			Scrambled = scrambled;
		}
	}
	public class MediaPlayerESAddedEventArgs : EventArgs
	{
		public readonly int Id;

		public readonly TrackType Type;

		internal MediaPlayerESAddedEventArgs(int id, TrackType type)
		{
			Id = id;
			Type = type;
		}
	}
	public class MediaPlayerESDeletedEventArgs : EventArgs
	{
		public readonly int Id;

		public readonly TrackType Type;

		internal MediaPlayerESDeletedEventArgs(int id, TrackType type)
		{
			Id = id;
			Type = type;
		}
	}
	public class MediaPlayerESSelectedEventArgs : EventArgs
	{
		public readonly int Id;

		public readonly TrackType Type;

		internal MediaPlayerESSelectedEventArgs(int id, TrackType type)
		{
			Id = id;
			Type = type;
		}
	}
	public class MediaPlayerAudioDeviceEventArgs : EventArgs
	{
		public readonly string AudioDevice;

		internal MediaPlayerAudioDeviceEventArgs(string audioDevice)
		{
			AudioDevice = audioDevice;
		}
	}
	public class MediaPlayerVolumeChangedEventArgs : EventArgs
	{
		public readonly float Volume;

		internal MediaPlayerVolumeChangedEventArgs(float volume)
		{
			Volume = volume;
		}
	}
	public abstract class MediaListBaseEventArgs : EventArgs
	{
		public readonly Media Media;

		public readonly int Index;

		protected internal MediaListBaseEventArgs(Media media, int index)
		{
			Media = media;
			Index = index;
		}
	}
	public class MediaListItemAddedEventArgs : MediaListBaseEventArgs
	{
		internal MediaListItemAddedEventArgs(Media media, int index)
			: base(media, index)
		{
		}
	}
	public class MediaListWillAddItemEventArgs : MediaListBaseEventArgs
	{
		internal MediaListWillAddItemEventArgs(Media media, int index)
			: base(media, index)
		{
		}
	}
	public class MediaListItemDeletedEventArgs : MediaListBaseEventArgs
	{
		internal MediaListItemDeletedEventArgs(Media media, int index)
			: base(media, index)
		{
		}
	}
	public class MediaListWillDeleteItemEventArgs : MediaListBaseEventArgs
	{
		internal MediaListWillDeleteItemEventArgs(Media media, int index)
			: base(media, index)
		{
		}
	}
	public class RendererDiscovererItemAddedEventArgs : EventArgs
	{
		public RendererItem RendererItem { get; }

		internal RendererDiscovererItemAddedEventArgs(RendererItem rendererItem)
		{
			RendererItem = rendererItem;
		}
	}
	public class RendererDiscovererItemDeletedEventArgs : EventArgs
	{
		public RendererItem RendererItem { get; }

		internal RendererDiscovererItemDeletedEventArgs(RendererItem rendererItem)
		{
			RendererItem = rendererItem;
		}
	}
	public sealed class LogEventArgs : EventArgs
	{
		public LogLevel Level { get; }

		public string Message { get; }

		public string? Module { get; }

		public string? SourceFile { get; }

		public uint? SourceLine { get; }

		public string FormattedLog { get; }

		internal LogEventArgs(LogLevel level, string message, string? module, string? sourceFile, uint? sourceLine)
		{
			Level = level;
			Message = message;
			Module = module;
			SourceFile = sourceFile;
			SourceLine = sourceLine;
			FormattedLog = $"{module} {level}: {message}";
		}
	}
	public class Media : Internal
	{
		[StructLayout(LayoutKind.Sequential, Size = 1)]
		internal struct Native
		{
			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_media_new_location")]
			internal static extern IntPtr LibVLCMediaNewLocation(IntPtr libVLC, IntPtr mrl);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_media_new_path")]
			internal static extern IntPtr LibVLCMediaNewPath(IntPtr libVLC, IntPtr path);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_media_new_as_node")]
			internal static extern IntPtr LibVLCMediaNewAsNode(IntPtr libVLC, IntPtr name);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_media_new_fd")]
			internal static extern IntPtr LibVLCMediaNewFd(IntPtr libVLC, int fd);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_media_release")]
			internal static extern void LibVLCMediaRelease(IntPtr media);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_media_list_media")]
			internal static extern IntPtr LibVLCMediaListMedia(IntPtr mediaList);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_media_new_callbacks")]
			internal static extern IntPtr LibVLCMediaNewCallbacks(IntPtr libVLC, InternalOpenMedia openCb, InternalReadMedia readCb, InternalSeekMedia? seekCb, InternalCloseMedia closeCb, IntPtr opaque);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_media_add_option")]
			internal static extern void LibVLCMediaAddOption(IntPtr media, IntPtr option);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_media_add_option_flag")]
			internal static extern void LibVLCMediaAddOptionFlag(IntPtr media, IntPtr options, uint flags);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_media_get_mrl")]
			internal static extern IntPtr LibVLCMediaGetMrl(IntPtr media);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_media_duplicate")]
			internal static extern IntPtr LibVLCMediaDuplicate(IntPtr media);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_media_get_meta")]
			internal static extern IntPtr LibVLCMediaGetMeta(IntPtr media, MetadataType metadataType);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_media_set_meta")]
			internal static extern void LibVLCMediaSetMeta(IntPtr media, MetadataType metadataType, IntPtr value);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_media_save_meta")]
			internal static extern int LibVLCMediaSaveMeta(IntPtr media);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_media_get_state")]
			internal static extern VLCState LibVLCMediaGetState(IntPtr media);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_media_event_manager")]
			internal static extern IntPtr LibVLCMediaEventManager(IntPtr media);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_media_get_stats")]
			internal static extern int LibVLCMediaGetStats(IntPtr media, out MediaStats statistics);

			[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_media_get_duration")]
			internal static extern long LibVLCMediaGetDuration(IntPtr

BepInEx/plugins/wlVLC/System.ValueTuple.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Numerics.Hashing;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using FxResources.System.ValueTuple;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyDefaultAlias("System.ValueTuple")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyDescription("System.ValueTuple")]
[assembly: AssemblyFileVersion("4.600.125.16908")]
[assembly: AssemblyInformationalVersion("4.6.1+6b84308c9ad012f53240d72c1d716d7e42546483")]
[assembly: AssemblyProduct("Microsoft® .NET")]
[assembly: AssemblyTitle("System.ValueTuple")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/dotnet/maintenance-packages")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyVersion("4.0.5.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 FxResources.System.ValueTuple
{
	internal static class SR
	{
	}
}
namespace System
{
	public static class TupleExtensions
	{
		[EditorBrowsable(EditorBrowsableState.Never)]
		public static void Deconstruct<T1>(this Tuple<T1> value, out T1 item1)
		{
			item1 = value.Item1;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public static void Deconstruct<T1, T2>(this Tuple<T1, T2> value, out T1 item1, out T2 item2)
		{
			item1 = value.Item1;
			item2 = value.Item2;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public static void Deconstruct<T1, T2, T3>(this Tuple<T1, T2, T3> value, out T1 item1, out T2 item2, out T3 item3)
		{
			item1 = value.Item1;
			item2 = value.Item2;
			item3 = value.Item3;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public static void Deconstruct<T1, T2, T3, T4>(this Tuple<T1, T2, T3, T4> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4)
		{
			item1 = value.Item1;
			item2 = value.Item2;
			item3 = value.Item3;
			item4 = value.Item4;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public static void Deconstruct<T1, T2, T3, T4, T5>(this Tuple<T1, T2, T3, T4, T5> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5)
		{
			item1 = value.Item1;
			item2 = value.Item2;
			item3 = value.Item3;
			item4 = value.Item4;
			item5 = value.Item5;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public static void Deconstruct<T1, T2, T3, T4, T5, T6>(this Tuple<T1, T2, T3, T4, T5, T6> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6)
		{
			item1 = value.Item1;
			item2 = value.Item2;
			item3 = value.Item3;
			item4 = value.Item4;
			item5 = value.Item5;
			item6 = value.Item6;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7>(this Tuple<T1, T2, T3, T4, T5, T6, T7> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7)
		{
			item1 = value.Item1;
			item2 = value.Item2;
			item3 = value.Item3;
			item4 = value.Item4;
			item5 = value.Item5;
			item6 = value.Item6;
			item7 = value.Item7;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8)
		{
			item1 = value.Item1;
			item2 = value.Item2;
			item3 = value.Item3;
			item4 = value.Item4;
			item5 = value.Item5;
			item6 = value.Item6;
			item7 = value.Item7;
			item8 = value.Rest.Item1;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9)
		{
			item1 = value.Item1;
			item2 = value.Item2;
			item3 = value.Item3;
			item4 = value.Item4;
			item5 = value.Item5;
			item6 = value.Item6;
			item7 = value.Item7;
			item8 = value.Rest.Item1;
			item9 = value.Rest.Item2;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10)
		{
			item1 = value.Item1;
			item2 = value.Item2;
			item3 = value.Item3;
			item4 = value.Item4;
			item5 = value.Item5;
			item6 = value.Item6;
			item7 = value.Item7;
			item8 = value.Rest.Item1;
			item9 = value.Rest.Item2;
			item10 = value.Rest.Item3;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11)
		{
			item1 = value.Item1;
			item2 = value.Item2;
			item3 = value.Item3;
			item4 = value.Item4;
			item5 = value.Item5;
			item6 = value.Item6;
			item7 = value.Item7;
			item8 = value.Rest.Item1;
			item9 = value.Rest.Item2;
			item10 = value.Rest.Item3;
			item11 = value.Rest.Item4;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12)
		{
			item1 = value.Item1;
			item2 = value.Item2;
			item3 = value.Item3;
			item4 = value.Item4;
			item5 = value.Item5;
			item6 = value.Item6;
			item7 = value.Item7;
			item8 = value.Rest.Item1;
			item9 = value.Rest.Item2;
			item10 = value.Rest.Item3;
			item11 = value.Rest.Item4;
			item12 = value.Rest.Item5;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13)
		{
			item1 = value.Item1;
			item2 = value.Item2;
			item3 = value.Item3;
			item4 = value.Item4;
			item5 = value.Item5;
			item6 = value.Item6;
			item7 = value.Item7;
			item8 = value.Rest.Item1;
			item9 = value.Rest.Item2;
			item10 = value.Rest.Item3;
			item11 = value.Rest.Item4;
			item12 = value.Rest.Item5;
			item13 = value.Rest.Item6;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14)
		{
			item1 = value.Item1;
			item2 = value.Item2;
			item3 = value.Item3;
			item4 = value.Item4;
			item5 = value.Item5;
			item6 = value.Item6;
			item7 = value.Item7;
			item8 = value.Rest.Item1;
			item9 = value.Rest.Item2;
			item10 = value.Rest.Item3;
			item11 = value.Rest.Item4;
			item12 = value.Rest.Item5;
			item13 = value.Rest.Item6;
			item14 = value.Rest.Item7;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15>>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15)
		{
			item1 = value.Item1;
			item2 = value.Item2;
			item3 = value.Item3;
			item4 = value.Item4;
			item5 = value.Item5;
			item6 = value.Item6;
			item7 = value.Item7;
			item8 = value.Rest.Item1;
			item9 = value.Rest.Item2;
			item10 = value.Rest.Item3;
			item11 = value.Rest.Item4;
			item12 = value.Rest.Item5;
			item13 = value.Rest.Item6;
			item14 = value.Rest.Item7;
			item15 = value.Rest.Rest.Item1;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16>>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16)
		{
			item1 = value.Item1;
			item2 = value.Item2;
			item3 = value.Item3;
			item4 = value.Item4;
			item5 = value.Item5;
			item6 = value.Item6;
			item7 = value.Item7;
			item8 = value.Rest.Item1;
			item9 = value.Rest.Item2;
			item10 = value.Rest.Item3;
			item11 = value.Rest.Item4;
			item12 = value.Rest.Item5;
			item13 = value.Rest.Item6;
			item14 = value.Rest.Item7;
			item15 = value.Rest.Rest.Item1;
			item16 = value.Rest.Rest.Item2;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17>>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17)
		{
			item1 = value.Item1;
			item2 = value.Item2;
			item3 = value.Item3;
			item4 = value.Item4;
			item5 = value.Item5;
			item6 = value.Item6;
			item7 = value.Item7;
			item8 = value.Rest.Item1;
			item9 = value.Rest.Item2;
			item10 = value.Rest.Item3;
			item11 = value.Rest.Item4;
			item12 = value.Rest.Item5;
			item13 = value.Rest.Item6;
			item14 = value.Rest.Item7;
			item15 = value.Rest.Rest.Item1;
			item16 = value.Rest.Rest.Item2;
			item17 = value.Rest.Rest.Item3;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18>>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17, out T18 item18)
		{
			item1 = value.Item1;
			item2 = value.Item2;
			item3 = value.Item3;
			item4 = value.Item4;
			item5 = value.Item5;
			item6 = value.Item6;
			item7 = value.Item7;
			item8 = value.Rest.Item1;
			item9 = value.Rest.Item2;
			item10 = value.Rest.Item3;
			item11 = value.Rest.Item4;
			item12 = value.Rest.Item5;
			item13 = value.Rest.Item6;
			item14 = value.Rest.Item7;
			item15 = value.Rest.Rest.Item1;
			item16 = value.Rest.Rest.Item2;
			item17 = value.Rest.Rest.Item3;
			item18 = value.Rest.Rest.Item4;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19>>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17, out T18 item18, out T19 item19)
		{
			item1 = value.Item1;
			item2 = value.Item2;
			item3 = value.Item3;
			item4 = value.Item4;
			item5 = value.Item5;
			item6 = value.Item6;
			item7 = value.Item7;
			item8 = value.Rest.Item1;
			item9 = value.Rest.Item2;
			item10 = value.Rest.Item3;
			item11 = value.Rest.Item4;
			item12 = value.Rest.Item5;
			item13 = value.Rest.Item6;
			item14 = value.Rest.Item7;
			item15 = value.Rest.Rest.Item1;
			item16 = value.Rest.Rest.Item2;
			item17 = value.Rest.Rest.Item3;
			item18 = value.Rest.Rest.Item4;
			item19 = value.Rest.Rest.Item5;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19, T20>>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17, out T18 item18, out T19 item19, out T20 item20)
		{
			item1 = value.Item1;
			item2 = value.Item2;
			item3 = value.Item3;
			item4 = value.Item4;
			item5 = value.Item5;
			item6 = value.Item6;
			item7 = value.Item7;
			item8 = value.Rest.Item1;
			item9 = value.Rest.Item2;
			item10 = value.Rest.Item3;
			item11 = value.Rest.Item4;
			item12 = value.Rest.Item5;
			item13 = value.Rest.Item6;
			item14 = value.Rest.Item7;
			item15 = value.Rest.Rest.Item1;
			item16 = value.Rest.Rest.Item2;
			item17 = value.Rest.Rest.Item3;
			item18 = value.Rest.Rest.Item4;
			item19 = value.Rest.Rest.Item5;
			item20 = value.Rest.Rest.Item6;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19, T20, T21>>> value, out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17, out T18 item18, out T19 item19, out T20 item20, out T21 item21)
		{
			item1 = value.Item1;
			item2 = value.Item2;
			item3 = value.Item3;
			item4 = value.Item4;
			item5 = value.Item5;
			item6 = value.Item6;
			item7 = value.Item7;
			item8 = value.Rest.Item1;
			item9 = value.Rest.Item2;
			item10 = value.Rest.Item3;
			item11 = value.Rest.Item4;
			item12 = value.Rest.Item5;
			item13 = value.Rest.Item6;
			item14 = value.Rest.Item7;
			item15 = value.Rest.Rest.Item1;
			item16 = value.Rest.Rest.Item2;
			item17 = value.Rest.Rest.Item3;
			item18 = value.Rest.Rest.Item4;
			item19 = value.Rest.Rest.Item5;
			item20 = value.Rest.Rest.Item6;
			item21 = value.Rest.Rest.Item7;
		}

		public static ValueTuple<T1> ToValueTuple<T1>(this Tuple<T1> value)
		{
			return ValueTuple.Create(value.Item1);
		}

		public static (T1, T2) ToValueTuple<T1, T2>(this Tuple<T1, T2> value)
		{
			return ValueTuple.Create(value.Item1, value.Item2);
		}

		public static (T1, T2, T3) ToValueTuple<T1, T2, T3>(this Tuple<T1, T2, T3> value)
		{
			return ValueTuple.Create(value.Item1, value.Item2, value.Item3);
		}

		public static (T1, T2, T3, T4) ToValueTuple<T1, T2, T3, T4>(this Tuple<T1, T2, T3, T4> value)
		{
			return ValueTuple.Create(value.Item1, value.Item2, value.Item3, value.Item4);
		}

		public static (T1, T2, T3, T4, T5) ToValueTuple<T1, T2, T3, T4, T5>(this Tuple<T1, T2, T3, T4, T5> value)
		{
			return ValueTuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5);
		}

		public static (T1, T2, T3, T4, T5, T6) ToValueTuple<T1, T2, T3, T4, T5, T6>(this Tuple<T1, T2, T3, T4, T5, T6> value)
		{
			return ValueTuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6);
		}

		public static (T1, T2, T3, T4, T5, T6, T7) ToValueTuple<T1, T2, T3, T4, T5, T6, T7>(this Tuple<T1, T2, T3, T4, T5, T6, T7> value)
		{
			return ValueTuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7);
		}

		public static (T1, T2, T3, T4, T5, T6, T7, T8) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>> value)
		{
			return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, ValueTuple.Create(value.Rest.Item1));
		}

		public static (T1, T2, T3, T4, T5, T6, T7, T8, T9) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9>> value)
		{
			return CreateLong<T1, T2, T3, T4, T5, T6, T7, (T8, T9)>(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, ValueTuple.Create(value.Rest.Item1, value.Rest.Item2));
		}

		public static (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10>> value)
		{
			return CreateLong<T1, T2, T3, T4, T5, T6, T7, (T8, T9, T10)>(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, ValueTuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3));
		}

		public static (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11>> value)
		{
			return CreateLong<T1, T2, T3, T4, T5, T6, T7, (T8, T9, T10, T11)>(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, ValueTuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4));
		}

		public static (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12>> value)
		{
			return CreateLong<T1, T2, T3, T4, T5, T6, T7, (T8, T9, T10, T11, T12)>(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, ValueTuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5));
		}

		public static (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13>> value)
		{
			return CreateLong<T1, T2, T3, T4, T5, T6, T7, (T8, T9, T10, T11, T12, T13)>(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, ValueTuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6));
		}

		public static (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14>> value)
		{
			return CreateLong<T1, T2, T3, T4, T5, T6, T7, (T8, T9, T10, T11, T12, T13, T14)>(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, ValueTuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7));
		}

		public static (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15>>> value)
		{
			return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLong(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, ValueTuple.Create(value.Rest.Rest.Item1)));
		}

		public static (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16>>> value)
		{
			return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLong<T8, T9, T10, T11, T12, T13, T14, (T15, T16)>(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2)));
		}

		public static (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17>>> value)
		{
			return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLong<T8, T9, T10, T11, T12, T13, T14, (T15, T16, T17)>(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3)));
		}

		public static (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18>>> value)
		{
			return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLong<T8, T9, T10, T11, T12, T13, T14, (T15, T16, T17, T18)>(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4)));
		}

		public static (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19>>> value)
		{
			return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLong<T8, T9, T10, T11, T12, T13, T14, (T15, T16, T17, T18, T19)>(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5)));
		}

		public static (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19, T20>>> value)
		{
			return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLong<T8, T9, T10, T11, T12, T13, T14, (T15, T16, T17, T18, T19, T20)>(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5, value.Rest.Rest.Item6)));
		}

		public static (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19, T20, T21>>> value)
		{
			return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLong<T8, T9, T10, T11, T12, T13, T14, (T15, T16, T17, T18, T19, T20, T21)>(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5, value.Rest.Rest.Item6, value.Rest.Rest.Item7)));
		}

		public static Tuple<T1> ToTuple<T1>(this ValueTuple<T1> value)
		{
			return Tuple.Create(value.Item1);
		}

		public static Tuple<T1, T2> ToTuple<T1, T2>(this (T1, T2) value)
		{
			return Tuple.Create(value.Item1, value.Item2);
		}

		public static Tuple<T1, T2, T3> ToTuple<T1, T2, T3>(this (T1, T2, T3) value)
		{
			return Tuple.Create(value.Item1, value.Item2, value.Item3);
		}

		public static Tuple<T1, T2, T3, T4> ToTuple<T1, T2, T3, T4>(this (T1, T2, T3, T4) value)
		{
			return Tuple.Create(value.Item1, value.Item2, value.Item3, value.Item4);
		}

		public static Tuple<T1, T2, T3, T4, T5> ToTuple<T1, T2, T3, T4, T5>(this (T1, T2, T3, T4, T5) value)
		{
			return Tuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5);
		}

		public static Tuple<T1, T2, T3, T4, T5, T6> ToTuple<T1, T2, T3, T4, T5, T6>(this (T1, T2, T3, T4, T5, T6) value)
		{
			return Tuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6);
		}

		public static Tuple<T1, T2, T3, T4, T5, T6, T7> ToTuple<T1, T2, T3, T4, T5, T6, T7>(this (T1, T2, T3, T4, T5, T6, T7) value)
		{
			return Tuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7);
		}

		public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8>(this (T1, T2, T3, T4, T5, T6, T7, T8) value)
		{
			return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, Tuple.Create(value.Rest.Item1));
		}

		public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9) value)
		{
			return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, Tuple.Create(value.Rest.Item1, value.Rest.Item2));
		}

		public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) value)
		{
			return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, Tuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3));
		}

		public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) value)
		{
			return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, Tuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4));
		}

		public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) value)
		{
			return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, Tuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5));
		}

		public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) value)
		{
			return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, Tuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6));
		}

		public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) value)
		{
			return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, Tuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7));
		}

		public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15>>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) value)
		{
			return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, Tuple.Create(value.Rest.Rest.Item1)));
		}

		public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16>>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) value)
		{
			return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2)));
		}

		public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17>>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) value)
		{
			return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3)));
		}

		public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18>>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) value)
		{
			return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4)));
		}

		public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19>>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) value)
		{
			return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5)));
		}

		public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19, T20>>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) value)
		{
			return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5, value.Rest.Rest.Item6)));
		}

		public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19, T20, T21>>> ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(this (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) value)
		{
			return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7, CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7, Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5, value.Rest.Rest.Item6, value.Rest.Rest.Item7)));
		}

		private static ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> CreateLong<T1, T2, T3, T4, T5, T6, T7, TRest>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) where TRest : struct
		{
			return new ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>(item1, item2, item3, item4, item5, item6, item7, rest);
		}

		private static Tuple<T1, T2, T3, T4, T5, T6, T7, TRest> CreateLongRef<T1, T2, T3, T4, T5, T6, T7, TRest>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest)
		{
			return new Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>(item1, item2, item3, item4, item5, item6, item7, rest);
		}
	}
	internal interface ITupleInternal
	{
		int Size { get; }

		int GetHashCode(IEqualityComparer comparer);

		string ToStringEnd();
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	public struct ValueTuple : IEquatable<ValueTuple>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple>, System.ITupleInternal
	{
		int System.ITupleInternal.Size => 0;

		public override bool Equals(object obj)
		{
			return obj is ValueTuple;
		}

		public bool Equals(ValueTuple other)
		{
			return true;
		}

		bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
		{
			return other is ValueTuple;
		}

		int IComparable.CompareTo(object other)
		{
			if (other == null)
			{
				return 1;
			}
			if (!(other is ValueTuple))
			{
				throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other");
			}
			return 0;
		}

		public int CompareTo(ValueTuple other)
		{
			return 0;
		}

		int IStructuralComparable.CompareTo(object other, IComparer comparer)
		{
			if (other == null)
			{
				return 1;
			}
			if (!(other is ValueTuple))
			{
				throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other");
			}
			return 0;
		}

		public override int GetHashCode()
		{
			return 0;
		}

		int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
		{
			return 0;
		}

		int System.ITupleInternal.GetHashCode(IEqualityComparer comparer)
		{
			return 0;
		}

		public override string ToString()
		{
			return "()";
		}

		string System.ITupleInternal.ToStringEnd()
		{
			return ")";
		}

		public static ValueTuple Create()
		{
			return default(ValueTuple);
		}

		public static ValueTuple<T1> Create<T1>(T1 item1)
		{
			return new ValueTuple<T1>(item1);
		}

		public static (T1, T2) Create<T1, T2>(T1 item1, T2 item2)
		{
			return (item1, item2);
		}

		public static (T1, T2, T3) Create<T1, T2, T3>(T1 item1, T2 item2, T3 item3)
		{
			return (item1, item2, item3);
		}

		public static (T1, T2, T3, T4) Create<T1, T2, T3, T4>(T1 item1, T2 item2, T3 item3, T4 item4)
		{
			return (item1, item2, item3, item4);
		}

		public static (T1, T2, T3, T4, T5) Create<T1, T2, T3, T4, T5>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5)
		{
			return (item1, item2, item3, item4, item5);
		}

		public static (T1, T2, T3, T4, T5, T6) Create<T1, T2, T3, T4, T5, T6>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6)
		{
			return (item1, item2, item3, item4, item5, item6);
		}

		public static (T1, T2, T3, T4, T5, T6, T7) Create<T1, T2, T3, T4, T5, T6, T7>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7)
		{
			return (item1, item2, item3, item4, item5, item6, item7);
		}

		public static (T1, T2, T3, T4, T5, T6, T7, T8) Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8)
		{
			return new ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8>>(item1, item2, item3, item4, item5, item6, item7, Create(item8));
		}

		internal static int CombineHashCodes(int h1, int h2)
		{
			return HashHelpers.Combine(HashHelpers.Combine(HashHelpers.RandomSeed, h1), h2);
		}

		internal static int CombineHashCodes(int h1, int h2, int h3)
		{
			return HashHelpers.Combine(CombineHashCodes(h1, h2), h3);
		}

		internal static int CombineHashCodes(int h1, int h2, int h3, int h4)
		{
			return HashHelpers.Combine(CombineHashCodes(h1, h2, h3), h4);
		}

		internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5)
		{
			return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4), h5);
		}

		internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6)
		{
			return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5), h6);
		}

		internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7)
		{
			return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5, h6), h7);
		}

		internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8)
		{
			return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5, h6, h7), h8);
		}
	}
	public struct ValueTuple<T1> : IEquatable<ValueTuple<T1>>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple<T1>>, System.ITupleInternal
	{
		private static readonly EqualityComparer<T1> s_t1Comparer = EqualityComparer<T1>.Default;

		public T1 Item1;

		int System.ITupleInternal.Size => 1;

		public ValueTuple(T1 item1)
		{
			Item1 = item1;
		}

		public override bool Equals(object obj)
		{
			if (obj is ValueTuple<T1>)
			{
				return Equals((ValueTuple<T1>)obj);
			}
			return false;
		}

		public bool Equals(ValueTuple<T1> other)
		{
			return s_t1Comparer.Equals(Item1, other.Item1);
		}

		bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
		{
			if (other == null || !(other is ValueTuple<T1> valueTuple))
			{
				return false;
			}
			return comparer.Equals(Item1, valueTuple.Item1);
		}

		int IComparable.CompareTo(object other)
		{
			if (other == null)
			{
				return 1;
			}
			if (!(other is ValueTuple<T1> valueTuple))
			{
				throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other");
			}
			return Comparer<T1>.Default.Compare(Item1, valueTuple.Item1);
		}

		public int CompareTo(ValueTuple<T1> other)
		{
			return Comparer<T1>.Default.Compare(Item1, other.Item1);
		}

		int IStructuralComparable.CompareTo(object other, IComparer comparer)
		{
			if (other == null)
			{
				return 1;
			}
			if (!(other is ValueTuple<T1> valueTuple))
			{
				throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other");
			}
			return comparer.Compare(Item1, valueTuple.Item1);
		}

		public override int GetHashCode()
		{
			return s_t1Comparer.GetHashCode(Item1);
		}

		int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
		{
			return comparer.GetHashCode(Item1);
		}

		int System.ITupleInternal.GetHashCode(IEqualityComparer comparer)
		{
			return comparer.GetHashCode(Item1);
		}

		public override string ToString()
		{
			return "(" + Item1?.ToString() + ")";
		}

		string System.ITupleInternal.ToStringEnd()
		{
			return Item1?.ToString() + ")";
		}
	}
	[StructLayout(LayoutKind.Auto)]
	public struct ValueTuple<T1, T2> : IEquatable<(T1, T2)>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<(T1, T2)>, System.ITupleInternal
	{
		private static readonly EqualityComparer<T1> s_t1Comparer = EqualityComparer<T1>.Default;

		private static readonly EqualityComparer<T2> s_t2Comparer = EqualityComparer<T2>.Default;

		public T1 Item1;

		public T2 Item2;

		int System.ITupleInternal.Size => 2;

		public ValueTuple(T1 item1, T2 item2)
		{
			Item1 = item1;
			Item2 = item2;
		}

		public override bool Equals(object obj)
		{
			if (obj is ValueTuple<T1, T2>)
			{
				return Equals(((T1, T2))obj);
			}
			return false;
		}

		public bool Equals((T1, T2) other)
		{
			if (s_t1Comparer.Equals(Item1, other.Item1))
			{
				return s_t2Comparer.Equals(Item2, other.Item2);
			}
			return false;
		}

		bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
		{
			if (other == null || !(other is (T1, T2) tuple))
			{
				return false;
			}
			if (comparer.Equals(Item1, tuple.Item1))
			{
				return comparer.Equals(Item2, tuple.Item2);
			}
			return false;
		}

		int IComparable.CompareTo(object other)
		{
			if (other == null)
			{
				return 1;
			}
			if (!(other is ValueTuple<T1, T2>))
			{
				throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other");
			}
			return CompareTo(((T1, T2))other);
		}

		public int CompareTo((T1, T2) other)
		{
			int num = Comparer<T1>.Default.Compare(Item1, other.Item1);
			if (num != 0)
			{
				return num;
			}
			return Comparer<T2>.Default.Compare(Item2, other.Item2);
		}

		int IStructuralComparable.CompareTo(object other, IComparer comparer)
		{
			if (other == null)
			{
				return 1;
			}
			if (!(other is (T1, T2) tuple))
			{
				throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other");
			}
			int num = comparer.Compare(Item1, tuple.Item1);
			if (num != 0)
			{
				return num;
			}
			return comparer.Compare(Item2, tuple.Item2);
		}

		public override int GetHashCode()
		{
			return ValueTuple.CombineHashCodes(s_t1Comparer.GetHashCode(Item1), s_t2Comparer.GetHashCode(Item2));
		}

		int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
		{
			return GetHashCodeCore(comparer);
		}

		private int GetHashCodeCore(IEqualityComparer comparer)
		{
			return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2));
		}

		int System.ITupleInternal.GetHashCode(IEqualityComparer comparer)
		{
			return GetHashCodeCore(comparer);
		}

		public override string ToString()
		{
			return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ")";
		}

		string System.ITupleInternal.ToStringEnd()
		{
			return Item1?.ToString() + ", " + Item2?.ToString() + ")";
		}
	}
	[StructLayout(LayoutKind.Auto)]
	public struct ValueTuple<T1, T2, T3> : IEquatable<(T1, T2, T3)>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<(T1, T2, T3)>, System.ITupleInternal
	{
		private static readonly EqualityComparer<T1> s_t1Comparer = EqualityComparer<T1>.Default;

		private static readonly EqualityComparer<T2> s_t2Comparer = EqualityComparer<T2>.Default;

		private static readonly EqualityComparer<T3> s_t3Comparer = EqualityComparer<T3>.Default;

		public T1 Item1;

		public T2 Item2;

		public T3 Item3;

		int System.ITupleInternal.Size => 3;

		public ValueTuple(T1 item1, T2 item2, T3 item3)
		{
			Item1 = item1;
			Item2 = item2;
			Item3 = item3;
		}

		public override bool Equals(object obj)
		{
			if (obj is ValueTuple<T1, T2, T3>)
			{
				return Equals(((T1, T2, T3))obj);
			}
			return false;
		}

		public bool Equals((T1, T2, T3) other)
		{
			if (s_t1Comparer.Equals(Item1, other.Item1) && s_t2Comparer.Equals(Item2, other.Item2))
			{
				return s_t3Comparer.Equals(Item3, other.Item3);
			}
			return false;
		}

		bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
		{
			if (other == null || !(other is (T1, T2, T3) tuple))
			{
				return false;
			}
			if (comparer.Equals(Item1, tuple.Item1) && comparer.Equals(Item2, tuple.Item2))
			{
				return comparer.Equals(Item3, tuple.Item3);
			}
			return false;
		}

		int IComparable.CompareTo(object other)
		{
			if (other == null)
			{
				return 1;
			}
			if (!(other is ValueTuple<T1, T2, T3>))
			{
				throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other");
			}
			return CompareTo(((T1, T2, T3))other);
		}

		public int CompareTo((T1, T2, T3) other)
		{
			int num = Comparer<T1>.Default.Compare(Item1, other.Item1);
			if (num != 0)
			{
				return num;
			}
			num = Comparer<T2>.Default.Compare(Item2, other.Item2);
			if (num != 0)
			{
				return num;
			}
			return Comparer<T3>.Default.Compare(Item3, other.Item3);
		}

		int IStructuralComparable.CompareTo(object other, IComparer comparer)
		{
			if (other == null)
			{
				return 1;
			}
			if (!(other is (T1, T2, T3) tuple))
			{
				throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other");
			}
			int num = comparer.Compare(Item1, tuple.Item1);
			if (num != 0)
			{
				return num;
			}
			num = comparer.Compare(Item2, tuple.Item2);
			if (num != 0)
			{
				return num;
			}
			return comparer.Compare(Item3, tuple.Item3);
		}

		public override int GetHashCode()
		{
			return ValueTuple.CombineHashCodes(s_t1Comparer.GetHashCode(Item1), s_t2Comparer.GetHashCode(Item2), s_t3Comparer.GetHashCode(Item3));
		}

		int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
		{
			return GetHashCodeCore(comparer);
		}

		private int GetHashCodeCore(IEqualityComparer comparer)
		{
			return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3));
		}

		int System.ITupleInternal.GetHashCode(IEqualityComparer comparer)
		{
			return GetHashCodeCore(comparer);
		}

		public override string ToString()
		{
			return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ")";
		}

		string System.ITupleInternal.ToStringEnd()
		{
			return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ")";
		}
	}
	[StructLayout(LayoutKind.Auto)]
	public struct ValueTuple<T1, T2, T3, T4> : IEquatable<(T1, T2, T3, T4)>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<(T1, T2, T3, T4)>, System.ITupleInternal
	{
		private static readonly EqualityComparer<T1> s_t1Comparer = EqualityComparer<T1>.Default;

		private static readonly EqualityComparer<T2> s_t2Comparer = EqualityComparer<T2>.Default;

		private static readonly EqualityComparer<T3> s_t3Comparer = EqualityComparer<T3>.Default;

		private static readonly EqualityComparer<T4> s_t4Comparer = EqualityComparer<T4>.Default;

		public T1 Item1;

		public T2 Item2;

		public T3 Item3;

		public T4 Item4;

		int System.ITupleInternal.Size => 4;

		public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4)
		{
			Item1 = item1;
			Item2 = item2;
			Item3 = item3;
			Item4 = item4;
		}

		public override bool Equals(object obj)
		{
			if (obj is ValueTuple<T1, T2, T3, T4>)
			{
				return Equals(((T1, T2, T3, T4))obj);
			}
			return false;
		}

		public bool Equals((T1, T2, T3, T4) other)
		{
			if (s_t1Comparer.Equals(Item1, other.Item1) && s_t2Comparer.Equals(Item2, other.Item2) && s_t3Comparer.Equals(Item3, other.Item3))
			{
				return s_t4Comparer.Equals(Item4, other.Item4);
			}
			return false;
		}

		bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
		{
			if (other == null || !(other is (T1, T2, T3, T4) tuple))
			{
				return false;
			}
			if (comparer.Equals(Item1, tuple.Item1) && comparer.Equals(Item2, tuple.Item2) && comparer.Equals(Item3, tuple.Item3))
			{
				return comparer.Equals(Item4, tuple.Item4);
			}
			return false;
		}

		int IComparable.CompareTo(object other)
		{
			if (other == null)
			{
				return 1;
			}
			if (!(other is ValueTuple<T1, T2, T3, T4>))
			{
				throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other");
			}
			return CompareTo(((T1, T2, T3, T4))other);
		}

		public int CompareTo((T1, T2, T3, T4) other)
		{
			int num = Comparer<T1>.Default.Compare(Item1, other.Item1);
			if (num != 0)
			{
				return num;
			}
			num = Comparer<T2>.Default.Compare(Item2, other.Item2);
			if (num != 0)
			{
				return num;
			}
			num = Comparer<T3>.Default.Compare(Item3, other.Item3);
			if (num != 0)
			{
				return num;
			}
			return Comparer<T4>.Default.Compare(Item4, other.Item4);
		}

		int IStructuralComparable.CompareTo(object other, IComparer comparer)
		{
			if (other == null)
			{
				return 1;
			}
			if (!(other is (T1, T2, T3, T4) tuple))
			{
				throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other");
			}
			int num = comparer.Compare(Item1, tuple.Item1);
			if (num != 0)
			{
				return num;
			}
			num = comparer.Compare(Item2, tuple.Item2);
			if (num != 0)
			{
				return num;
			}
			num = comparer.Compare(Item3, tuple.Item3);
			if (num != 0)
			{
				return num;
			}
			return comparer.Compare(Item4, tuple.Item4);
		}

		public override int GetHashCode()
		{
			return ValueTuple.CombineHashCodes(s_t1Comparer.GetHashCode(Item1), s_t2Comparer.GetHashCode(Item2), s_t3Comparer.GetHashCode(Item3), s_t4Comparer.GetHashCode(Item4));
		}

		int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
		{
			return GetHashCodeCore(comparer);
		}

		private int GetHashCodeCore(IEqualityComparer comparer)
		{
			return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4));
		}

		int System.ITupleInternal.GetHashCode(IEqualityComparer comparer)
		{
			return GetHashCodeCore(comparer);
		}

		public override string ToString()
		{
			return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ")";
		}

		string System.ITupleInternal.ToStringEnd()
		{
			return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ")";
		}
	}
	[StructLayout(LayoutKind.Auto)]
	public struct ValueTuple<T1, T2, T3, T4, T5> : IEquatable<(T1, T2, T3, T4, T5)>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<(T1, T2, T3, T4, T5)>, System.ITupleInternal
	{
		private static readonly EqualityComparer<T1> s_t1Comparer = EqualityComparer<T1>.Default;

		private static readonly EqualityComparer<T2> s_t2Comparer = EqualityComparer<T2>.Default;

		private static readonly EqualityComparer<T3> s_t3Comparer = EqualityComparer<T3>.Default;

		private static readonly EqualityComparer<T4> s_t4Comparer = EqualityComparer<T4>.Default;

		private static readonly EqualityComparer<T5> s_t5Comparer = EqualityComparer<T5>.Default;

		public T1 Item1;

		public T2 Item2;

		public T3 Item3;

		public T4 Item4;

		public T5 Item5;

		int System.ITupleInternal.Size => 5;

		public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5)
		{
			Item1 = item1;
			Item2 = item2;
			Item3 = item3;
			Item4 = item4;
			Item5 = item5;
		}

		public override bool Equals(object obj)
		{
			if (obj is ValueTuple<T1, T2, T3, T4, T5>)
			{
				return Equals(((T1, T2, T3, T4, T5))obj);
			}
			return false;
		}

		public bool Equals((T1, T2, T3, T4, T5) other)
		{
			if (s_t1Comparer.Equals(Item1, other.Item1) && s_t2Comparer.Equals(Item2, other.Item2) && s_t3Comparer.Equals(Item3, other.Item3) && s_t4Comparer.Equals(Item4, other.Item4))
			{
				return s_t5Comparer.Equals(Item5, other.Item5);
			}
			return false;
		}

		bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
		{
			if (other == null || !(other is (T1, T2, T3, T4, T5) tuple))
			{
				return false;
			}
			if (comparer.Equals(Item1, tuple.Item1) && comparer.Equals(Item2, tuple.Item2) && comparer.Equals(Item3, tuple.Item3) && comparer.Equals(Item4, tuple.Item4))
			{
				return comparer.Equals(Item5, tuple.Item5);
			}
			return false;
		}

		int IComparable.CompareTo(object other)
		{
			if (other == null)
			{
				return 1;
			}
			if (!(other is ValueTuple<T1, T2, T3, T4, T5>))
			{
				throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other");
			}
			return CompareTo(((T1, T2, T3, T4, T5))other);
		}

		public int CompareTo((T1, T2, T3, T4, T5) other)
		{
			int num = Comparer<T1>.Default.Compare(Item1, other.Item1);
			if (num != 0)
			{
				return num;
			}
			num = Comparer<T2>.Default.Compare(Item2, other.Item2);
			if (num != 0)
			{
				return num;
			}
			num = Comparer<T3>.Default.Compare(Item3, other.Item3);
			if (num != 0)
			{
				return num;
			}
			num = Comparer<T4>.Default.Compare(Item4, other.Item4);
			if (num != 0)
			{
				return num;
			}
			return Comparer<T5>.Default.Compare(Item5, other.Item5);
		}

		int IStructuralComparable.CompareTo(object other, IComparer comparer)
		{
			if (other == null)
			{
				return 1;
			}
			if (!(other is (T1, T2, T3, T4, T5) tuple))
			{
				throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other");
			}
			int num = comparer.Compare(Item1, tuple.Item1);
			if (num != 0)
			{
				return num;
			}
			num = comparer.Compare(Item2, tuple.Item2);
			if (num != 0)
			{
				return num;
			}
			num = comparer.Compare(Item3, tuple.Item3);
			if (num != 0)
			{
				return num;
			}
			num = comparer.Compare(Item4, tuple.Item4);
			if (num != 0)
			{
				return num;
			}
			return comparer.Compare(Item5, tuple.Item5);
		}

		public override int GetHashCode()
		{
			return ValueTuple.CombineHashCodes(s_t1Comparer.GetHashCode(Item1), s_t2Comparer.GetHashCode(Item2), s_t3Comparer.GetHashCode(Item3), s_t4Comparer.GetHashCode(Item4), s_t5Comparer.GetHashCode(Item5));
		}

		int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
		{
			return GetHashCodeCore(comparer);
		}

		private int GetHashCodeCore(IEqualityComparer comparer)
		{
			return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5));
		}

		int System.ITupleInternal.GetHashCode(IEqualityComparer comparer)
		{
			return GetHashCodeCore(comparer);
		}

		public override string ToString()
		{
			return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ")";
		}

		string System.ITupleInternal.ToStringEnd()
		{
			return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ")";
		}
	}
	[StructLayout(LayoutKind.Auto)]
	public struct ValueTuple<T1, T2, T3, T4, T5, T6> : IEquatable<(T1, T2, T3, T4, T5, T6)>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<(T1, T2, T3, T4, T5, T6)>, System.ITupleInternal
	{
		private static readonly EqualityComparer<T1> s_t1Comparer = EqualityComparer<T1>.Default;

		private static readonly EqualityComparer<T2> s_t2Comparer = EqualityComparer<T2>.Default;

		private static readonly EqualityComparer<T3> s_t3Comparer = EqualityComparer<T3>.Default;

		private static readonly EqualityComparer<T4> s_t4Comparer = EqualityComparer<T4>.Default;

		private static readonly EqualityComparer<T5> s_t5Comparer = EqualityComparer<T5>.Default;

		private static readonly EqualityComparer<T6> s_t6Comparer = EqualityComparer<T6>.Default;

		public T1 Item1;

		public T2 Item2;

		public T3 Item3;

		public T4 Item4;

		public T5 Item5;

		public T6 Item6;

		int System.ITupleInternal.Size => 6;

		public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6)
		{
			Item1 = item1;
			Item2 = item2;
			Item3 = item3;
			Item4 = item4;
			Item5 = item5;
			Item6 = item6;
		}

		public override bool Equals(object obj)
		{
			if (obj is ValueTuple<T1, T2, T3, T4, T5, T6>)
			{
				return Equals(((T1, T2, T3, T4, T5, T6))obj);
			}
			return false;
		}

		public bool Equals((T1, T2, T3, T4, T5, T6) other)
		{
			if (s_t1Comparer.Equals(Item1, other.Item1) && s_t2Comparer.Equals(Item2, other.Item2) && s_t3Comparer.Equals(Item3, other.Item3) && s_t4Comparer.Equals(Item4, other.Item4) && s_t5Comparer.Equals(Item5, other.Item5))
			{
				return s_t6Comparer.Equals(Item6, other.Item6);
			}
			return false;
		}

		bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
		{
			if (other == null || !(other is (T1, T2, T3, T4, T5, T6) tuple))
			{
				return false;
			}
			if (comparer.Equals(Item1, tuple.Item1) && comparer.Equals(Item2, tuple.Item2) && comparer.Equals(Item3, tuple.Item3) && comparer.Equals(Item4, tuple.Item4) && comparer.Equals(Item5, tuple.Item5))
			{
				return comparer.Equals(Item6, tuple.Item6);
			}
			return false;
		}

		int IComparable.CompareTo(object other)
		{
			if (other == null)
			{
				return 1;
			}
			if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6>))
			{
				throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other");
			}
			return CompareTo(((T1, T2, T3, T4, T5, T6))other);
		}

		public int CompareTo((T1, T2, T3, T4, T5, T6) other)
		{
			int num = Comparer<T1>.Default.Compare(Item1, other.Item1);
			if (num != 0)
			{
				return num;
			}
			num = Comparer<T2>.Default.Compare(Item2, other.Item2);
			if (num != 0)
			{
				return num;
			}
			num = Comparer<T3>.Default.Compare(Item3, other.Item3);
			if (num != 0)
			{
				return num;
			}
			num = Comparer<T4>.Default.Compare(Item4, other.Item4);
			if (num != 0)
			{
				return num;
			}
			num = Comparer<T5>.Default.Compare(Item5, other.Item5);
			if (num != 0)
			{
				return num;
			}
			return Comparer<T6>.Default.Compare(Item6, other.Item6);
		}

		int IStructuralComparable.CompareTo(object other, IComparer comparer)
		{
			if (other == null)
			{
				return 1;
			}
			if (!(other is (T1, T2, T3, T4, T5, T6) tuple))
			{
				throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other");
			}
			int num = comparer.Compare(Item1, tuple.Item1);
			if (num != 0)
			{
				return num;
			}
			num = comparer.Compare(Item2, tuple.Item2);
			if (num != 0)
			{
				return num;
			}
			num = comparer.Compare(Item3, tuple.Item3);
			if (num != 0)
			{
				return num;
			}
			num = comparer.Compare(Item4, tuple.Item4);
			if (num != 0)
			{
				return num;
			}
			num = comparer.Compare(Item5, tuple.Item5);
			if (num != 0)
			{
				return num;
			}
			return comparer.Compare(Item6, tuple.Item6);
		}

		public override int GetHashCode()
		{
			return ValueTuple.CombineHashCodes(s_t1Comparer.GetHashCode(Item1), s_t2Comparer.GetHashCode(Item2), s_t3Comparer.GetHashCode(Item3), s_t4Comparer.GetHashCode(Item4), s_t5Comparer.GetHashCode(Item5), s_t6Comparer.GetHashCode(Item6));
		}

		int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
		{
			return GetHashCodeCore(comparer);
		}

		private int GetHashCodeCore(IEqualityComparer comparer)
		{
			return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6));
		}

		int System.ITupleInternal.GetHashCode(IEqualityComparer comparer)
		{
			return GetHashCodeCore(comparer);
		}

		public override string ToString()
		{
			return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ")";
		}

		string System.ITupleInternal.ToStringEnd()
		{
			return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ")";
		}
	}
	[StructLayout(LayoutKind.Auto)]
	public struct ValueTuple<T1, T2, T3, T4, T5, T6, T7> : IEquatable<(T1, T2, T3, T4, T5, T6, T7)>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<(T1, T2, T3, T4, T5, T6, T7)>, System.ITupleInternal
	{
		private static readonly EqualityComparer<T1> s_t1Comparer = EqualityComparer<T1>.Default;

		private static readonly EqualityComparer<T2> s_t2Comparer = EqualityComparer<T2>.Default;

		private static readonly EqualityComparer<T3> s_t3Comparer = EqualityComparer<T3>.Default;

		private static readonly EqualityComparer<T4> s_t4Comparer = EqualityComparer<T4>.Default;

		private static readonly EqualityComparer<T5> s_t5Comparer = EqualityComparer<T5>.Default;

		private static readonly EqualityComparer<T6> s_t6Comparer = EqualityComparer<T6>.Default;

		private static readonly EqualityComparer<T7> s_t7Comparer = EqualityComparer<T7>.Default;

		public T1 Item1;

		public T2 Item2;

		public T3 Item3;

		public T4 Item4;

		public T5 Item5;

		public T6 Item6;

		public T7 Item7;

		int System.ITupleInternal.Size => 7;

		public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7)
		{
			Item1 = item1;
			Item2 = item2;
			Item3 = item3;
			Item4 = item4;
			Item5 = item5;
			Item6 = item6;
			Item7 = item7;
		}

		public override bool Equals(object obj)
		{
			if (obj is ValueTuple<T1, T2, T3, T4, T5, T6, T7>)
			{
				return Equals(((T1, T2, T3, T4, T5, T6, T7))obj);
			}
			return false;
		}

		public bool Equals((T1, T2, T3, T4, T5, T6, T7) other)
		{
			if (s_t1Comparer.Equals(Item1, other.Item1) && s_t2Comparer.Equals(Item2, other.Item2) && s_t3Comparer.Equals(Item3, other.Item3) && s_t4Comparer.Equals(Item4, other.Item4) && s_t5Comparer.Equals(Item5, other.Item5) && s_t6Comparer.Equals(Item6, other.Item6))
			{
				return s_t7Comparer.Equals(Item7, other.Item7);
			}
			return false;
		}

		bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
		{
			if (other == null || !(other is (T1, T2, T3, T4, T5, T6, T7) tuple))
			{
				return false;
			}
			if (comparer.Equals(Item1, tuple.Item1) && comparer.Equals(Item2, tuple.Item2) && comparer.Equals(Item3, tuple.Item3) && comparer.Equals(Item4, tuple.Item4) && comparer.Equals(Item5, tuple.Item5) && comparer.Equals(Item6, tuple.Item6))
			{
				return comparer.Equals(Item7, tuple.Item7);
			}
			return false;
		}

		int IComparable.CompareTo(object other)
		{
			if (other == null)
			{
				return 1;
			}
			if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6, T7>))
			{
				throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other");
			}
			return CompareTo(((T1, T2, T3, T4, T5, T6, T7))other);
		}

		public int CompareTo((T1, T2, T3, T4, T5, T6, T7) other)
		{
			int num = Comparer<T1>.Default.Compare(Item1, other.Item1);
			if (num != 0)
			{
				return num;
			}
			num = Comparer<T2>.Default.Compare(Item2, other.Item2);
			if (num != 0)
			{
				return num;
			}
			num = Comparer<T3>.Default.Compare(Item3, other.Item3);
			if (num != 0)
			{
				return num;
			}
			num = Comparer<T4>.Default.Compare(Item4, other.Item4);
			if (num != 0)
			{
				return num;
			}
			num = Comparer<T5>.Default.Compare(Item5, other.Item5);
			if (num != 0)
			{
				return num;
			}
			num = Comparer<T6>.Default.Compare(Item6, other.Item6);
			if (num != 0)
			{
				return num;
			}
			return Comparer<T7>.Default.Compare(Item7, other.Item7);
		}

		int IStructuralComparable.CompareTo(object other, IComparer comparer)
		{
			if (other == null)
			{
				return 1;
			}
			if (!(other is (T1, T2, T3, T4, T5, T6, T7) tuple))
			{
				throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other");
			}
			int num = comparer.Compare(Item1, tuple.Item1);
			if (num != 0)
			{
				return num;
			}
			num = comparer.Compare(Item2, tuple.Item2);
			if (num != 0)
			{
				return num;
			}
			num = comparer.Compare(Item3, tuple.Item3);
			if (num != 0)
			{
				return num;
			}
			num = comparer.Compare(Item4, tuple.Item4);
			if (num != 0)
			{
				return num;
			}
			num = comparer.Compare(Item5, tuple.Item5);
			if (num != 0)
			{
				return num;
			}
			num = comparer.Compare(Item6, tuple.Item6);
			if (num != 0)
			{
				return num;
			}
			return comparer.Compare(Item7, tuple.Item7);
		}

		public override int GetHashCode()
		{
			return ValueTuple.CombineHashCodes(s_t1Comparer.GetHashCode(Item1), s_t2Comparer.GetHashCode(Item2), s_t3Comparer.GetHashCode(Item3), s_t4Comparer.GetHashCode(Item4), s_t5Comparer.GetHashCode(Item5), s_t6Comparer.GetHashCode(Item6), s_t7Comparer.GetHashCode(Item7));
		}

		int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
		{
			return GetHashCodeCore(comparer);
		}

		private int GetHashCodeCore(IEqualityComparer comparer)
		{
			return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7));
		}

		int System.ITupleInternal.GetHashCode(IEqualityComparer comparer)
		{
			return GetHashCodeCore(comparer);
		}

		public override string ToString()
		{
			return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ")";
		}

		string System.ITupleInternal.ToStringEnd()
		{
			return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ")";
		}
	}
	[StructLayout(LayoutKind.Auto)]
	public struct ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> : IEquatable<ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>>, System.ITupleInternal where TRest : struct
	{
		private static readonly EqualityComparer<T1> s_t1Comparer = EqualityComparer<T1>.Default;

		private static readonly EqualityComparer<T2> s_t2Comparer = EqualityComparer<T2>.Default;

		private static readonly EqualityComparer<T3> s_t3Comparer = EqualityComparer<T3>.Default;

		private static readonly EqualityComparer<T4> s_t4Comparer = EqualityComparer<T4>.Default;

		private static readonly EqualityComparer<T5> s_t5Comparer = EqualityComparer<T5>.Default;

		private static readonly EqualityComparer<T6> s_t6Comparer = EqualityComparer<T6>.Default;

		private static readonly EqualityComparer<T7> s_t7Comparer = EqualityComparer<T7>.Default;

		private static readonly EqualityComparer<TRest> s_tRestComparer = EqualityComparer<TRest>.Default;

		public T1 Item1;

		public T2 Item2;

		public T3 Item3;

		public T4 Item4;

		public T5 Item5;

		public T6 Item6;

		public T7 Item7;

		public TRest Rest;

		int System.ITupleInternal.Size
		{
			get
			{
				if ((object)Rest is System.ITupleInternal tupleInternal)
				{
					return 7 + tupleInternal.Size;
				}
				return 8;
			}
		}

		public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest)
		{
			if (!(rest is System.ITupleInternal))
			{
				throw new ArgumentException(System.SR.ArgumentException_ValueTupleLastArgumentNotAValueTuple);
			}
			Item1 = item1;
			Item2 = item2;
			Item3 = item3;
			Item4 = item4;
			Item5 = item5;
			Item6 = item6;
			Item7 = item7;
			Rest = rest;
		}

		public override bool Equals(object obj)
		{
			if (obj is ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>)
			{
				return Equals((ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>)obj);
			}
			return false;
		}

		public bool Equals(ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> other)
		{
			if (s_t1Comparer.Equals(Item1, other.Item1) && s_t2Comparer.Equals(Item2, other.Item2) && s_t3Comparer.Equals(Item3, other.Item3) && s_t4Comparer.Equals(Item4, other.Item4) && s_t5Comparer.Equals(Item5, other.Item5) && s_t6Comparer.Equals(Item6, other.Item6) && s_t7Comparer.Equals(Item7, other.Item7))
			{
				return s_tRestComparer.Equals(Rest, other.Rest);
			}
			return false;
		}

		bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
		{
			if (other == null || !(other is ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> valueTuple))
			{
				return false;
			}
			if (comparer.Equals(Item1, valueTuple.Item1) && comparer.Equals(Item2, valueTuple.Item2) && comparer.Equals(Item3, valueTuple.Item3) && comparer.Equals(Item4, valueTuple.Item4) && comparer.Equals(Item5, valueTuple.Item5) && comparer.Equals(Item6, valueTuple.Item6) && comparer.Equals(Item7, valueTuple.Item7))
			{
				return comparer.Equals(Rest, valueTuple.Rest);
			}
			return false;
		}

		int IComparable.CompareTo(object other)
		{
			if (other == null)
			{
				return 1;
			}
			if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>))
			{
				throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other");
			}
			return CompareTo((ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>)other);
		}

		public int CompareTo(ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> other)
		{
			int num = Comparer<T1>.Default.Compare(Item1, other.Item1);
			if (num != 0)
			{
				return num;
			}
			num = Comparer<T2>.Default.Compare(Item2, other.Item2);
			if (num != 0)
			{
				return num;
			}
			num = Comparer<T3>.Default.Compare(Item3, other.Item3);
			if (num != 0)
			{
				return num;
			}
			num = Comparer<T4>.Default.Compare(Item4, other.Item4);
			if (num != 0)
			{
				return num;
			}
			num = Comparer<T5>.Default.Compare(Item5, other.Item5);
			if (num != 0)
			{
				return num;
			}
			num = Comparer<T6>.Default.Compare(Item6, other.Item6);
			if (num != 0)
			{
				return num;
			}
			num = Comparer<T7>.Default.Compare(Item7, other.Item7);
			if (num != 0)
			{
				return num;
			}
			return Comparer<TRest>.Default.Compare(Rest, other.Rest);
		}

		int IStructuralComparable.CompareTo(object other, IComparer comparer)
		{
			if (other == null)
			{
				return 1;
			}
			if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> valueTuple))
			{
				throw new ArgumentException(System.SR.ArgumentException_ValueTupleIncorrectType, "other");
			}
			int num = comparer.Compare(Item1, valueTuple.Item1);
			if (num != 0)
			{
				return num;
			}
			num = comparer.Compare(Item2, valueTuple.Item2);
			if (num != 0)
			{
				return num;
			}
			num = comparer.Compare(Item3, valueTuple.Item3);
			if (num != 0)
			{
				return num;
			}
			num = comparer.Compare(Item4, valueTuple.Item4);
			if (num != 0)
			{
				return num;
			}
			num = comparer.Compare(Item5, valueTuple.Item5);
			if (num != 0)
			{
				return num;
			}
			num = comparer.Compare(Item6, valueTuple.Item6);
			if (num != 0)
			{
				return num;
			}
			num = comparer.Compare(Item7, valueTuple.Item7);
			if (num != 0)
			{
				return num;
			}
			return comparer.Compare(Rest, valueTuple.Rest);
		}

		public override int GetHashCode()
		{
			if (!((object)Rest is System.ITupleInternal tupleInternal))
			{
				return ValueTuple.CombineHashCodes(s_t1Comparer.GetHashCode(Item1), s_t2Comparer.GetHashCode(Item2), s_t3Comparer.GetHashCode(Item3), s_t4Comparer.GetHashCode(Item4), s_t5Comparer.GetHashCode(Item5), s_t6Comparer.GetHashCode(Item6), s_t7Comparer.GetHashCode(Item7));
			}
			int size = tupleInternal.Size;
			if (size >= 8)
			{
				return tupleInternal.GetHashCode();
			}
			switch (8 - size)
			{
			case 1:
				return ValueTuple.CombineHashCodes(s_t7Comparer.GetHashCode(Item7), tupleInternal.GetHashCode());
			case 2:
				return ValueTuple.CombineHashCodes(s_t6Comparer.GetHashCode(Item6), s_t7Comparer.GetHashCode(Item7), tupleInternal.GetHashCode());
			case 3:
				return ValueTuple.CombineHashCodes(s_t5Comparer.GetHashCode(Item5), s_t6Comparer.GetHashCode(Item6), s_t7Comparer.GetHashCode(Item7), tupleInternal.GetHashCode());
			case 4:
				return ValueTuple.CombineHashCodes(s_t4Comparer.GetHashCode(Item4), s_t5Comparer.GetHashCode(Item5), s_t6Comparer.GetHashCode(Item6), s_t7Comparer.GetHashCode(Item7), tupleInternal.GetHashCode());
			case 5:
				return ValueTuple.CombineHashCodes(s_t3Comparer.GetHashCode(Item3), s_t4Comparer.GetHashCode(Item4), s_t5Comparer.GetHashCode(Item5), s_t6Comparer.GetHashCode(Item6), s_t7Comparer.GetHashCode(Item7), tupleInternal.GetHashCode());
			case 6:
				return ValueTuple.CombineHashCodes(s_t2Comparer.GetHashCode(Item2), s_t3Comparer.GetHashCode(Item3), s_t4Comparer.GetHashCode(Item4), s_t5Comparer.GetHashCode(Item5), s_t6Comparer.GetHashCode(Item6), s_t7Comparer.GetHashCode(Item7), tupleInternal.GetHashCode());
			case 7:
			case 8:
				return ValueTuple.CombineHashCodes(s_t1Comparer.GetHashCode(Item1), s_t2Comparer.GetHashCode(Item2), s_t3Comparer.GetHashCode(Item3), s_t4Comparer.GetHashCode(Item4), s_t5Comparer.GetHashCode(Item5), s_t6Comparer.GetHashCode(Item6), s_t7Comparer.GetHashCode(Item7), tupleInternal.GetHashCode());
			default:
				return -1;
			}
		}

		int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
		{
			return GetHashCodeCore(comparer);
		}

		private int GetHashCodeCore(IEqualityComparer comparer)
		{
			if (!((object)Rest is System.ITupleInternal tupleInternal))
			{
				return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7));
			}
			int size = tupleInternal.Size;
			if (size >= 8)
			{
				return tupleInternal.GetHashCode(comparer);
			}
			switch (8 - size)
			{
			case 1:
				return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item7), tupleInternal.GetHashCode(comparer));
			case 2:
				return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), tupleInternal.GetHashCode(comparer));
			case 3:
				return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), tupleInternal.GetHashCode(comparer));
			case 4:
				return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), tupleInternal.GetHashCode(comparer));
			case 5:
				return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), tupleInternal.GetHashCode(comparer));
			case 6:
				return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), tupleInternal.GetHashCode(comparer));
			case 7:
			case 8:
				return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), tupleInternal.GetHashCode(comparer));
			default:
				return -1;
			}
		}

		int System.ITupleInternal.GetHashCode(IEqualityComparer comparer)
		{
			return GetHashCodeCore(comparer);
		}

		public override string ToString()
		{
			string[] obj;
			T1 val;
			object obj2;
			if (!((object)Rest is System.ITupleInternal tupleInternal))
			{
				obj = new string[17]
				{
					"(", null, null, null, null, null, null, null, null, null,
					null, null, null, null, null, null, null
				};
				ref T1 reference = ref Item1;
				val = default(T1);
				if (val == null)
				{
					val = reference;
					reference = ref val;
					if (val == null)
					{
						obj2 = null;
						goto IL_005d;
					}
				}
				obj2 = reference.ToString();
				goto IL_005d;
			}
			string[] obj3 = new string[16]
			{
				"(", null, null, null, null, null, null, null, null, null,
				null, null, null, null, null, null
			};
			ref T1 reference2 = ref Item1;
			val = default(T1);
			object obj4;
			if (val == null)
			{
				val = reference2;
				reference2 = ref val;
				if (val == null)
				{
					obj4 = null;
					goto IL_0262;
				}
			}
			obj4 = reference2.ToString();
			goto IL_0262;
			IL_02e2:
			object obj5;
			obj3[5] = (string)obj5;
			obj3[6] = ", ";
			ref T4 reference3 = ref Item4;
			T4 val2 = default(T4);
			object obj6;
			if (val2 == null)
			{
				val2 = reference3;
				reference3 = ref val2;
				if (val2 == null)
				{
					obj6 = null;
					goto IL_0325;
				}
			}
			obj6 = reference3.ToString();
			goto IL_0325;
			IL_03f3:
			object obj7;
			obj3[13] = (string)obj7;
			obj3[14] = ", ";
			obj3[15] = tupleInternal.ToStringEnd();
			return string.Concat(obj3);
			IL_03ae:
			object obj8;
			obj3[11] = (string)obj8;
			obj3[12] = ", ";
			ref T7 reference4 = ref Item7;
			T7 val3 = default(T7);
			if (val3 == null)
			{
				val3 = reference4;
				reference4 = ref val3;
				if (val3 == null)
				{
					obj7 = null;
					goto IL_03f3;
				}
			}
			obj7 = reference4.ToString();
			goto IL_03f3;
			IL_0120:
			object obj9;
			obj[7] = (string)obj9;
			obj[8] = ", ";
			ref T5 reference5 = ref Item5;
			T5 val4 = default(T5);
			object obj10;
			if (val4 == null)
			{
				val4 = reference5;
				reference5 = ref val4;
				if (val4 == null)
				{
					obj10 = null;
					goto IL_0164;
				}
			}
			obj10 = reference5.ToString();
			goto IL_0164;
			IL_005d:
			obj[1] = (string)obj2;
			obj[2] = ", ";
			ref T2 reference6 = ref Item2;
			T2 val5 = default(T2);
			object obj11;
			if (val5 == null)
			{
				val5 = reference6;
				reference6 = ref val5;
				if (val5 == null)
				{
					obj11 = null;
					goto IL_009d;
				}
			}
			obj11 = reference6.ToString();
			goto IL_009d;
			IL_0164:
			obj[9] = (string)obj10;
			obj[10] = ", ";
			ref T6 reference7 = ref Item6;
			T6 val6 = default(T6);
			object obj12;
			if (val6 == null)
			{
				val6 = reference7;
				reference7 = ref val6;
				if (val6 == null)
				{
					obj12 = null;
					goto IL_01a9;
				}
			}
			obj12 = reference7.ToString();
			goto IL_01a9;
			IL_02a2:
			object obj13;
			obj3[3] = (string)obj13;
			obj3[4] = ", ";
			ref T3 reference8 = ref Item3;
			T3 val7 = default(T3);
			if (val7 == null)
			{
				val7 = reference8;
				reference8 = ref val7;
				if (val7 == null)
				{
					obj5 = null;
					goto IL_02e2;
				}
			}
			obj5 = reference8.ToString();
			goto IL_02e2;
			IL_01ee:
			object obj14;
			obj[13] = (string)obj14;
			obj[14] = ", ";
			obj[15] = Rest.ToString();
			obj[16] = ")";
			return string.Concat(obj);
			IL_009d:
			obj[3] = (string)obj11;
			obj[4] = ", ";
			ref T3 reference9 = ref Item3;
			val7 = default(T3);
			object obj15;
			if (val7 == null)
			{
				val7 = reference9;
				reference9 = ref val7;
				if (val7 == null)
				{
					obj15 = null;
					goto IL_00dd;
				}
			}
			obj15 = reference9.ToString();
			goto IL_00dd;
			IL_0325:
			obj3[7] = (string)obj6;
			obj3[8] = ", ";
			ref T5 reference10 = ref Item5;
			val4 = default(T5);
			object obj16;
			if (val4 == null)
			{
				val4 = reference10;
				reference10 = ref val4;
				if (val4 == null)
				{
					obj16 = null;
					goto IL_0369;
				}
			}
			obj16 = reference10.ToString();
			goto IL_0369;
			IL_01a9:
			obj[11] = (string)obj12;
			obj[12] = ", ";
			ref T7 reference11 = ref Item7;
			val3 = default(T7);
			if (val3 == null)
			{
				val3 = reference11;
				reference11 = ref val3;
				if (val3 == null)
				{
					obj14 = null;
					goto IL_01ee;
				}
			}
			obj14 = reference11.ToString();
			goto IL_01ee;
			IL_0262:
			obj3[1] = (string)obj4;
			obj3[2] = ", ";
			ref T2 reference12 = ref Item2;
			val5 = default(T2);
			if (val5 == null)
			{
				val5 = reference12;
				reference12 = ref val5;
				if (val5 == null)
				{
					obj13 = null;
					goto IL_02a2;
				}
			}
			obj13 = reference12.ToString();
			goto IL_02a2;
			IL_00dd:
			obj[5] = (string)obj15;
			obj[6] = ", ";
			ref T4 reference13 = ref Item4;
			val2 = default(T4);
			if (val2 == null)
			{
				val2 = reference13;
				reference13 = ref val2;
				if (val2 == null)
				{
					obj9 = null;
					goto IL_0120;
				}
			}
			obj9 = reference13.ToString();
			goto IL_0120;
			IL_0369:
			obj3[9] = (string)obj16;
			obj3[10] = ", ";
			ref T6 reference14 = ref Item6;
			val6 = default(T6);
			if (val6 == null)
			{
				val6 = reference14;
				reference14 = ref val6;
				if (val6 == null)
				{
					obj8 = null;
					goto IL_03ae;
				}
			}
			obj8 = reference14.ToString();
			goto IL_03ae;
		}

		string System.ITupleInternal.ToStringEnd()
		{
			string[] array;
			T1 val;
			object obj;
			if (!((object)Rest is System.ITupleInternal tupleInternal))
			{
				array = new string[16];
				ref T1 reference = ref Item1;
				val = default(T1);
				if (val == null)
				{
					val = reference;
					reference = ref val;
					if (val == null)
					{
						obj = null;
						goto IL_0055;
					}
				}
				obj = reference.ToString();
				goto IL_0055;
			}
			string[] array2 = new string[15];
			ref T1 reference2 = ref Item1;
			val = default(T1);
			object obj2;
			if (val == null)
			{
				val = reference2;
				reference2 = ref val;
				if (val == null)
				{
					obj2 = null;
					goto IL_0251;
				}
			}
			obj2 = reference2.ToString();
			goto IL_0251;
			IL_02d1:
			object obj3;
			array2[4] = (string)obj3;
			array2[5] = ", ";
			ref T4 reference3 = ref Item4;
			T4 val2 = default(T4);
			object obj4;
			if (val2 == null)
			{
				val2 = reference3;
				reference3 = ref val2;
				if (val2 == null)
				{
					obj4 = null;
					goto IL_0314;
				}
			}
			obj4 = reference3.ToString();
			goto IL_0314;
			IL_03e1:
			object obj5;
			array2[12] = (string)obj5;
			array2[13] = ", ";
			array2[14] = tupleInternal.ToStringEnd();
			return string.Concat(array2);
			IL_039c:
			object obj6;
			array2[10] = (string)obj6;
			array2[11] = ", ";
			ref T7 reference4 = ref Item7;
			T7 val3 = default(T7);
			if (val3 == null)
			{
				val3 = reference4;
				reference4 = ref val3;
				if (val3 == null)
				{
					obj5 = null;
					goto IL_03e1;
				}
			}
			obj5 = reference4.ToString();
			goto IL_03e1;
			IL_0118:
			object obj7;
			array[6] = (string)obj7;
			array[7] = ", ";
			ref T5 reference5 = ref Item5;
			T5 val4 = default(T5);
			object obj8;
			if (val4 == null)
			{
				val4 = reference5;
				reference5 = ref val4;
				if (val4 == null)
				{
					obj8 = null;
					goto IL_015b;
				}
			}
			obj8 = reference5.ToString();
			goto IL_015b;
			IL_0055:
			array[0] = (string)obj;
			array[1] = ", ";
			ref T2 reference6 = ref Item2;
			T2 val5 = default(T2);
			object obj9;
			if (val5 == null)
			{
				val5 = reference6;
				reference6 = ref val5;
				if (val5 == null)
				{
					obj9 = null;
					goto IL_0095;
				}
			}
			obj9 = reference6.ToString();
			goto IL_0095;
			IL_015b:
			array[8] = (string)obj8;
			array[9] = ", ";
			ref T6 reference7 = ref Item6;
			T6 val6 = default(T6);
			object obj10;
			if (val6 == null)
			{
				val6 = reference7;
				reference7 = ref val6;
				if (val6 == null)
				{
					obj10 = null;
					goto IL_01a0;
				}
			}
			obj10 = reference7.ToString();
			goto IL_01a0;
			IL_0291:
			object obj11;
			array2[2] = (string)obj11;
			array2[3] = ", ";
			ref T3 reference8 = ref Item3;
			T3 val7 = default(T3);
			if (val7 == null)
			{
				val7 = reference8;
				reference8 = ref val7;
				if (val7 == null)
				{
					obj3 = null;
					goto IL_02d1;
				}
			}
			obj3 = reference8.ToString();
			goto IL_02d1;
			IL_01e5:
			object obj12;
			array[12] = (string)obj12;
			array[13] = ", ";
			array[14] = Rest.ToString();
			array[15] = ")";
			return string.Concat(array);
			IL_0095:
			array[2] = (string)obj9;
			array[3] = ", ";
			ref T3 reference9 = ref Item3;
			val7 = default(T3);
			object obj13;
			if (val7 == null)
			{
				val7 = reference9;
				reference9 = ref val7;
				if (val7 == null)
				{
					obj13 = null;
					goto IL_00d5;
				}
			}
			obj13 = reference9.ToString();
			goto IL_00d5;
			IL_0314:
			array2[6] = (string)obj4;
			array2[7] = ", ";
			ref T5 reference10 = ref Item5;
			val4 = default(T5);
			object obj14;
			if (val4 == null)
			{
				val4 = reference10;
				reference10 = ref val4;
				if (val4 == null)
				{
					obj14 = null;
					goto IL_0357;
				}
			}
			obj14 = reference10.ToString();
			goto IL_0357;
			IL_01a0:
			array[10] = (string)obj10;
			array[11] = ", ";
			ref T7 reference11 = ref Item7;
			val3 = default(T7);
			if (val3 == null)
			{
				val3 = reference11;
				reference11 = ref val3;
				if (val3 == null)
				{
					obj12 = null;
					goto IL_01e5;
				}
			}
			obj12 = reference11.ToString();
			goto IL_01e5;
			IL_0251:
			array2[0] = (string)obj2;
			array2[1] = ", ";
			ref T2 reference12 = ref Item2;
			val5 = default(T2);
			if (val5 == null)
			{
				val5 = reference12;
				reference12 = ref val5;
				if (val5 == null)
				{
					obj11 = null;
					goto IL_0291;
				}
			}
			obj11 = reference12.ToString();
			goto IL_0291;
			IL_00d5:
			array[4] = (string)obj13;
			array[5] = ", ";
			ref T4 reference13 = ref Item4;
			val2 = default(T4);
			if (val2 == null)
			{
				val2 = reference13;
				reference13 = ref val2;
				if (val2 == null)
				{
					obj7 = null;
					goto IL_0118;
				}
			}
			obj7 = reference13.ToString();
			goto IL_0118;
			IL_0357:
			array2[8] = (string)obj14;
			array2[9] = ", ";
			ref T6 reference14 = ref Item6;
			val6 = default(T6);
			if (val6 == null)
			{
				val6 = reference14;
				reference14 = ref val6;
				if (val6 == null)
				{
					obj6 = null;
					goto IL_039c;
				}
			}
			obj6 = reference14.ToString();
			goto IL_039c;
		}
	}
	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_ValueTupleIncorrectType => GetResourceString("ArgumentException_ValueTupleIncorrectType");

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

		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.Numerics.Hashing
{
	internal static class HashHelpers
	{
		public static readonly int RandomSeed = Guid.NewGuid().GetHashCode();

		public static int Combine(int h1, int h2)
		{
			uint num = (uint)(h1 << 5) | ((uint)h1 >> 27);
			return ((int)num + h1) ^ h2;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[CLSCompliant(false)]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue)]
	public sealed class TupleElementNamesAttribute : Attribute
	{
		private readonly string[] _transformNames;

		public IList<string> TransformNames => _transformNames;

		public TupleElementNamesAttribute(string[] transformNames)
		{
			if (transformNames == null)
			{
				throw new ArgumentNullException("transformNames");
			}
			_transformNames = transformNames;
		}
	}
}

BepInEx/plugins/wlVLC/wlVLC.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
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.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FMOD;
using FMOD.Studio;
using FMODUnity;
using HarmonyLib;
using LibVLCSharp.Shared;
using Microsoft.CodeAnalysis;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.Video;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")]
[assembly: AssemblyCompany("wlVLC")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+20adbf3360da4a93e9c8fa50f2693a07d87684a1")]
[assembly: AssemblyProduct("wlVLC")]
[assembly: AssemblyTitle("wlVLC")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 wlVLC
{
	public class FMODAudioBridge : IDisposable
	{
		private const string MasterBusPath = "bus:/";

		private const string SfxVcaPath = "vca:/SFX";

		private const int Channels = 2;

		private const int RingSize = 1048576;

		private const int RingMask = 1048575;

		private const float InitialLatencySeconds = 0.12f;

		private const float MinLatencySeconds = 0.06f;

		private const float MaxLatencySeconds = 2.5f;

		private const float SlackSeconds = 0.08f;

		private const long MaxLeadMicroseconds = 10000000L;

		private const float RoomFadeSpeed = 1f;

		private const float Headroom = 0.01f;

		private IntPtr _ring;

		private long _writePos;

		private long _readPos;

		private int _activeCallbacks;

		private readonly int _sampleRate;

		private readonly int _frameSize;

		private readonly int _bytesPerSecond;

		private readonly long _minTargetBytes;

		private readonly long _maxTargetBytes;

		private readonly long _slackBytes;

		private long _targetBytes;

		private long _outputLatencyUs;

		private long _offsetUs;

		private bool _scheduleToPts;

		private int _priming = 1;

		private readonly SOUND_PCMREAD_CALLBACK _pcmReadCallback;

		private readonly SOUND_PCMSETPOS_CALLBACK _pcmSetPosCallback;

		private Sound _sound;

		private Channel _channel;

		private ChannelGroup _channelGroup;

		private bool _channelGroupIsBus;

		private bool _started;

		private bool _disposed;

		private float _roomVolume;

		private long _droppedBytes;

		public int SampleRate => _sampleRate;

		public int ChannelCount => 2;

		public string VlcFormat => "S16N";

		public unsafe FMODAudioBridge(int requestedRate)
		{
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Expected O, but got Unknown
			_sampleRate = ((requestedRate > 0) ? requestedRate : GetMixerSampleRate());
			_frameSize = 4;
			_bytesPerSecond = _sampleRate * _frameSize;
			_minTargetBytes = AlignToFrame((long)((float)_bytesPerSecond * 0.06f));
			_maxTargetBytes = AlignToFrame((long)((float)_bytesPerSecond * 2.5f));
			_slackBytes = AlignToFrame((long)((float)_bytesPerSecond * 0.08f));
			_targetBytes = AlignToFrame((long)((float)_bytesPerSecond * 0.12f));
			_pcmReadCallback = new SOUND_PCMREAD_CALLBACK(PcmRead);
			_pcmSetPosCallback = new SOUND_PCMSETPOS_CALLBACK(PcmSetPos);
			_ring = Marshal.AllocHGlobal(1048576);
			byte* ptr = (byte*)(void*)_ring;
			for (int i = 0; i < 1048576; i++)
			{
				ptr[i] = 0;
			}
		}

		private long AlignToFrame(long bytes)
		{
			return bytes - bytes % _frameSize;
		}

		[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_clock")]
		private static extern long LibVlcClock();

		private static bool PrimeVlcClock()
		{
			try
			{
				LibVlcClock();
				return true;
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogWarning((object)("libvlc_clock is unavailable, so the cinema audio cannot be scheduled against VLC's clock and may run ahead of the picture: " + ex.Message));
				return false;
			}
		}

		private static int GetMixerSampleRate()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (RuntimeManager.IsInitialized)
				{
					System coreSystem = RuntimeManager.CoreSystem;
					int num = default(int);
					SPEAKERMODE val = default(SPEAKERMODE);
					int num2 = default(int);
					if ((int)((System)(ref coreSystem)).getSoftwareFormat(ref num, ref val, ref num2) == 0 && num > 0)
					{
						return num;
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogWarning((object)("Could not query the FMOD mixer rate, defaulting to 48000: " + ex.Message));
			}
			return 48000;
		}

		public unsafe bool Start(Vector3 position, float minDistance, float maxDistance)
		{
			//IL_0024: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: 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_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: 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_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: 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_0136: Unknown result type (might be due to invalid IL or missing references)
			if (_started)
			{
				return true;
			}
			if (!RuntimeManager.IsInitialized)
			{
				Plugin.Logger.LogWarning((object)"FMOD is not initialised yet - spatial cinema audio is not available.");
				return false;
			}
			CREATESOUNDEXINFO val = new CREATESOUNDEXINFO
			{
				cbsize = Marshal.SizeOf(typeof(CREATESOUNDEXINFO)),
				numchannels = 2,
				defaultfrequency = _sampleRate,
				format = (SOUND_FORMAT)2,
				decodebuffersize = 1024u,
				length = (uint)(_sampleRate * _frameSize)
			};
			((CREATESOUNDEXINFO)(ref val)).pcmreadcallback = _pcmReadCallback;
			((CREATESOUNDEXINFO)(ref val)).pcmsetposcallback = _pcmSetPosCallback;
			System coreSystem = RuntimeManager.CoreSystem;
			RESULT val2 = ((System)(ref coreSystem)).createSound(IntPtr.Zero, (MODE)4195474, ref val, ref _sound);
			if ((int)val2 != 0)
			{
				Plugin.Logger.LogError((object)("FMOD createSound failed: " + ((object)(*(RESULT*)(&val2))/*cast due to .constrained prefix*/).ToString()));
				return false;
			}
			_channelGroup = ResolveChannelGroup();
			coreSystem = RuntimeManager.CoreSystem;
			val2 = ((System)(ref coreSystem)).playSound(_sound, _channelGroup, true, ref _channel);
			if ((int)val2 != 0)
			{
				Plugin.Logger.LogError((object)("FMOD playSound failed: " + ((object)(*(RESULT*)(&val2))/*cast due to .constrained prefix*/).ToString()));
				((Sound)(ref _sound)).release();
				((Sound)(ref _sound)).clearHandle();
				return false;
			}
			((Channel)(ref _channel)).set3DMinMaxDistance(minDistance, maxDistance);
			SetChannelPosition(position);
			((Channel)(ref _channel)).setVolume(0f);
			((Channel)(ref _channel)).setPaused(false);
			_outputLatencyUs = MeasureOutputLatency(val.decodebuffersize);
			_scheduleToPts = PrimeVlcClock();
			_started = true;
			Plugin.Logger.LogInfo((object)($"Cinema audio routed through FMOD ({_sampleRate}Hz {VlcFormat}, " + (_channelGroupIsBus ? "under bus:/" : "under the core master group") + $", output latency {(float)_outputLatencyUs / 1000f:0}ms)."));
			return true;
		}

		private long MeasureOutputLatency(uint decodeBufferSize)
		{
			//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)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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)
			long num = (long)decodeBufferSize * 1000000L / _sampleRate;
			System coreSystem = RuntimeManager.CoreSystem;
			uint num2 = default(uint);
			int num3 = default(int);
			if ((int)((System)(ref coreSystem)).getDSPBufferSize(ref num2, ref num3) == 0)
			{
				coreSystem = RuntimeManager.CoreSystem;
				int num4 = default(int);
				SPEAKERMODE val = default(SPEAKERMODE);
				int num5 = default(int);
				if ((int)((System)(ref coreSystem)).getSoftwareFormat(ref num4, ref val, ref num5) == 0 && num4 > 0)
				{
					num += num2 * num3 * 1000000 / num4;
				}
			}
			return num;
		}

		public void SetLatencyOffset(float milliseconds)
		{
			Interlocked.Exchange(ref _offsetUs, (long)(milliseconds * 1000f));
		}

		private ChannelGroup ResolveChannelGroup()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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_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_0025: 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_004d: 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_0047: 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)
			try
			{
				Bus bus = RuntimeManager.GetBus("bus:/");
				if (((Bus)(ref bus)).isValid() && (int)((Bus)(ref bus)).lockChannelGroup() == 0)
				{
					System studioSystem = RuntimeManager.StudioSystem;
					((System)(ref studioSystem)).flushCommands();
					ChannelGroup result = default(ChannelGroup);
					if ((int)((Bus)(ref bus)).getChannelGroup(ref result) == 0 && ((ChannelGroup)(ref result)).hasHandle())
					{
						_channelGroupIsBus = true;
						return result;
					}
					((Bus)(ref bus)).unlockChannelGroup();
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogWarning((object)("Could not lock bus:/ for cinema audio: " + ex.Message));
			}
			System coreSystem = RuntimeManager.CoreSystem;
			ChannelGroup result2 = default(ChannelGroup);
			((System)(ref coreSystem)).getMasterChannelGroup(ref result2);
			return result2;
		}

		public unsafe void Feed(IntPtr samples, uint frameCount, long pts)
		{
			if (samples == IntPtr.Zero || frameCount == 0 || frameCount > (uint)_sampleRate)
			{
				return;
			}
			Interlocked.Increment(ref _activeCallbacks);
			try
			{
				if (!_disposed && !(_ring == IntPtr.Zero))
				{
					Schedule(pts);
					int num = (int)frameCount * _frameSize;
					long num2 = _writePos;
					byte* ptr = (byte*)(void*)samples;
					byte* ptr2 = (byte*)(void*)_ring;
					int num3 = 0;
					while (num > 0)
					{
						int num4 = (int)(num2 & 0xFFFFF);
						int num5 = Math.Min(num, 1048576 - num4);
						Buffer.MemoryCopy(ptr + num3, ptr2 + num4, 1048576 - num4, num5);
						num3 += num5;
						num2 += num5;
						num -= num5;
					}
					Interlocked.Exchange(ref _writePos, num2);
				}
			}
			finally
			{
				Interlocked.Decrement(ref _activeCallbacks);
			}
		}

		private void Schedule(long pts)
		{
			if (!_scheduleToPts || pts <= 0)
			{
				return;
			}
			long num = pts - LibVlcClock();
			if (num < 10000000 && num > -10000000)
			{
				long num2 = (num - _outputLatencyUs + Interlocked.Read(in _offsetUs)) * _sampleRate / 1000000 * _frameSize;
				if (num2 < _minTargetBytes)
				{
					num2 = _minTargetBytes;
				}
				else if (num2 > _maxTargetBytes)
				{
					num2 = _maxTargetBytes;
				}
				if (Volatile.Read(in _priming) != 0)
				{
					Interlocked.Exchange(ref _targetBytes, num2);
					return;
				}
				long num3 = Interlocked.Read(in _targetBytes);
				Interlocked.Exchange(ref _targetBytes, AlignToFrame(num3 + (num2 - num3) / 32));
			}
		}

		public void Flush()
		{
			Interlocked.Exchange(ref _writePos, Interlocked.Read(in _readPos));
			Volatile.Write(ref _priming, 1);
		}

		private unsafe RESULT PcmRead(IntPtr sound, IntPtr data, uint datalen)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			if (data == IntPtr.Zero)
			{
				return (RESULT)0;
			}
			Interlocked.Increment(ref _activeCallbacks);
			try
			{
				byte* ptr = (byte*)(void*)data;
				if (_disposed || _ring == IntPtr.Zero)
				{
					for (int i = 0; i < (int)datalen; i++)
					{
						ptr[i] = 0;
					}
					return (RESULT)0;
				}
				byte* ptr2 = (byte*)(void*)_ring;
				long num = _readPos;
				long num2 = Interlocked.Read(in _writePos);
				long num3 = Interlocked.Read(in _targetBytes);
				long num4 = num2 - num;
				if (num4 > num3 + _slackBytes)
				{
					long num5 = num4 - num3;
					num5 -= num5 % _frameSize;
					num += num5;
					_droppedBytes += num5;
				}
				if (Volatile.Read(in _priming) != 0)
				{
					if (num2 - num < num3)
					{
						for (int j = 0; j < (int)datalen; j++)
						{
							ptr[j] = 0;
						}
						Interlocked.Exchange(ref _readPos, num);
						return (RESULT)0;
					}
					Volatile.Write(ref _priming, 0);
				}
				int num6 = (int)Math.Min((int)datalen, num2 - num);
				int k;
				int num8;
				for (k = 0; k < num6; k += num8)
				{
					int num7 = (int)(num & 0xFFFFF);
					num8 = Math.Min(num6 - k, 1048576 - num7);
					Buffer.MemoryCopy(ptr2 + num7, ptr + k, (int)datalen - k, num8);
					num += num8;
				}
				if (k < (int)datalen)
				{
					Volatile.Write(ref _priming, 1);
				}
				for (int l = k; l < (int)datalen; l++)
				{
					ptr[l] = 0;
				}
				Interlocked.Exchange(ref _readPos, num);
				return (RESULT)0;
			}
			finally
			{
				Interlocked.Decrement(ref _activeCallbacks);
			}
		}

		private RESULT PcmSetPos(IntPtr sound, int subsound, uint position, TIMEUNIT postype)
		{
			return (RESULT)0;
		}

		public void Update(Vector3 position, bool audible, bool occluded, float userVolume, float deltaTime)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			if (_started && !_disposed)
			{
				_roomVolume = Mathf.MoveTowards(_roomVolume, audible ? 1f : 0f, deltaTime * 1f);
				SetChannelPosition(position);
				float num = 1f;
				VCA vCA = RuntimeManager.GetVCA("vca:/SFX");
				if (((VCA)(ref vCA)).isValid())
				{
					float num2 = default(float);
					((VCA)(ref vCA)).getVolume(ref num, ref num2);
				}
				((Channel)(ref _channel)).setVolume(_roomVolume * num * userVolume * 0.01f);
				((Channel)(ref _channel)).setLowPassGain(occluded ? 0.35f : 1f);
			}
		}

		private void SetChannelPosition(Vector3 position)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			VECTOR val = RuntimeUtils.ToFMODVector(position);
			VECTOR val2 = default(VECTOR);
			if ((int)((Channel)(ref _channel)).set3DAttributes(ref val, ref val2) == 30)
			{
				System coreSystem = RuntimeManager.CoreSystem;
				if ((int)((System)(ref coreSystem)).playSound(_sound, _channelGroup, false, ref _channel) == 0)
				{
					((Channel)(ref _channel)).set3DAttributes(ref val, ref val2);
				}
			}
		}

		public void SetMinMaxDistance(float minDistance, float maxDistance)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (_started)
			{
				((Channel)(ref _channel)).set3DMinMaxDistance(minDistance, maxDistance);
			}
		}

		public void Dispose()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_004d: Unknown result type (might be due to invalid IL or missing references)
			if (_disposed)
			{
				return;
			}
			_disposed = true;
			if (_started)
			{
				((Channel)(ref _channel)).stop();
				((Channel)(ref _channel)).clearHandle();
				if (_channelGroupIsBus)
				{
					Bus bus = RuntimeManager.GetBus("bus:/");
					if (((Bus)(ref bus)).isValid())
					{
						((Bus)(ref bus)).unlockChannelGroup();
					}
				}
				((ChannelGroup)(ref _channelGroup)).clearHandle();
				_started = false;
			}
			if (((Sound)(ref _sound)).hasHandle())
			{
				((Sound)(ref _sound)).release();
				((Sound)(ref _sound)).clearHandle();
			}
			for (int i = 0; i < 200; i++)
			{
				if (Volatile.Read(in _activeCallbacks) <= 0)
				{
					break;
				}
				Thread.Sleep(1);
			}
			if (_ring != IntPtr.Zero)
			{
				IntPtr ring = _ring;
				_ring = IntPtr.Zero;
				Marshal.FreeHGlobal(ring);
			}
			long num = Interlocked.Read(in _droppedBytes);
			if (num > 0)
			{
				Plugin.Logger.LogInfo((object)$"Cinema audio bridge closed ({(float)num / (float)_bytesPerSecond:0.00}s skipped to hold latency).");
			}
		}
	}
	[BepInPlugin("wlVLC", "wlVLC", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		[DisallowMultipleComponent]
		public class VLCClient : MonoBehaviour
		{
			private MeshRenderer meshRenderer;

			private VideoPlayer _videoPlayer;

			private WobblyCinemaPlayer _cinemaPlayer;

			private bool _warmedUp;

			private bool _setupDone;

			public uint width = 1280u;

			public uint height = 720u;

			private Texture2D _videoTexture;

			private LibVLC _libVLC;

			private MediaPlayer _mediaPlayer;

			private GCHandle _videoBufferHandle;

			private byte[] _videoBuffer;

			private readonly Queue<Action> _mainThreadActions = new Queue<Action>();

			private Texture _previousTexture;

			private bool _isPlaying;

			private FMODAudioBridge _audioBridge;

			private int _volumeAttempts;

			private Exception _audioCallbackFault;

			private long _audioCallbackFaults;

			private long _reportedFaults;

			private Transform _screenTransform;

			private SoundRoomData _soundRoom;

			private void Awake()
			{
				enabled.SettingChanged += OnEnabledChanged;
				((MonoBehaviour)this).StartCoroutine(InitWhenReady());
			}

			private IEnumerator InitWhenReady()
			{
				while (!VLCWarmup.Ready)
				{
					yield return null;
				}
				_warmedUp = true;
				if (enabled.Value)
				{
					SetupVLCNow();
				}
			}

			private void EnqueueOnMainThread(Action action)
			{
				lock (_mainThreadActions)
				{
					_mainThreadActions.Enqueue(action);
				}
			}

			private void OnEnabledChanged(object _, EventArgs __)
			{
				EnqueueOnMainThread(delegate
				{
					if (_warmedUp)
					{
						if (enabled.Value)
						{
							SetupVLCNow();
						}
						else
						{
							TeardownVLCNow();
						}
					}
				});
			}

			private void SetupVLCNow()
			{
				//IL_009a: 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_0095: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
				//IL_0108: Expected O, but got Unknown
				if (!_setupDone)
				{
					_setupDone = true;
					width = (uint)math.clamp(videoWidth.Value, 1, 3840);
					height = (uint)math.clamp(videoHeight.Value, 1, 2160);
					VideoPlayer val = (_videoPlayer = ((Component)this).GetComponentInChildren<VideoPlayer>());
					WobblyCinemaPlayer val2 = (_cinemaPlayer = ((Component)this).GetComponent<WobblyCinemaPlayer>());
					meshRenderer = ((Component)val).GetComponent<MeshRenderer>();
					_screenTransform = ((Component)meshRenderer).transform;
					_soundRoom = (SoundRoomData)(((Object)(object)val2 != (Object)null) ? val2.soundRoom : default(SoundRoomData));
					StopGameCinemaClip();
					((Behaviour)val).enabled = false;
					Core.Initialize((string)null);
					_libVLC = VLCWarmup.SharedVLC;
					_videoBuffer = new byte[width * height * 4];
					_videoBufferHandle = GCHandle.Alloc(_videoBuffer, GCHandleType.Pinned);
					_videoTexture = new Texture2D((int)width, (int)height, (TextureFormat)14, false);
					_previousTexture = ((Renderer)meshRenderer).material.mainTexture;
					((Renderer)meshRenderer).material.mainTexture = (Texture)(object)_videoTexture;
					CreateMediaPlayer();
					_isPlaying = true;
					networkUrl.SettingChanged += RefreshMedia;
					fixedMediaPath.SettingChanged += RefreshMedia;
					useNetworkUrl.SettingChanged += RefreshMedia;
					optimizeForLiveStream.SettingChanged += RefreshMedia;
					loopVideo.SettingChanged += RefreshMedia;
					spatialAudio.SettingChanged += RebuildMediaPlayer;
					audioSampleRate.SettingChanged += RebuildMediaPlayer;
					audioMinDistance.SettingChanged += RefreshAudioDistances;
					audioMaxDistance.SettingChanged += RefreshAudioDistances;
					audioOffsetMs.SettingChanged += RefreshAudioOffset;
					RefreshMediaNow();
				}
			}

			private void TeardownVLCNow(bool restoreGameCinema = true)
			{
				if (_setupDone)
				{
					_setupDone = false;
					networkUrl.SettingChanged -= RefreshMedia;
					fixedMediaPath.SettingChanged -= RefreshMedia;
					useNetworkUrl.SettingChanged -= RefreshMedia;
					optimizeForLiveStream.SettingChanged -= RefreshMedia;
					loopVideo.SettingChanged -= RefreshMedia;
					spatialAudio.SettingChanged -= RebuildMediaPlayer;
					audioSampleRate.SettingChanged -= RebuildMediaPlayer;
					audioMinDistance.SettingChanged -= RefreshAudioDistances;
					audioMaxDistance.SettingChanged -= RefreshAudioDistances;
					audioOffsetMs.SettingChanged -= RefreshAudioOffset;
					DestroyMediaPlayer();
					if ((Object)(object)meshRenderer != (Object)null)
					{
						((Renderer)meshRenderer).material.mainTexture = _previousTexture;
					}
					if ((Object)(object)_videoPlayer != (Object)null)
					{
						((Behaviour)_videoPlayer).enabled = true;
					}
					if (restoreGameCinema)
					{
						RestartGameCinemaClip();
					}
					meshRenderer = null;
					_isPlaying = false;
					if ((Object)(object)_videoTexture != (Object)null)
					{
						Object.Destroy((Object)(object)_videoTexture);
					}
					_videoTexture = null;
					if (_videoBufferHandle.IsAllocated)
					{
						_videoBufferHandle.Free();
					}
				}
			}

			private void CreateMediaPlayer()
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Expected O, but got Unknown
				//IL_0042: 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_0059: Expected O, but got Unknown
				//IL_0059: Expected O, but got Unknown
				//IL_007d: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_0109: Expected O, but got Unknown
				//IL_0109: Expected O, but got Unknown
				//IL_0109: Expected O, but got Unknown
				_mediaPlayer = new MediaPlayer(_libVLC);
				_mediaPlayer.SetVideoFormat("RV32", width, height, width * 4);
				_mediaPlayer.SetVideoCallbacks(new LibVLCVideoLockCb(Lock), (LibVLCVideoUnlockCb)null, new LibVLCVideoDisplayCb(Display));
				if (spatialAudio.Value)
				{
					FMODAudioBridge fMODAudioBridge = new FMODAudioBridge(audioSampleRate.Value);
					if (!fMODAudioBridge.Start(_screenTransform.position, audioMinDistance.Value, audioMaxDistance.Value))
					{
						fMODAudioBridge.Dispose();
						return;
					}
					fMODAudioBridge.SetLatencyOffset(audioOffsetMs.Value);
					_audioBridge = fMODAudioBridge;
					_mediaPlayer.SetAudioFormat(fMODAudioBridge.VlcFormat, (uint)fMODAudioBridge.SampleRate, (uint)fMODAudioBridge.ChannelCount);
					_mediaPlayer.SetAudioCallbacks(new LibVLCAudioPlayCb(AudioPlay), (LibVLCAudioPauseCb)null, (LibVLCAudioResumeCb)null, new LibVLCAudioFlushCb(AudioFlush), new LibVLCAudioDrainCb(AudioDrain));
				}
			}

			private void DestroyMediaPlayer()
			{
				MediaPlayer mediaPlayer = _mediaPlayer;
				if (mediaPlayer != null)
				{
					mediaPlayer.Stop();
				}
				MediaPlayer mediaPlayer2 = _mediaPlayer;
				if (mediaPlayer2 != null)
				{
					((Internal)mediaPlayer2).Dispose();
				}
				_mediaPlayer = null;
				_audioBridge?.Dispose();
				_audioBridge = null;
			}

			private void RebuildMediaPlayer(object sender, EventArgs args)
			{
				EnqueueOnMainThread(delegate
				{
					DestroyMediaPlayer();
					CreateMediaPlayer();
					RefreshMediaNow();
				});
			}

			private void RefreshAudioDistances(object sender, EventArgs args)
			{
				EnqueueOnMainThread(delegate
				{
					_audioBridge?.SetMinMaxDistance(audioMinDistance.Value, audioMaxDistance.Value);
				});
			}

			private void RefreshAudioOffset(object sender, EventArgs args)
			{
				EnqueueOnMainThread(delegate
				{
					_audioBridge?.SetLatencyOffset(audioOffsetMs.Value);
				});
			}

			private WobblyCinemaClip GetCurrentCinemaClip()
			{
				if ((Object)(object)_cinemaPlayer == (Object)null)
				{
					return null;
				}
				WobblyCinemaClip[] cinemaClips = _cinemaPlayer.cinemaClips;
				byte currentClipIndex = _cinemaPlayer.currentClipIndex;
				if (cinemaClips == null || currentClipIndex >= cinemaClips.Length)
				{
					return null;
				}
				return cinemaClips[currentClipIndex];
			}

			private void StopGameCinemaClip()
			{
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				WobblyCinemaClip currentCinemaClip = GetCurrentCinemaClip();
				if (currentCinemaClip != null)
				{
					currentCinemaClip.Unload(_cinemaPlayer.videoPlayer, _cinemaPlayer.soundRoom);
				}
			}

			private void RestartGameCinemaClip()
			{
				if (!((Object)(object)_cinemaPlayer == (Object)null) && _cinemaPlayer.bPlayingVideo && !((Object)(object)_cinemaPlayer.visibleTrigger == (Object)null) && _cinemaPlayer.visibleTrigger.ContainsCameras())
				{
					_cinemaPlayer.OnFirstCameraEntered_VisibleTrigger((GameplayCamera)null);
				}
			}

			private void RefreshMedia(object sender, EventArgs args)
			{
				EnqueueOnMainThread(RefreshMediaNow);
			}

			private void RefreshMediaNow()
			{
				//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ad: Expected O, but got Unknown
				//IL_0076: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Expected O, but got Unknown
				if (_mediaPlayer == null)
				{
					return;
				}
				try
				{
					if ((useNetworkUrl.Value && string.IsNullOrEmpty(networkUrl.Value)) || (!useNetworkUrl.Value && string.IsNullOrEmpty(fixedMediaPath.Value)))
					{
						_mediaPlayer.Stop();
						return;
					}
					if (!useNetworkUrl.Value)
					{
						Media val = new Media(_libVLC, fixedMediaPath.Value, (FromType)0, Array.Empty<string>());
						ApplyLoopOption(val);
						_mediaPlayer.Play(val);
						return;
					}
					Media val2 = new Media(_libVLC, networkUrl.Value, (FromType)1, Array.Empty<string>());
					if (optimizeForLiveStream.Value)
					{
						val2.AddOption(":network-caching=50");
						val2.AddOption(":rtmp-live");
					}
					ApplyLoopOption(val2);
					_mediaPlayer.Play(val2);
				}
				catch (Exception ex)
				{
					Logger.LogError((object)("Error refreshing media for wlVLC: " + ex));
				}
			}

			private static void ApplyLoopOption(Media media)
			{
				if (loopVideo.Value)
				{
					media.AddOption(":input-repeat=65535");
				}
			}

			private void Update()
			{
				while (true)
				{
					Action action;
					lock (_mainThreadActions)
					{
						if (_mainThreadActions.Count == 0)
						{
							break;
						}
						action = _mainThreadActions.Dequeue();
						goto IL_0039;
					}
					IL_0039:
					try
					{
						action?.Invoke();
					}
					catch (Exception ex)
					{
						Logger.LogError((object)("wlVLC main thread action failed: " + ex));
					}
				}
				if (meshRenderer != null)
				{
					if (Input.GetKeyDown((KeyCode)35) || Input.GetKeyDown((KeyCode)51) || Input.inputString.Contains("#") || Input.GetKeyDown((KeyCode)290))
					{
						_isPlaying = !_isPlaying;
						((Renderer)meshRenderer).material.mainTexture = (Texture)(_isPlaying ? ((object)_videoTexture) : ((object)_previousTexture));
					}
					UpdateAudio();
				}
			}

			private void UpdateAudio()
			{
				//IL_0082: Unknown result type (might be due to invalid IL or missing references)
				if (_audioBridge != null)
				{
					if (_mediaPlayer != null && _volumeAttempts < 5 && _mediaPlayer.Volume != 100)
					{
						_volumeAttempts++;
						_mediaPlayer.Volume = 100;
					}
					bool flag = IsListenerOutsideSoundRoom();
					bool audible = _isPlaying && (!flag || _soundRoom.bOcclusion);
					bool occluded = _soundRoom.bOcclusion && flag;
					_audioBridge.Update(_screenTransform.position, audible, occluded, audioVolume.Value, Time.deltaTime);
					long num = Interlocked.Read(in _audioCallbackFaults);
					if (num > _reportedFaults)
					{
						_reportedFaults = num;
						Logger.LogError((object)($"[cinema audio] audio callback threw ({num} total) - this is what " + $"stops the feed: {_audioCallbackFault}"));
					}
				}
			}

			private bool IsListenerOutsideSoundRoom()
			{
				//IL_0014: 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)
				if (!respectSoundRoom.Value)
				{
					return false;
				}
				if ((int)_soundRoom.soundRoom == 0)
				{
					return false;
				}
				if (!UnitySingleton<WobblySoundRoomManager>.InstanceExists)
				{
					return false;
				}
				WobblySoundRoomManager rawInstance = UnitySingleton<WobblySoundRoomManager>.GetRawInstance();
				if ((Object)(object)rawInstance == (Object)null)
				{
					return false;
				}
				return !rawInstance.GetCamerasInRoom().ContainsKey(_soundRoom.soundRoom);
			}

			private void OnDestroy()
			{
				enabled.SettingChanged -= OnEnabledChanged;
				TeardownVLCNow(restoreGameCinema: false);
			}

			private IntPtr Lock(IntPtr opaque, IntPtr planes)
			{
				Marshal.WriteIntPtr(planes, _videoBufferHandle.AddrOfPinnedObject());
				return IntPtr.Zero;
			}

			private void Display(IntPtr opaque, IntPtr picture)
			{
				lock (_mainThreadActions)
				{
					_mainThreadActions.Enqueue(delegate
					{
						if (!((Object)(object)_videoTexture == (Object)null))
						{
							int num = (int)(width * 4);
							byte[] array = new byte[_videoBuffer.Length];
							for (int i = 0; i < height; i++)
							{
								Buffer.BlockCopy(_videoBuffer, i * num, array, _videoBuffer.Length - (i + 1) * num, num);
							}
							_videoTexture.LoadRawTextureData(array);
							_videoTexture.Apply(false);
						}
					});
				}
			}

			private void AudioPlay(IntPtr data, IntPtr samples, uint count, long pts)
			{
				try
				{
					_audioBridge?.Feed(samples, count, pts);
				}
				catch (Exception ex)
				{
					RecordAudioFault(ex);
				}
			}

			private void AudioFlush(IntPtr data, long pts)
			{
				try
				{
					_audioBridge?.Flush();
				}
				catch (Exception ex)
				{
					RecordAudioFault(ex);
				}
			}

			private void AudioDrain(IntPtr data)
			{
				try
				{
					_audioBridge?.Flush();
				}
				catch (Exception ex)
				{
					RecordAudioFault(ex);
				}
			}

			private void RecordAudioFault(Exception ex)
			{
				_audioCallbackFault = ex;
				Interlocked.Increment(ref _audioCallbackFaults);
			}
		}

		internal static ManualLogSource Logger;

		internal static ConfigEntry<string> networkUrl;

		internal static ConfigEntry<bool> optimizeForLiveStream;

		internal static ConfigEntry<string> fixedMediaPath;

		internal static ConfigEntry<bool> useNetworkUrl;

		internal static ConfigEntry<bool> loopVideo;

		internal static ConfigEntry<bool> enabled;

		internal static ConfigEntry<bool> spatialAudio;

		internal static ConfigEntry<float> audioVolume;

		internal static ConfigEntry<float> audioMinDistance;

		internal static ConfigEntry<float> audioMaxDistance;

		internal static ConfigEntry<int> audioSampleRate;

		internal static ConfigEntry<float> audioOffsetMs;

		internal static ConfigEntry<bool> respectSoundRoom;

		internal static ConfigEntry<int> videoWidth;

		internal static ConfigEntry<int> videoHeight;

		private void Awake()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Expected O, but got Unknown
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Expected O, but got Unknown
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Expected O, but got Unknown
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			new Harmony("wlVLC").PatchAll(typeof(Plugin));
			enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "Enabled", true, (ConfigDescription)null);
			networkUrl = ((BaseUnityPlugin)this).Config.Bind<string>("Config", "NetworkResourceURL", "", (ConfigDescription)null);
			useNetworkUrl = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "UseNetworkUrl", false, "false = Use Media Path");
			optimizeForLiveStream = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "OptimizeForLiveStream", false, (ConfigDescription)null);
			fixedMediaPath = ((BaseUnityPlugin)this).Config.Bind<string>("Config", "FixedMediaPath", "", (ConfigDescription)null);
			loopVideo = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "Loop", false, "Start the video over again when it reaches the end. Toggling this restarts playback, and it has no effect on live streams.");
			videoWidth = ((BaseUnityPlugin)this).Config.Bind<int>("Config", "Video Width", 1280, "Resolution width for the buffer and texture, does not need to match the source video, restart the game to apply (e.g. 1920 for 1080p or 1280 for 720p)");
			videoHeight = ((BaseUnityPlugin)this).Config.Bind<int>("Config", "Video Height", 720, "Resolution height for the buffer and texture, does not need to match the source video, restart the game to apply (e.g. 1080 for 1080p or 720 for 720p)");
			spatialAudio = ((BaseUnityPlugin)this).Config.Bind<bool>("Audio", "SpatialAudio", true, "Play the audio through the game's FMOD system, positioned at the cinema screen, instead of straight out of the default audio device.");
			audioVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "Volume", 1f, new ConfigDescription("Volume of the spatialized audio, on top of the game's own volume sliders. 1 is calibrated to sit at about the same level as the game's own sounds; the range goes well above that for hosts whose media is quieter.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
			audioMinDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "MinDistance", 5f, new ConfigDescription("Distance from the screen at which the audio starts getting quieter.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 100f), Array.Empty<object>()));
			audioMaxDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "MaxDistance", 45f, new ConfigDescription("Distance from the screen at which the audio becomes inaudible.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 500f), Array.Empty<object>()));
			audioSampleRate = ((BaseUnityPlugin)this).Config.Bind<int>("Audio", "SampleRate", 0, "Sample rate to ask LibVLC for. 0 follows FMOD's mixer rate (48000). Setting the media's own rate instead (usually 44100) sounds better");
			audioOffsetMs = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "OffsetMilliseconds", 0f, new ConfigDescription("Fine adjustment to when the spatialised audio plays, relative to the picture. The audio is already scheduled against VLC's own clock, so 0 should be right; raise it if the sound still runs ahead of the picture, lower it if it lags behind.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-500f, 500f), Array.Empty<object>()));
			respectSoundRoom = ((BaseUnityPlugin)this).Config.Bind<bool>("Audio", "RespectSoundRoom", true, "Mute the audio while you are outside the cinema's sound room, the way the game does with its own cinema soundtrack. Turn off if the audio stays silent indoors.");
			VLCWarmup.StartWarmup();
			Logger.LogInfo((object)"Plugin wlVLC is loaded!");
		}

		[HarmonyPatch(typeof(WobblyCinemaClip), "Load")]
		[HarmonyPrefix]
		public static bool WobblyCinemaClip_Load_Prefix()
		{
			if (enabled.Value)
			{
				return VLCWarmup.Failed;
			}
			return true;
		}

		[HarmonyPatch(typeof(WobblyCinemaPlayer), "NetworkPost")]
		[HarmonyPostfix]
		public static void WobblyCinemaPlayer_NetworkPost_Postfix(ref WobblyCinemaPlayer __instance)
		{
			((Component)__instance).gameObject.AddComponent<VLCClient>();
		}
	}
	public static class VLCWarmup
	{
		public static LibVLC SharedVLC;

		public static bool Ready;

		public static bool Failed;

		public static void StartWarmup()
		{
			if (Ready)
			{
				return;
			}
			ThreadPool.QueueUserWorkItem(delegate
			{
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Expected O, but got Unknown
				try
				{
					Core.Initialize((string)null);
					SharedVLC = new LibVLC(new string[1] { "--no-xlib" });
					Ready = true;
				}
				catch (Exception ex)
				{
					Failed = true;
					Plugin.Logger.LogError((object)("VLC warmup failed: " + ex));
				}
			});
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "wlVLC";

		public const string PLUGIN_NAME = "wlVLC";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}