Decompiled source of WormtownAI v0.1.0

Microsoft.ML.OnnxRuntime.dll

Decompiled 14 hours ago
using System;
using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.ML.OnnxRuntime.Tensors;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: InternalsVisibleTo("Microsoft.ML.OnnxRuntime.Tests.Common, PublicKey=002400000480000094000000060200000024000052534131000400000100010059013e94e4bc70136ca4c35f33acd6b62974536b698f9c7a21cee18d805c7ad860ad9eebfdc47a96ba2f8d03f4cf1c36b9d30787e276c7b9833b5bf2a6eba7e919e6b90083078a352262aed1d842e5f70a3085cbcf4c56ae851b161137920961c23fcc246598d61d258ccc615c927b2441359eea666a99ce1c3c07dca18fb0e1")]
[assembly: InternalsVisibleTo("Microsoft.ML.OnnxRuntime.Tests.Droid, PublicKey=002400000480000094000000060200000024000052534131000400000100010059013e94e4bc70136ca4c35f33acd6b62974536b698f9c7a21cee18d805c7ad860ad9eebfdc47a96ba2f8d03f4cf1c36b9d30787e276c7b9833b5bf2a6eba7e919e6b90083078a352262aed1d842e5f70a3085cbcf4c56ae851b161137920961c23fcc246598d61d258ccc615c927b2441359eea666a99ce1c3c07dca18fb0e1")]
[assembly: InternalsVisibleTo("Microsoft.ML.OnnxRuntime.Tests.iOS, PublicKey=002400000480000094000000060200000024000052534131000400000100010059013e94e4bc70136ca4c35f33acd6b62974536b698f9c7a21cee18d805c7ad860ad9eebfdc47a96ba2f8d03f4cf1c36b9d30787e276c7b9833b5bf2a6eba7e919e6b90083078a352262aed1d842e5f70a3085cbcf4c56ae851b161137920961c23fcc246598d61d258ccc615c927b2441359eea666a99ce1c3c07dca18fb0e1")]
[assembly: InternalsVisibleTo("Microsoft.ML.OnnxRuntime.Tests.NetCoreApp, PublicKey=002400000480000094000000060200000024000052534131000400000100010059013e94e4bc70136ca4c35f33acd6b62974536b698f9c7a21cee18d805c7ad860ad9eebfdc47a96ba2f8d03f4cf1c36b9d30787e276c7b9833b5bf2a6eba7e919e6b90083078a352262aed1d842e5f70a3085cbcf4c56ae851b161137920961c23fcc246598d61d258ccc615c927b2441359eea666a99ce1c3c07dca18fb0e1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Embedded]
	internal sealed class IsUnmanagedAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Embedded]
	internal sealed class IsByRefLikeAttribute : Attribute
	{
	}
	[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 Microsoft.ML.OnnxRuntime
{
	public interface IDisposableReadOnlyCollection<T> : IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable, IReadOnlyList<T>, IDisposable
	{
	}
	internal class DisposableList<T> : List<T>, IDisposableReadOnlyCollection<T>, IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable, IReadOnlyList<T>, IDisposable where T : IDisposable
	{
		private bool _disposed;

		public DisposableList()
		{
		}

		public DisposableList(int count)
			: base(count)
		{
		}

		public DisposableList(IEnumerable<T> collection)
			: base(collection)
		{
		}

		protected virtual void Dispose(bool disposing)
		{
			if (_disposed || !disposing)
			{
				return;
			}
			for (int num = base.Count - 1; num >= 0; num--)
			{
				T val = base[num];
				if (val != null)
				{
					val.Dispose();
				}
			}
			Clear();
			_disposed = true;
		}

		public void Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}
	}
	public class DisposableNamedOnnxValue : NamedOnnxValue, IDisposable
	{
		private IOrtValueOwner _ortValueHolder;

		private bool _disposed;

		public TensorElementType ElementType { get; }

		private DisposableNamedOnnxValue(string name, object value, TensorElementType elementType, IOrtValueOwner ortValueHolder)
			: base(name, value, OnnxValueType.ONNX_TYPE_TENSOR)
		{
			_ortValueHolder = ortValueHolder;
			ElementType = elementType;
		}

		private DisposableNamedOnnxValue(string name, object value, OnnxValueType onnxValueType, IOrtValueOwner ortValueHolder)
			: base(name, value, onnxValueType)
		{
			_ortValueHolder = ortValueHolder;
			ElementType = TensorElementType.DataTypeMax;
		}

		private DisposableNamedOnnxValue(string name, object value, MapHelper mapHelper, IOrtValueOwner ortValueHolder)
			: base(name, value, mapHelper)
		{
			_ortValueHolder = ortValueHolder;
			ElementType = TensorElementType.DataTypeMax;
		}

		internal override IntPtr InputToOrtValueHandle(NodeMetadata metadata, out IDisposable memoryHolder)
		{
			if (_ortValueHolder == null)
			{
				throw new InvalidOperationException("The instance of this class does not own an OrtValue");
			}
			memoryHolder = null;
			return _ortValueHolder.Value.Handle;
		}

		internal override IntPtr OutputToOrtValueHandle(NodeMetadata metadata, out IDisposable memoryOwner)
		{
			return InputToOrtValueHandle(metadata, out memoryOwner);
		}

		internal static DisposableNamedOnnxValue CreateFromOrtValue(string name, ref OrtValue ortValue)
		{
			return CreateFromOrtValue(name, ref ortValue, OrtAllocator.DefaultInstance);
		}

		internal static DisposableNamedOnnxValue CreateFromOrtValue(string name, ref OrtValue ortValue, OrtAllocator allocator)
		{
			OnnxValueType onnxType = ortValue.OnnxType;
			return onnxType switch
			{
				OnnxValueType.ONNX_TYPE_TENSOR => FromNativeTensor(name, ref ortValue), 
				OnnxValueType.ONNX_TYPE_SEQUENCE => FromNativeSequence(name, ref ortValue, allocator), 
				OnnxValueType.ONNX_TYPE_MAP => FromNativeMap(name, ref ortValue, allocator), 
				_ => throw new NotSupportedException($"OnnxValueType : {onnxType} is not supported"), 
			};
		}

		private static DisposableNamedOnnxValue FromNativeTensor(string name, ref OrtValue ortValue)
		{
			OrtTensorTypeAndShapeInfo tensorTypeAndShape = ortValue.GetTensorTypeAndShape();
			switch (tensorTypeAndShape.ElementDataType)
			{
			case TensorElementType.Float:
				return FromNativeTensor<float>(name, ref ortValue);
			case TensorElementType.Double:
				return FromNativeTensor<double>(name, ref ortValue);
			case TensorElementType.Int16:
				return FromNativeTensor<short>(name, ref ortValue);
			case TensorElementType.UInt16:
				return FromNativeTensor<ushort>(name, ref ortValue);
			case TensorElementType.Int32:
				return FromNativeTensor<int>(name, ref ortValue);
			case TensorElementType.UInt32:
				return FromNativeTensor<uint>(name, ref ortValue);
			case TensorElementType.Int64:
				return FromNativeTensor<long>(name, ref ortValue);
			case TensorElementType.UInt64:
				return FromNativeTensor<ulong>(name, ref ortValue);
			case TensorElementType.UInt8:
				return FromNativeTensor<byte>(name, ref ortValue);
			case TensorElementType.Int8:
				return FromNativeTensor<sbyte>(name, ref ortValue);
			case TensorElementType.String:
			{
				int[] shape = Array.ConvertAll(tensorTypeAndShape.Shape, Convert.ToInt32);
				return FromNativeStringTensor(name, shape, ref ortValue);
			}
			case TensorElementType.Bool:
				return FromNativeTensor<bool>(name, ref ortValue);
			case TensorElementType.Float16:
				return FromNativeTensor<Float16>(name, ref ortValue);
			case TensorElementType.BFloat16:
				return FromNativeTensor<BFloat16>(name, ref ortValue);
			default:
				throw new NotSupportedException($"Tensor of element type: {tensorTypeAndShape.ElementDataType} is not supported");
			}
		}

		private static DisposableNamedOnnxValue FromNativeStringTensor(string name, int[] shape, ref OrtValue ortValue)
		{
			DenseTensor<string> value = new DenseTensor<string>(ortValue.GetStringTensorAsArray(), shape);
			DisposableNamedOnnxValue result = new DisposableNamedOnnxValue(name, value, TensorElementType.String, ortValue);
			ortValue = null;
			return result;
		}

		private static DisposableNamedOnnxValue FromNativeTensor<T>(string name, ref OrtValue ortValue)
		{
			OrtValueTensor<T> ortValueTensor = new OrtValueTensor<T>(ref ortValue);
			try
			{
				DenseTensor<T> value = new DenseTensor<T>(ortValueTensor.Memory, ortValueTensor.Dimensions);
				return new DisposableNamedOnnxValue(name, value, ortValueTensor.ElementType, ortValueTensor);
			}
			catch (Exception)
			{
				ortValueTensor.Dispose();
				throw;
			}
		}

		private static DisposableNamedOnnxValue FromNativeSequence(string name, ref OrtValue ortValueSequence, OrtAllocator allocator)
		{
			int valueCount = ortValueSequence.GetValueCount();
			DisposableList<DisposableNamedOnnxValue> disposableList = new DisposableList<DisposableNamedOnnxValue>(valueCount);
			try
			{
				for (int i = 0; i < valueCount; i++)
				{
					OrtValue ortValue = ortValueSequence.GetValue(i, allocator);
					try
					{
						disposableList.Add(CreateFromOrtValue(string.Empty, ref ortValue, allocator));
					}
					finally
					{
						ortValue?.Dispose();
					}
				}
				NativeOrtValueCollectionOwner ortValueHolder = new NativeOrtValueCollectionOwner(ref ortValueSequence, disposableList);
				return new DisposableNamedOnnxValue(name, disposableList, OnnxValueType.ONNX_TYPE_SEQUENCE, ortValueHolder);
			}
			catch (Exception)
			{
				disposableList.Dispose();
				throw;
			}
		}

		private static DisposableNamedOnnxValue FromNativeMap(string name, ref OrtValue ortValueMap, OrtAllocator allocator)
		{
			DisposableNamedOnnxValue result = null;
			Span<OrtValue> disposables = new OrtValue[2];
			DisposableArray<OrtValue> disposableArray = new DisposableArray<OrtValue>(disposables);
			try
			{
				disposables[0] = ortValueMap.GetValue(0, allocator);
				disposables[1] = ortValueMap.GetValue(1, allocator);
				OrtTensorTypeAndShapeInfo tensorTypeAndShape = disposables[0].GetTensorTypeAndShape();
				OrtTensorTypeAndShapeInfo tensorTypeAndShape2 = disposables[1].GetTensorTypeAndShape();
				int[] keysShape = Array.ConvertAll(tensorTypeAndShape.Shape, Convert.ToInt32);
				int[] valsShape = Array.ConvertAll(tensorTypeAndShape2.Shape, Convert.ToInt32);
				result = tensorTypeAndShape.ElementDataType switch
				{
					TensorElementType.Int64 => tensorTypeAndShape2.ElementDataType switch
					{
						TensorElementType.Float => FromNativeMapElements<long, float>(name, ref ortValueMap, keysShape, ref disposables[0], valsShape, ref disposables[1]), 
						TensorElementType.Double => FromNativeMapElements<long, double>(name, ref ortValueMap, keysShape, ref disposables[0], valsShape, ref disposables[1]), 
						TensorElementType.Int64 => FromNativeMapElements<long, long>(name, ref ortValueMap, keysShape, ref disposables[0], valsShape, ref disposables[1]), 
						TensorElementType.String => FromNativeMapElements<long, string>(name, ref ortValueMap, keysShape, ref disposables[0], valsShape, ref disposables[1]), 
						_ => throw new NotSupportedException($"Map value type: {tensorTypeAndShape2.ElementDataType} is not supported"), 
					}, 
					TensorElementType.String => tensorTypeAndShape2.ElementDataType switch
					{
						TensorElementType.Float => FromNativeMapElements<string, float>(name, ref ortValueMap, keysShape, ref disposables[0], valsShape, ref disposables[1]), 
						TensorElementType.Double => FromNativeMapElements<string, double>(name, ref ortValueMap, keysShape, ref disposables[0], valsShape, ref disposables[1]), 
						TensorElementType.Int64 => FromNativeMapElements<string, long>(name, ref ortValueMap, keysShape, ref disposables[0], valsShape, ref disposables[1]), 
						TensorElementType.String => FromNativeMapElements<string, string>(name, ref ortValueMap, keysShape, ref disposables[0], valsShape, ref disposables[1]), 
						_ => throw new NotSupportedException($"Map value type: {tensorTypeAndShape2.ElementDataType} is not supported"), 
					}, 
					_ => throw new NotSupportedException($"Map key type: {tensorTypeAndShape.ElementDataType} is not supported"), 
				};
			}
			finally
			{
				disposableArray.Dispose();
			}
			return result;
		}

		private static DisposableNamedOnnxValue FromNativeMapElements<K, V>(string name, ref OrtValue ortValueMap, int[] keysShape, ref OrtValue ortValueTensorKeys, int[] valsShape, ref OrtValue ortValueTensorValues)
		{
			if (typeof(K) == typeof(string))
			{
				DenseTensor<string> denseTensorKeys = new DenseTensor<string>(ortValueTensorKeys.GetStringTensorAsArray(), keysShape);
				if (typeof(V) == typeof(string))
				{
					DenseTensor<string> denseTensorValues = new DenseTensor<string>(ortValueTensorValues.GetStringTensorAsArray(), valsShape);
					Dictionary<string, string> value = Enumerable.Range(0, (int)denseTensorKeys.Length).ToDictionary((int i) => denseTensorKeys[new int[1] { i }], (int i) => denseTensorValues[new int[1] { i }]);
					MapHelper mapHelper = new MapHelper(denseTensorKeys, denseTensorValues);
					DisposableNamedOnnxValue result = new DisposableNamedOnnxValue(name, value, mapHelper, ortValueMap);
					ortValueMap = null;
					return result;
				}
				OrtValueTensor<V> ortValueTensor = new OrtValueTensor<V>(ref ortValueTensorValues);
				try
				{
					DenseTensor<V> values = new DenseTensor<V>(ortValueTensor.Memory, ortValueTensor.Dimensions);
					return FromMapDenseTensors(name, ref ortValueMap, denseTensorKeys, values, ortValueTensor);
				}
				catch (Exception)
				{
					ortValueTensor.Dispose();
					throw;
				}
			}
			DisposableList<IDisposable> disposableList = new DisposableList<IDisposable>(2);
			try
			{
				OrtValueTensor<K> ortValueTensor2 = new OrtValueTensor<K>(ref ortValueTensorKeys);
				disposableList.Add(ortValueTensor2);
				DenseTensor<K> keys = new DenseTensor<K>(ortValueTensor2.Memory, ortValueTensor2.Dimensions);
				if (typeof(V) == typeof(string))
				{
					DenseTensor<string> values2 = new DenseTensor<string>(ortValueTensorValues.GetStringTensorAsArray(), valsShape);
					return FromMapDenseTensors(name, ref ortValueMap, keys, values2, disposableList);
				}
				OrtValueTensor<V> ortValueTensor3 = new OrtValueTensor<V>(ref ortValueTensorValues);
				disposableList.Add(ortValueTensor3);
				DenseTensor<V> values3 = new DenseTensor<V>(ortValueTensor3.Memory, ortValueTensor3.Dimensions);
				return FromMapDenseTensors(name, ref ortValueMap, keys, values3, disposableList);
			}
			catch (Exception)
			{
				disposableList.Dispose();
				throw;
			}
		}

		private static DisposableNamedOnnxValue FromMapDenseTensors<K, V>(string name, ref OrtValue ortValueMap, DenseTensor<K> keys, DenseTensor<V> values, IDisposable disposables)
		{
			Dictionary<K, V> value = Enumerable.Range(0, (int)keys.Length).ToDictionary((int i) => keys[new int[1] { i }], (int i) => values[new int[1] { i }]);
			MapHelper mapHelper = new MapHelper(keys, values);
			NativeOrtValueCollectionOwner ortValueHolder = new NativeOrtValueCollectionOwner(ref ortValueMap, disposables);
			return new DisposableNamedOnnxValue(name, value, mapHelper, ortValueHolder);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (!_disposed)
			{
				if (disposing && _ortValueHolder != null)
				{
					_ortValueHolder.Dispose();
					_ortValueHolder = null;
				}
				_disposed = true;
			}
		}

		public void Dispose()
		{
			Dispose(disposing: true);
		}
	}
	internal enum ErrorCode
	{
		Ok,
		Fail,
		InvalidArgument,
		NoSuchFile,
		NoModel,
		EngineError,
		RuntimeException,
		InvalidProtobuf,
		ModelLoaded,
		NotImplemented,
		InvalidGraph,
		ShapeInferenceNotRegistered,
		RequirementNotRegistered
	}
	public class OnnxRuntimeException : Exception
	{
		private static Dictionary<ErrorCode, string> errorCodeToString = new Dictionary<ErrorCode, string>
		{
			{
				ErrorCode.Ok,
				"Ok"
			},
			{
				ErrorCode.Fail,
				"Fail"
			},
			{
				ErrorCode.InvalidArgument,
				"InvalidArgument"
			},
			{
				ErrorCode.NoSuchFile,
				"NoSuchFile"
			},
			{
				ErrorCode.NoModel,
				"NoModel"
			},
			{
				ErrorCode.EngineError,
				"EngineError"
			},
			{
				ErrorCode.RuntimeException,
				"RuntimeException"
			},
			{
				ErrorCode.InvalidProtobuf,
				"InvalidProtobuf"
			},
			{
				ErrorCode.ModelLoaded,
				"ModelLoaded"
			},
			{
				ErrorCode.NotImplemented,
				"NotImplemented"
			},
			{
				ErrorCode.InvalidGraph,
				"InvalidGraph"
			},
			{
				ErrorCode.ShapeInferenceNotRegistered,
				"ShapeInferenceNotRegistered"
			},
			{
				ErrorCode.RequirementNotRegistered,
				"RequirementNotRegistered"
			}
		};

		internal OnnxRuntimeException(ErrorCode errorCode, string message)
			: base("[ErrorCode:" + errorCodeToString[errorCode] + "] " + message)
		{
		}
	}
	public class FixedBufferOnnxValue : IDisposable
	{
		private bool _disposed = false;

		internal OrtValue Value { get; private set; }

		internal OnnxValueType OnnxValueType { get; private set; }

		internal TensorElementType ElementType { get; private set; }

		private FixedBufferOnnxValue(ref OrtValue ortValue, OnnxValueType onnxValueType, TensorElementType elementType)
		{
			Value = ortValue;
			ortValue = null;
			OnnxValueType = onnxValueType;
			ElementType = elementType;
		}

		public static FixedBufferOnnxValue CreateFromTensor<T>(Tensor<T> value)
		{
			TensorElementType elementType;
			OrtValue ortValue = OrtValue.CreateFromTensorObject(value, out elementType);
			return new FixedBufferOnnxValue(ref ortValue, OnnxValueType.ONNX_TYPE_TENSOR, elementType);
		}

		public static FixedBufferOnnxValue CreateFromMemory<T>(OrtMemoryInfo memoryInfo, Memory<T> memory, TensorElementType elementType, long[] shape, long bytesSize) where T : unmanaged
		{
			if (elementType == TensorElementType.String)
			{
				throw new ArgumentException("String data type is not supported");
			}
			OrtValue ortValue = OrtValue.CreateTensorValueFromMemory(memoryInfo, memory, shape);
			try
			{
				return new FixedBufferOnnxValue(ref ortValue, OnnxValueType.ONNX_TYPE_TENSOR, elementType);
			}
			catch (Exception)
			{
				ortValue?.Dispose();
				throw;
			}
		}

		protected virtual void Dispose(bool disposing)
		{
			if (!_disposed)
			{
				if (disposing)
				{
					Value.Dispose();
				}
				_disposed = true;
			}
		}

		public void Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}
	}
	public class InferenceSession : IDisposable
	{
		private delegate string NameExtractor<in TInput>(TInput input);

		private delegate IntPtr OrtValueHandleExtractor(NamedOnnxValue value, NodeMetadata metadata, out IDisposable memOwner);

		private delegate NodeMetadata MetadataLookup(string nodeName);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OrtCallbackDelegate(IntPtr userData, IntPtr[] outputs, uint numOutputs, IntPtr status);

		private delegate void UserCallbackDelegate(IReadOnlyCollection<OrtValue> outputs, IntPtr status);

		private class CallbackHost
		{
			public IReadOnlyCollection<string> inputNames { get; }

			public IReadOnlyCollection<OrtValue> inputValues { get; }

			public IReadOnlyCollection<string> outputNames { get; }

			public IReadOnlyCollection<OrtValue> outputValues { get; }

			public UserCallbackDelegate callback { get; }

			public IntPtr[] rawInputNames { get; }

			public IntPtr[] rawInputValues { get; }

			public IntPtr[] rawOutputNames { get; }

			public IntPtr[] rawOutputValues { get; }

			public CallbackHost(InferenceSession session, IReadOnlyCollection<string> cbInputNames, IReadOnlyCollection<OrtValue> cbinputValues, IReadOnlyCollection<string> cbOutputNames, IReadOnlyCollection<OrtValue> cbOutputValues, UserCallbackDelegate userCallback)
			{
				inputNames = cbInputNames;
				inputValues = cbinputValues;
				outputNames = cbOutputNames;
				outputValues = cbOutputValues;
				callback = userCallback;
				rawInputNames = LookupUtf8Names(inputNames, (string n) => n, session.LookupInputMetadata);
				rawInputValues = inputValues.Select((OrtValue v) => v.Handle).ToArray();
				rawOutputNames = LookupUtf8Names(outputNames, (string n) => n, session.LookupOutputMetadata);
				rawOutputValues = outputValues.Select((OrtValue v) => v.Handle).ToArray();
			}
		}

		private IntPtr _nativeHandle;

		private Dictionary<string, NodeMetadata> _inputMetadata;

		private List<string> _inputNames;

		private Dictionary<string, NodeMetadata> _outputMetadata;

		private List<string> _outputNames;

		private Dictionary<string, NodeMetadata> _overridableInitializerMetadata;

		private List<IntPtr> _namesMemoryPtrs;

		private SessionOptions _builtInSessionOptions = null;

		private RunOptions _builtInRunOptions = null;

		private ModelMetadata _modelMetadata = null;

		private bool _disposed = false;

		private ulong _profilingStartTimeNs = 0uL;

		private static OrtCallbackDelegate ortCallback = OrtCallback;

		public IReadOnlyDictionary<string, NodeMetadata> InputMetadata => _inputMetadata;

		public IReadOnlyList<string> InputNames => _inputNames;

		public IReadOnlyDictionary<string, NodeMetadata> OutputMetadata => _outputMetadata;

		public IReadOnlyList<string> OutputNames => _outputNames;

		public IReadOnlyDictionary<string, NodeMetadata> OverridableInitializerMetadata => _overridableInitializerMetadata;

		public ModelMetadata ModelMetadata
		{
			get
			{
				if (_modelMetadata != null)
				{
					return _modelMetadata;
				}
				_modelMetadata = new ModelMetadata(this);
				return _modelMetadata;
			}
		}

		public ulong ProfilingStartTimeNs => _profilingStartTimeNs;

		internal IntPtr Handle => _nativeHandle;

		public InferenceSession(string modelPath)
		{
			_builtInSessionOptions = new SessionOptions();
			Init(modelPath, _builtInSessionOptions);
		}

		public InferenceSession(string modelPath, PrePackedWeightsContainer prepackedWeightsContainer)
		{
			_builtInSessionOptions = new SessionOptions();
			Init(modelPath, _builtInSessionOptions, prepackedWeightsContainer);
		}

		public InferenceSession(string modelPath, SessionOptions options)
		{
			Init(modelPath, options);
		}

		public InferenceSession(string modelPath, SessionOptions options, PrePackedWeightsContainer prepackedWeightsContainer)
		{
			Init(modelPath, options, prepackedWeightsContainer);
		}

		public InferenceSession(byte[] model)
		{
			_builtInSessionOptions = new SessionOptions();
			Init(model, _builtInSessionOptions);
		}

		public InferenceSession(byte[] model, PrePackedWeightsContainer prepackedWeightsContainer)
		{
			_builtInSessionOptions = new SessionOptions();
			Init(model, _builtInSessionOptions, prepackedWeightsContainer);
		}

		public InferenceSession(byte[] model, SessionOptions options)
		{
			Init(model, options);
		}

		public InferenceSession(byte[] model, SessionOptions options, PrePackedWeightsContainer prepackedWeightsContainer)
		{
			Init(model, options, prepackedWeightsContainer);
		}

		public IDisposableReadOnlyCollection<DisposableNamedOnnxValue> Run(IReadOnlyCollection<NamedOnnxValue> inputs)
		{
			return Run(inputs, _outputNames);
		}

		public IDisposableReadOnlyCollection<DisposableNamedOnnxValue> Run(IReadOnlyCollection<NamedOnnxValue> inputs, IReadOnlyCollection<string> outputNames)
		{
			return Run(inputs, outputNames, _builtInRunOptions);
		}

		public IDisposableReadOnlyCollection<DisposableNamedOnnxValue> Run(IReadOnlyCollection<NamedOnnxValue> inputs, IReadOnlyCollection<string> outputNames, RunOptions options)
		{
			IntPtr[] inputNames = LookupUtf8Names(inputs, (NamedOnnxValue v) => v.Name, LookupInputMetadata);
			IntPtr[] outputNames2 = LookupUtf8Names(outputNames, (string n) => n, LookupOutputMetadata);
			DisposableArray<IDisposable> disposer;
			IntPtr[] ortValuesHandles = GetOrtValuesHandles(inputs, LookupInputMetadata, ExtractOrtValueHandleForInput, out disposer);
			try
			{
				using DisposableOrtValueHandleArray disposableOrtValueHandleArray = RunImpl(options, inputNames, ortValuesHandles, outputNames2);
				return CreateDisposableResult(disposableOrtValueHandleArray.Span, outputNames);
			}
			finally
			{
				disposer.Dispose();
			}
		}

		public IDisposableReadOnlyCollection<DisposableNamedOnnxValue> Run(IReadOnlyCollection<string> inputNames, IReadOnlyCollection<FixedBufferOnnxValue> inputValues)
		{
			return Run(inputNames, inputValues, _outputNames, _builtInRunOptions);
		}

		public IDisposableReadOnlyCollection<DisposableNamedOnnxValue> Run(IReadOnlyCollection<string> inputNames, IReadOnlyCollection<FixedBufferOnnxValue> inputValues, IReadOnlyCollection<string> outputNames)
		{
			return Run(inputNames, inputValues, outputNames, _builtInRunOptions);
		}

		public IDisposableReadOnlyCollection<DisposableNamedOnnxValue> Run(IReadOnlyCollection<string> inputNames, IReadOnlyCollection<FixedBufferOnnxValue> inputValues, IReadOnlyCollection<string> outputNames, RunOptions options)
		{
			if (inputNames.Count != inputValues.Count)
			{
				throw new ArgumentException(string.Format("Length of {0} ({1}) must match that of {2} ({3}).", "inputNames", inputNames.Count, "inputValues", inputValues.Count));
			}
			IntPtr[] inputNames2 = LookupUtf8Names(inputNames, (string n) => n, LookupInputMetadata);
			IntPtr[] ortValuesHandles = GetOrtValuesHandles(inputValues, input: true);
			IntPtr[] outputNames2 = LookupUtf8Names(outputNames, (string n) => n, LookupOutputMetadata);
			using DisposableOrtValueHandleArray disposableOrtValueHandleArray = RunImpl(options, inputNames2, ortValuesHandles, outputNames2);
			return CreateDisposableResult(disposableOrtValueHandleArray.Span, outputNames);
		}

		public void Run(IReadOnlyCollection<string> inputNames, IReadOnlyCollection<FixedBufferOnnxValue> inputValues, IReadOnlyCollection<string> outputNames, IReadOnlyCollection<FixedBufferOnnxValue> outputValues)
		{
			Run(inputNames, inputValues, outputNames, outputValues, _builtInRunOptions);
		}

		public void Run(IReadOnlyCollection<string> inputNames, IReadOnlyCollection<FixedBufferOnnxValue> inputValues, IReadOnlyCollection<string> outputNames, IReadOnlyCollection<FixedBufferOnnxValue> outputValues, RunOptions options)
		{
			if (inputNames.Count != inputValues.Count)
			{
				throw new ArgumentException(string.Format("Length of {0} ({1}) must match that of {2} ({3}).", "inputNames", inputNames.Count, "inputValues", inputValues.Count));
			}
			if (outputNames.Count != outputValues.Count)
			{
				throw new ArgumentException(string.Format("Length of {0} ({1}) must match that of {2} ({3}).", "outputNames", outputNames.Count, "outputValues", outputValues.Count));
			}
			IntPtr[] inputNames2 = LookupUtf8Names(inputNames, (string n) => n, LookupInputMetadata);
			IntPtr[] ortValuesHandles = GetOrtValuesHandles(inputValues, input: true);
			IntPtr[] outputNames2 = LookupUtf8Names(outputNames, (string n) => n, LookupOutputMetadata);
			IntPtr[] ortValuesHandles2 = GetOrtValuesHandles(outputValues, input: false);
			NativeApiStatus.VerifySuccess(NativeMethods.OrtRun(_nativeHandle, options.Handle, inputNames2, ortValuesHandles, (UIntPtr)(ulong)inputNames.Count, outputNames2, (UIntPtr)(ulong)outputNames.Count, ortValuesHandles2));
		}

		public void Run(IReadOnlyCollection<NamedOnnxValue> inputs, IReadOnlyCollection<NamedOnnxValue> outputs)
		{
			Run(inputs, outputs, _builtInRunOptions);
		}

		public void Run(IReadOnlyCollection<NamedOnnxValue> inputs, IReadOnlyCollection<NamedOnnxValue> outputs, RunOptions options)
		{
			IntPtr[] inputNames = LookupUtf8Names(inputs, (NamedOnnxValue i) => i.Name, LookupInputMetadata);
			IntPtr[] outputNames = LookupUtf8Names(outputs, (NamedOnnxValue o) => o.Name, LookupOutputMetadata);
			DisposableArray<IDisposable> disposer;
			IntPtr[] ortValuesHandles = GetOrtValuesHandles(inputs, LookupInputMetadata, ExtractOrtValueHandleForInput, out disposer);
			try
			{
				DisposableArray<IDisposable> disposer2;
				IntPtr[] ortValuesHandles2 = GetOrtValuesHandles(outputs, LookupOutputMetadata, ExtractOrtValueHandleForOutput, out disposer2);
				try
				{
					NativeApiStatus.VerifySuccess(NativeMethods.OrtRun(_nativeHandle, options.Handle, inputNames, ortValuesHandles, (UIntPtr)(ulong)inputs.Count, outputNames, (UIntPtr)(ulong)outputs.Count, ortValuesHandles2));
				}
				finally
				{
					disposer2.Dispose();
				}
			}
			finally
			{
				disposer.Dispose();
			}
		}

		public void Run(IReadOnlyCollection<NamedOnnxValue> inputs, IReadOnlyCollection<string> outputNames, IReadOnlyCollection<FixedBufferOnnxValue> outputValues)
		{
			Run(inputs, outputNames, outputValues, _builtInRunOptions);
		}

		public void Run(IReadOnlyCollection<NamedOnnxValue> inputs, IReadOnlyCollection<string> outputNames, IReadOnlyCollection<FixedBufferOnnxValue> outputValues, RunOptions options)
		{
			if (outputNames.Count != outputValues.Count)
			{
				throw new ArgumentException(string.Format("Length of {0} ({1}) must match that of {2} ({3}).", "outputNames", outputNames.Count, "outputValues", outputValues.Count));
			}
			IntPtr[] inputNames = LookupUtf8Names(inputs, (NamedOnnxValue i) => i.Name, LookupInputMetadata);
			IntPtr[] outputNames2 = LookupUtf8Names(outputNames, (string n) => n, LookupOutputMetadata);
			IntPtr[] ortValuesHandles = GetOrtValuesHandles(outputValues, input: false);
			DisposableArray<IDisposable> disposer;
			IntPtr[] ortValuesHandles2 = GetOrtValuesHandles(inputs, LookupInputMetadata, ExtractOrtValueHandleForInput, out disposer);
			try
			{
				NativeApiStatus.VerifySuccess(NativeMethods.OrtRun(_nativeHandle, options.Handle, inputNames, ortValuesHandles2, (UIntPtr)(ulong)inputs.Count, outputNames2, (UIntPtr)(ulong)outputNames.Count, ortValuesHandles));
			}
			finally
			{
				disposer.Dispose();
			}
		}

		public void Run(IReadOnlyCollection<string> inputNames, IReadOnlyCollection<FixedBufferOnnxValue> inputValues, IReadOnlyCollection<NamedOnnxValue> outputs)
		{
			Run(inputNames, inputValues, outputs, _builtInRunOptions);
		}

		public void Run(IReadOnlyCollection<string> inputNames, IReadOnlyCollection<FixedBufferOnnxValue> inputValues, IReadOnlyCollection<NamedOnnxValue> outputs, RunOptions options)
		{
			if (inputNames.Count != inputValues.Count)
			{
				throw new ArgumentException(string.Format("Length of {0} ({1}) must match that of {2} ({3}).", "inputNames", inputNames.Count, "inputValues", inputValues.Count));
			}
			IntPtr[] inputNames2 = LookupUtf8Names(inputNames, (string n) => n, LookupInputMetadata);
			IntPtr[] ortValuesHandles = GetOrtValuesHandles(inputValues, input: true);
			IntPtr[] outputNames = LookupUtf8Names(outputs, (NamedOnnxValue o) => o.Name, LookupOutputMetadata);
			DisposableArray<IDisposable> disposer;
			IntPtr[] ortValuesHandles2 = GetOrtValuesHandles(outputs, LookupOutputMetadata, ExtractOrtValueHandleForOutput, out disposer);
			try
			{
				NativeApiStatus.VerifySuccess(NativeMethods.OrtRun(_nativeHandle, options.Handle, inputNames2, ortValuesHandles, (UIntPtr)(ulong)inputNames.Count, outputNames, (UIntPtr)(ulong)outputs.Count, ortValuesHandles2));
			}
			finally
			{
				disposer.Dispose();
			}
		}

		public IDisposableReadOnlyCollection<OrtValue> Run(RunOptions runOptions, IReadOnlyCollection<string> inputNames, IReadOnlyCollection<OrtValue> inputValues, IReadOnlyCollection<string> outputNames)
		{
			if (inputNames.Count != inputValues.Count)
			{
				throw new ArgumentException(string.Format("Length of {0} ({1}) must match that of {2} ({3}).", "inputNames", inputNames.Count, "inputValues", inputValues.Count));
			}
			IntPtr[] inputNames2 = LookupUtf8Names(inputNames, (string n) => n, LookupInputMetadata);
			IntPtr[] inputValues2 = inputValues.Select((OrtValue v) => v.Handle).ToArray();
			IntPtr[] outputNames2 = LookupUtf8Names(outputNames, (string n) => n, LookupOutputMetadata);
			using DisposableOrtValueHandleArray disposableHandles = RunImpl(runOptions, inputNames2, inputValues2, outputNames2);
			return CreateDisposableResult(disposableHandles);
		}

		public IDisposableReadOnlyCollection<OrtValue> Run(RunOptions runOptions, IReadOnlyDictionary<string, OrtValue> inputs, IReadOnlyCollection<string> outputNames)
		{
			IntPtr[] array = new IntPtr[inputs.Count];
			IntPtr[] array2 = new IntPtr[inputs.Count];
			int num = 0;
			foreach (KeyValuePair<string, OrtValue> input in inputs)
			{
				array[num] = LookupInputMetadata(input.Key).ZeroTerminatedName;
				array2[num] = input.Value.Handle;
				num++;
			}
			IntPtr[] outputNames2 = LookupUtf8Names(outputNames, (string n) => n, LookupOutputMetadata);
			using DisposableOrtValueHandleArray disposableHandles = RunImpl(runOptions, array, array2, outputNames2);
			return CreateDisposableResult(disposableHandles);
		}

		private static IDisposableReadOnlyCollection<OrtValue> CreateDisposableResult(DisposableOrtValueHandleArray disposableHandles)
		{
			DisposableList<OrtValue> disposableList = new DisposableList<OrtValue>(disposableHandles.Span.Length);
			try
			{
				for (int i = 0; i < disposableHandles.Span.Length; i++)
				{
					disposableList.Add(new OrtValue(disposableHandles.Span[i]));
					disposableHandles.Span[i] = IntPtr.Zero;
				}
				return disposableList;
			}
			catch (Exception)
			{
				disposableList.Dispose();
				throw;
			}
		}

		public void Run(RunOptions runOptions, IReadOnlyCollection<string> inputNames, IReadOnlyCollection<OrtValue> inputValues, IReadOnlyCollection<string> outputNames, IReadOnlyCollection<OrtValue> outputValues)
		{
			if (inputNames.Count != inputValues.Count)
			{
				throw new ArgumentException(string.Format("Length of {0} ({1}) must match that of {2} ({3}).", "inputNames", inputNames.Count, "inputValues", inputValues.Count));
			}
			if (outputNames.Count != outputValues.Count)
			{
				throw new ArgumentException(string.Format("Length of {0} ({1}) must match that of {2} ({3}).", "outputNames", outputNames.Count, "outputValues", outputValues.Count));
			}
			if (runOptions == null)
			{
				runOptions = _builtInRunOptions;
			}
			IntPtr[] inputNames2 = LookupUtf8Names(inputNames, (string n) => n, LookupInputMetadata);
			IntPtr[] inputValues2 = inputValues.Select((OrtValue v) => v.Handle).ToArray();
			IntPtr[] outputNames2 = LookupUtf8Names(outputNames, (string n) => n, LookupOutputMetadata);
			IntPtr[] outputValues2 = outputValues.Select((OrtValue v) => v.Handle).ToArray();
			NativeApiStatus.VerifySuccess(NativeMethods.OrtRun(_nativeHandle, runOptions.Handle, inputNames2, inputValues2, (UIntPtr)(ulong)inputNames.Count, outputNames2, (UIntPtr)(ulong)outputNames.Count, outputValues2));
		}

		public OrtIoBinding CreateIoBinding()
		{
			return new OrtIoBinding(this);
		}

		public void RunWithBinding(RunOptions runOptions, OrtIoBinding ioBinding)
		{
			NativeApiStatus.VerifySuccess(NativeMethods.OrtRunWithBinding(Handle, runOptions.Handle, ioBinding.Handle));
		}

		public IDisposableReadOnlyCollection<OrtValue> RunWithBoundResults(RunOptions runOptions, OrtIoBinding ioBinding)
		{
			NativeApiStatus.VerifySuccess(NativeMethods.OrtRunWithBinding(Handle, runOptions.Handle, ioBinding.Handle));
			return ioBinding.GetOutputValues();
		}

		public IDisposableReadOnlyCollection<DisposableNamedOnnxValue> RunWithBindingAndNames(RunOptions runOptions, OrtIoBinding ioBinding, string[] names = null)
		{
			string[] array = names;
			if (array == null || names.Length == 0)
			{
				array = ioBinding.GetOutputNames();
			}
			NativeApiStatus.VerifySuccess(NativeMethods.OrtRunWithBinding(Handle, runOptions.Handle, ioBinding.Handle));
			OrtValue[] outputOrtValues = ioBinding.GetOutputOrtValues();
			DisposableArray<OrtValue> disposableArray = new DisposableArray<OrtValue>(outputOrtValues);
			try
			{
				DisposableList<DisposableNamedOnnxValue> disposableList = new DisposableList<DisposableNamedOnnxValue>(outputOrtValues.Length);
				try
				{
					for (int i = 0; i < array.Length; i++)
					{
						disposableList.Add(DisposableNamedOnnxValue.CreateFromOrtValue(array[i], ref outputOrtValues[i]));
					}
					return disposableList;
				}
				catch (Exception)
				{
					disposableList.Dispose();
					throw;
				}
			}
			finally
			{
				disposableArray.Dispose();
			}
		}

		public string EndProfiling()
		{
			OrtAllocator defaultInstance = OrtAllocator.DefaultInstance;
			NativeApiStatus.VerifySuccess(NativeMethods.OrtSessionEndProfiling(_nativeHandle, defaultInstance.Pointer, out var profile_file));
			return NativeOnnxValueHelper.StringFromNativeUtf8(profile_file, defaultInstance);
		}

		private NodeMetadata LookupInputMetadata(string nodeName)
		{
			if (!_inputMetadata.TryGetValue(nodeName, out var value) && !_overridableInitializerMetadata.TryGetValue(nodeName, out value))
			{
				throw new OnnxRuntimeException(ErrorCode.InvalidArgument, "Input name: '" + nodeName + "' is not in the metadata");
			}
			return value;
		}

		private NodeMetadata LookupOutputMetadata(string nodeName)
		{
			if (!_outputMetadata.TryGetValue(nodeName, out var value))
			{
				throw new OnnxRuntimeException(ErrorCode.InvalidArgument, "Output name: '" + nodeName + "' is not in the metadata");
			}
			return value;
		}

		private static IntPtr ExtractOrtValueHandleForInput(NamedOnnxValue input, NodeMetadata metadata, out IDisposable memOwner)
		{
			return input.InputToOrtValueHandle(metadata, out memOwner);
		}

		private static IntPtr ExtractOrtValueHandleForOutput(NamedOnnxValue output, NodeMetadata metadata, out IDisposable memOwner)
		{
			return output.OutputToOrtValueHandle(metadata, out memOwner);
		}

		private static IntPtr[] LookupUtf8Names<T>(IReadOnlyCollection<T> values, NameExtractor<T> nameExtractor, MetadataLookup metaLookup)
		{
			IntPtr[] array = new IntPtr[values.Count];
			for (int i = 0; i < values.Count; i++)
			{
				string nodeName = nameExtractor(values.ElementAt(i));
				NodeMetadata nodeMetadata = metaLookup(nodeName);
				array[i] = nodeMetadata.ZeroTerminatedName;
			}
			return array;
		}

		private static IntPtr[] GetOrtValuesHandles(IReadOnlyCollection<NamedOnnxValue> values, MetadataLookup metaLookup, OrtValueHandleExtractor ortValueExtractor, out DisposableArray<IDisposable> disposer)
		{
			IDisposable[] array = new IDisposable[values.Count];
			DisposableArray<IDisposable> disposableArray = new DisposableArray<IDisposable>(array);
			try
			{
				IntPtr[] array2 = new IntPtr[values.Count];
				for (int i = 0; i < values.Count; i++)
				{
					NamedOnnxValue namedOnnxValue = values.ElementAt(i);
					NodeMetadata metadata = metaLookup(namedOnnxValue.Name);
					array2[i] = ortValueExtractor(namedOnnxValue, metadata, out var memOwner);
					if (memOwner != null)
					{
						array[i] = memOwner;
					}
				}
				disposer = disposableArray;
				return array2;
			}
			catch (Exception)
			{
				disposableArray.Dispose();
				throw;
			}
		}

		private static IntPtr[] GetOrtValuesHandles(IReadOnlyCollection<FixedBufferOnnxValue> values, bool input)
		{
			IntPtr[] array = new IntPtr[values.Count];
			for (int i = 0; i < values.Count; i++)
			{
				FixedBufferOnnxValue fixedBufferOnnxValue = values.ElementAt(i);
				if (!input && fixedBufferOnnxValue.ElementType == TensorElementType.String)
				{
					throw new NotSupportedException("Using string type FixedBufferOnnxValue in outputs is not supported.");
				}
				array[i] = fixedBufferOnnxValue.Value.Handle;
			}
			return array;
		}

		private DisposableOrtValueHandleArray RunImpl(RunOptions options, IntPtr[] inputNames, IntPtr[] inputValues, IntPtr[] outputNames)
		{
			IntPtr[] array = new IntPtr[outputNames.Length];
			NativeApiStatus.VerifySuccess(NativeMethods.OrtRun(_nativeHandle, options.Handle, inputNames, inputValues, (UIntPtr)(ulong)inputNames.Length, outputNames, (UIntPtr)(ulong)outputNames.Length, array));
			return new DisposableOrtValueHandleArray(array);
		}

		private static IDisposableReadOnlyCollection<DisposableNamedOnnxValue> CreateDisposableResult(Span<IntPtr> valueHandles, IReadOnlyCollection<string> outputNames)
		{
			DisposableList<DisposableNamedOnnxValue> disposableList = new DisposableList<DisposableNamedOnnxValue>(valueHandles.Length);
			try
			{
				for (int i = 0; i < valueHandles.Length; i++)
				{
					OrtValue ortValue = new OrtValue(valueHandles[i]);
					disposableList.Add(DisposableNamedOnnxValue.CreateFromOrtValue(outputNames.ElementAt(i), ref ortValue));
					valueHandles[i] = IntPtr.Zero;
				}
			}
			catch (OnnxRuntimeException)
			{
				disposableList.Dispose();
				throw;
			}
			return disposableList;
		}

		private static void OrtCallback(IntPtr userData, IntPtr[] ouputs, uint numOutputs, IntPtr status)
		{
			GCHandle gCHandle = GCHandle.FromIntPtr(userData);
			CallbackHost callbackHost = (CallbackHost)gCHandle.Target;
			try
			{
				callbackHost.callback(callbackHost.outputValues, status);
			}
			finally
			{
				gCHandle.Free();
			}
		}

		private unsafe void RunAsyncInternal(RunOptions options, IReadOnlyCollection<string> inputNames, IReadOnlyCollection<OrtValue> inputValues, IReadOnlyCollection<string> outputNames, IReadOnlyCollection<OrtValue> outputValues, UserCallbackDelegate callback)
		{
			CallbackHost callbackHost = new CallbackHost(this, inputNames, inputValues, outputNames, outputValues, callback);
			GCHandle value = GCHandle.Alloc(callbackHost, GCHandleType.Normal);
			try
			{
				NativeApiStatus.VerifySuccess(NativeMethods.OrtRunAsync(_nativeHandle, options?.Handle ?? ((IntPtr)(void*)null), callbackHost.rawInputNames, callbackHost.rawInputValues, (UIntPtr)(ulong)callbackHost.rawInputNames.Length, callbackHost.rawOutputNames, (UIntPtr)(ulong)callbackHost.rawOutputNames.Length, callbackHost.rawOutputValues, Marshal.GetFunctionPointerForDelegate(ortCallback), GCHandle.ToIntPtr(value)));
			}
			catch (OnnxRuntimeException)
			{
				value.Free();
				throw;
			}
		}

		public async Task<IReadOnlyCollection<OrtValue>> RunAsync(RunOptions options, IReadOnlyCollection<string> inputNames, IReadOnlyCollection<OrtValue> inputValues, IReadOnlyCollection<string> outputNames, IReadOnlyCollection<OrtValue> outputValues)
		{
			TaskCompletionSource<IReadOnlyCollection<OrtValue>> promise = new TaskCompletionSource<IReadOnlyCollection<OrtValue>>();
			RunAsyncInternal(options, inputNames, inputValues, outputNames, outputValues, delegate(IReadOnlyCollection<OrtValue> outputs, IntPtr status)
			{
				try
				{
					NativeApiStatus.VerifySuccess(status);
					promise.SetResult(outputs);
				}
				catch (Exception exception)
				{
					promise.SetException(exception);
				}
			});
			return await promise.Task;
		}

		private void Init(string modelPath, SessionOptions options, PrePackedWeightsContainer prepackedWeightsContainer = null)
		{
			IntPtr handle = OrtEnv.Instance().Handle;
			IntPtr session;
			if (prepackedWeightsContainer == null)
			{
				NativeApiStatus.VerifySuccess(NativeMethods.OrtCreateSession(handle, NativeOnnxValueHelper.GetPlatformSerializedString(modelPath), options.Handle, out session));
			}
			else
			{
				NativeApiStatus.VerifySuccess(NativeMethods.OrtCreateSessionWithPrepackedWeightsContainer(handle, NativeOnnxValueHelper.GetPlatformSerializedString(modelPath), options.Handle, prepackedWeightsContainer.Pointer, out session));
			}
			InitWithSessionHandle(session);
		}

		private void Init(byte[] modelData, SessionOptions options, PrePackedWeightsContainer prepackedWeightsContainer = null)
		{
			IntPtr handle = OrtEnv.Instance().Handle;
			IntPtr session;
			if (prepackedWeightsContainer == null)
			{
				NativeApiStatus.VerifySuccess(NativeMethods.OrtCreateSessionFromArray(handle, modelData, (UIntPtr)(ulong)modelData.Length, options.Handle, out session));
			}
			else
			{
				NativeApiStatus.VerifySuccess(NativeMethods.OrtCreateSessionFromArrayWithPrepackedWeightsContainer(handle, modelData, (UIntPtr)(ulong)modelData.Length, options.Handle, prepackedWeightsContainer.Pointer, out session));
			}
			InitWithSessionHandle(session);
		}

		private void InitWithSessionHandle(IntPtr session)
		{
			_nativeHandle = session;
			try
			{
				NativeApiStatus.VerifySuccess(NativeMethods.OrtSessionGetInputCount(_nativeHandle, out var count));
				NativeApiStatus.VerifySuccess(NativeMethods.OrtSessionGetOutputCount(_nativeHandle, out var count2));
				NativeApiStatus.VerifySuccess(NativeMethods.OrtSessionGetOverridableInitializerCount(_nativeHandle, out var count3));
				int capacity = (int)((uint)count + (uint)count2 + (uint)count3);
				_namesMemoryPtrs = new List<IntPtr>(capacity);
				_inputMetadata = new Dictionary<string, NodeMetadata>((int)(uint)count);
				_inputNames = new List<string>((int)(uint)count);
				for (ulong num = 0uL; num < (ulong)count; num++)
				{
					NodeMetadata inputMetadata = GetInputMetadata(num);
					IntPtr utf;
					string inputName = GetInputName(num, out utf);
					_namesMemoryPtrs.Add(utf);
					inputMetadata.ZeroTerminatedName = utf;
					_inputNames.Add(inputName);
					_inputMetadata[inputName] = inputMetadata;
				}
				_outputMetadata = new Dictionary<string, NodeMetadata>((int)(uint)count2);
				_outputNames = new List<string>((int)(uint)count2);
				for (ulong num2 = 0uL; num2 < (ulong)count2; num2++)
				{
					NodeMetadata outputMetadata = GetOutputMetadata(num2);
					IntPtr utf2;
					string outputName = GetOutputName(num2, out utf2);
					_namesMemoryPtrs.Add(utf2);
					outputMetadata.ZeroTerminatedName = utf2;
					_outputNames.Add(outputName);
					_outputMetadata[outputName] = outputMetadata;
				}
				_overridableInitializerMetadata = new Dictionary<string, NodeMetadata>((int)(uint)count3);
				for (ulong num3 = 0uL; num3 < (ulong)count3; num3++)
				{
					NodeMetadata overridableInitializerMetadata = GetOverridableInitializerMetadata(num3);
					IntPtr utf3;
					string overridableInitializerName = GetOverridableInitializerName(num3, out utf3);
					_namesMemoryPtrs.Add(utf3);
					overridableInitializerMetadata.ZeroTerminatedName = utf3;
					_overridableInitializerMetadata[overridableInitializerName] = overridableInitializerMetadata;
				}
				NativeApiStatus.VerifySuccess(NativeMethods.OrtSessionGetProfilingStartTimeNs(_nativeHandle, out var startTime));
				_profilingStartTimeNs = (ulong)startTime;
			}
			catch (Exception)
			{
				DisposeImpl(disposing: true);
				throw;
			}
			_builtInRunOptions = new RunOptions();
		}

		private string GetOutputName(ulong index, out IntPtr utf8)
		{
			OrtAllocator defaultInstance = OrtAllocator.DefaultInstance;
			NativeApiStatus.VerifySuccess(NativeMethods.OrtSessionGetOutputName(_nativeHandle, (UIntPtr)index, defaultInstance.Pointer, out var name));
			NativeOnnxValueHelper.StringAndUtf8FromNative(defaultInstance, name, out var str, out utf8);
			return str;
		}

		private string GetInputName(ulong index, out IntPtr utf8)
		{
			OrtAllocator defaultInstance = OrtAllocator.DefaultInstance;
			NativeApiStatus.VerifySuccess(NativeMethods.OrtSessionGetInputName(_nativeHandle, (UIntPtr)index, defaultInstance.Pointer, out var name));
			NativeOnnxValueHelper.StringAndUtf8FromNative(defaultInstance, name, out var str, out utf8);
			return str;
		}

		private string GetOverridableInitializerName(ulong index, out IntPtr utf8)
		{
			OrtAllocator defaultInstance = OrtAllocator.DefaultInstance;
			NativeApiStatus.VerifySuccess(NativeMethods.OrtSessionGetOverridableInitializerName(_nativeHandle, (UIntPtr)index, defaultInstance.Pointer, out var name));
			NativeOnnxValueHelper.StringAndUtf8FromNative(defaultInstance, name, out var str, out utf8);
			return str;
		}

		private NodeMetadata GetInputMetadata(ulong index)
		{
			NativeApiStatus.VerifySuccess(NativeMethods.OrtSessionGetInputTypeInfo(_nativeHandle, (UIntPtr)index, out var typeInfo));
			try
			{
				return GetMetadataFromTypeInfo(typeInfo);
			}
			finally
			{
				NativeMethods.OrtReleaseTypeInfo(typeInfo);
			}
		}

		private NodeMetadata GetOutputMetadata(ulong index)
		{
			NativeApiStatus.VerifySuccess(NativeMethods.OrtSessionGetOutputTypeInfo(_nativeHandle, (UIntPtr)index, out var typeInfo));
			try
			{
				return GetMetadataFromTypeInfo(typeInfo);
			}
			finally
			{
				NativeMethods.OrtReleaseTypeInfo(typeInfo);
			}
		}

		private NodeMetadata GetOverridableInitializerMetadata(ulong index)
		{
			NativeApiStatus.VerifySuccess(NativeMethods.OrtSessionGetOverridableInitializerTypeInfo(_nativeHandle, (UIntPtr)index, out var typeInfo));
			try
			{
				return GetMetadataFromTypeInfo(typeInfo);
			}
			finally
			{
				NativeMethods.OrtReleaseTypeInfo(typeInfo);
			}
		}

		internal static NodeMetadata GetMetadataFromTypeInfo(IntPtr typeInfo)
		{
			NativeApiStatus.VerifySuccess(NativeMethods.OrtGetOnnxTypeFromTypeInfo(typeInfo, out var onnxtype));
			OnnxValueType onnxValueType = (OnnxValueType)(int)onnxtype;
			switch (onnxValueType)
			{
			case OnnxValueType.ONNX_TYPE_TENSOR:
			case OnnxValueType.ONNX_TYPE_SPARSETENSOR:
				return GetTensorNodeMetadata(onnxValueType, typeInfo);
			case OnnxValueType.ONNX_TYPE_SEQUENCE:
				return GetSequenceMetadataFromTypeInfo(typeInfo);
			case OnnxValueType.ONNX_TYPE_MAP:
				return GetMapMetadataFromTypeInfo(typeInfo);
			case OnnxValueType.ONNX_TYPE_OPTIONAL:
				return GetOptionalMetadataFromTypeInfo(typeInfo);
			default:
				throw new OnnxRuntimeException(ErrorCode.NotImplemented, $"Value type: '{onnxValueType}' not supported in this code");
			}
		}

		internal static NodeMetadata GetSequenceMetadataFromTypeInfo(IntPtr typeInfo)
		{
			NativeApiStatus.VerifySuccess(NativeMethods.OrtCastTypeInfoToSequenceTypeInfo(typeInfo, out var sequenceTypeInfo));
			if (sequenceTypeInfo == IntPtr.Zero)
			{
				throw new OnnxRuntimeException(ErrorCode.Fail, "TypeInfo cast to SequenceTypeInfo failed. The object does not represent a sequence");
			}
			NativeApiStatus.VerifySuccess(NativeMethods.OrtGetSequenceElementType(sequenceTypeInfo, out var elementTypeInfo));
			try
			{
				NodeMetadata metadataFromTypeInfo = GetMetadataFromTypeInfo(elementTypeInfo);
				SequenceMetadata sequenceMetadata = new SequenceMetadata(metadataFromTypeInfo);
				return new NodeMetadata(sequenceMetadata);
			}
			finally
			{
				NativeMethods.OrtReleaseTypeInfo(elementTypeInfo);
			}
		}

		internal static NodeMetadata GetMapMetadataFromTypeInfo(IntPtr typeInfo)
		{
			NativeApiStatus.VerifySuccess(NativeMethods.OrtCastTypeInfoToMapTypeInfo(typeInfo, out var mapTypeInfo));
			if (mapTypeInfo == IntPtr.Zero)
			{
				throw new OnnxRuntimeException(ErrorCode.Fail, "TypeInfo cast to MapTypeInfo failed. The object does not represent a map");
			}
			NativeApiStatus.VerifySuccess(NativeMethods.OrtGetMapKeyType(mapTypeInfo, out var tensorElementType));
			NativeApiStatus.VerifySuccess(NativeMethods.OrtGetMapValueType(mapTypeInfo, out var type_info));
			try
			{
				NodeMetadata metadataFromTypeInfo = GetMetadataFromTypeInfo(type_info);
				MapMetadata mapMetadata = new MapMetadata((TensorElementType)(int)tensorElementType, metadataFromTypeInfo);
				return new NodeMetadata(mapMetadata);
			}
			finally
			{
				NativeMethods.OrtReleaseTypeInfo(type_info);
			}
		}

		internal static NodeMetadata GetOptionalMetadataFromTypeInfo(IntPtr typeInfo)
		{
			NativeApiStatus.VerifySuccess(NativeMethods.OrtCastTypeInfoToOptionalTypeInfo(typeInfo, out var optionalTypeInfo));
			if (optionalTypeInfo == IntPtr.Zero)
			{
				throw new OnnxRuntimeException(ErrorCode.Fail, "TypeInfo cast to OptionalTypeInfo failed. The object does not represent a optional value");
			}
			NativeApiStatus.VerifySuccess(NativeMethods.OrtGetOptionalContainedTypeInfo(optionalTypeInfo, out var containedTypeInfo));
			try
			{
				NodeMetadata metadataFromTypeInfo = GetMetadataFromTypeInfo(containedTypeInfo);
				OptionalMetadata optMetadata = new OptionalMetadata(metadataFromTypeInfo);
				return new NodeMetadata(optMetadata);
			}
			finally
			{
				NativeMethods.OrtReleaseTypeInfo(containedTypeInfo);
			}
		}

		internal static NodeMetadata GetTensorNodeMetadata(OnnxValueType valueType, IntPtr typeInfo)
		{
			NativeApiStatus.VerifySuccess(NativeMethods.OrtCastTypeInfoToTensorInfo(typeInfo, out var typeAndShapeInfo));
			if (typeAndShapeInfo == IntPtr.Zero)
			{
				throw new OnnxRuntimeException(ErrorCode.Fail, "TypeInfo cast to TensorTypeInfo failed. The object does not represent a tensor");
			}
			NativeApiStatus.VerifySuccess(NativeMethods.OrtGetTensorElementType(typeAndShapeInfo, out var output));
			TensorElementType elementType = (TensorElementType)(int)output;
			NativeApiStatus.VerifySuccess(NativeMethods.OrtGetDimensionsCount(typeAndShapeInfo, out var output2));
			long[] array = new long[(uint)output2];
			NativeApiStatus.VerifySuccess(NativeMethods.OrtGetDimensions(typeAndShapeInfo, array, output2));
			int[] array2 = new int[(uint)output2];
			for (int i = 0; (long)i < (long)(ulong)output2; i++)
			{
				array2[i] = (int)array[i];
			}
			IntPtr[] array3 = new IntPtr[(uint)output2];
			NativeApiStatus.VerifySuccess(NativeMethods.OrtGetSymbolicDimensions(typeAndShapeInfo, array3, output2));
			string[] array4 = new string[(uint)output2];
			for (int j = 0; j < (int)(uint)output2; j++)
			{
				array4[j] = NativeOnnxValueHelper.StringFromNativeUtf8(array3[j]);
			}
			TensorTypeAndShape typeAndShape = new TensorTypeAndShape(elementType, array2, array4);
			return new NodeMetadata(valueType, typeAndShape);
		}

		~InferenceSession()
		{
			Dispose(disposing: false);
		}

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

		protected virtual void Dispose(bool disposing)
		{
			if (!_disposed)
			{
				DisposeImpl(disposing);
			}
		}

		private void DisposeImpl(bool disposing)
		{
			if (disposing)
			{
				if (_namesMemoryPtrs != null)
				{
					foreach (IntPtr namesMemoryPtr in _namesMemoryPtrs)
					{
						Marshal.FreeHGlobal(namesMemoryPtr);
					}
					_namesMemoryPtrs = null;
				}
				if (_builtInSessionOptions != null)
				{
					_builtInSessionOptions.Dispose();
					_builtInSessionOptions = null;
				}
				if (_builtInRunOptions != null)
				{
					_builtInRunOptions.Dispose();
					_builtInRunOptions = null;
				}
			}
			if (_nativeHandle != IntPtr.Zero)
			{
				NativeMethods.OrtReleaseSession(_nativeHandle);
				_nativeHandle = IntPtr.Zero;
			}
			_disposed = true;
		}
	}
	public class TensorTypeAndShape
	{
		public TensorElementType ElementDataType { get; }

		public int[] Dimensions { get; }

		public string[] SymbolicDimensions { get; }

		public TensorElementTypeInfo ElementTypeInfo { get; }

		internal TensorTypeAndShape(TensorElementType elementType, int[] dimensions, string[] symbolicDimensions)
		{
			ElementTypeInfo = TensorBase.GetElementTypeInfo(elementType);
			if (ElementTypeInfo == null)
			{
				throw new OnnxRuntimeException(ErrorCode.InvalidArgument, "Unregistered TensorElementType value of: " + elementType);
			}
			ElementDataType = elementType;
			Dimensions = dimensions;
			SymbolicDimensions = symbolicDimensions;
		}
	}
	public class SequenceMetadata
	{
		public NodeMetadata ElementMeta { get; }

		internal SequenceMetadata(NodeMetadata elementData)
		{
			ElementMeta = elementData;
		}
	}
	public class OptionalMetadata
	{
		public NodeMetadata ElementMeta { get; }

		internal OptionalMetadata(NodeMetadata elementData)
		{
			ElementMeta = elementData;
		}
	}
	public class MapMetadata
	{
		public TensorElementType KeyDataType { get; }

		public NodeMetadata ValueMetadata { get; }

		internal MapMetadata(TensorElementType keyDataType, NodeMetadata valueMetadata)
		{
			KeyDataType = keyDataType;
			ValueMetadata = valueMetadata;
		}
	}
	public class NodeMetadata
	{
		private readonly object _metadata;

		public OnnxValueType OnnxValueType { get; }

		internal IntPtr ZeroTerminatedName { get; set; }

		public int[] Dimensions
		{
			get
			{
				CheckTensor();
				return (_metadata as TensorTypeAndShape).Dimensions;
			}
		}

		public string[] SymbolicDimensions
		{
			get
			{
				CheckTensor();
				return (_metadata as TensorTypeAndShape).SymbolicDimensions;
			}
		}

		public Type ElementType
		{
			get
			{
				CheckTensor();
				return (_metadata as TensorTypeAndShape).ElementTypeInfo.TensorType;
			}
		}

		public TensorElementType ElementDataType
		{
			get
			{
				CheckTensor();
				return (_metadata as TensorTypeAndShape).ElementDataType;
			}
		}

		public bool IsString
		{
			get
			{
				CheckTensor();
				return (_metadata as TensorTypeAndShape).ElementTypeInfo.IsString;
			}
		}

		public bool IsTensor => OnnxValueType == OnnxValueType.ONNX_TYPE_TENSOR || OnnxValueType == OnnxValueType.ONNX_TYPE_SPARSETENSOR;

		internal NodeMetadata(OnnxValueType onnxValueType, TensorTypeAndShape typeAndShape)
		{
			OnnxValueType = onnxValueType;
			CheckTensor();
			_metadata = typeAndShape;
		}

		internal NodeMetadata(MapMetadata mapMetadata)
		{
			OnnxValueType = OnnxValueType.ONNX_TYPE_MAP;
			_metadata = mapMetadata;
		}

		internal NodeMetadata(SequenceMetadata sequenceMetadata)
		{
			OnnxValueType = OnnxValueType.ONNX_TYPE_SEQUENCE;
			_metadata = sequenceMetadata;
		}

		internal NodeMetadata(OptionalMetadata optMetadata)
		{
			OnnxValueType = OnnxValueType.ONNX_TYPE_OPTIONAL;
			_metadata = optMetadata;
		}

		private void CheckTensor()
		{
			if (!IsTensor)
			{
				throw new OnnxRuntimeException(ErrorCode.Fail, "OnnxValueType must either be a tensor or sparse tensor");
			}
		}

		public MapMetadata AsMapMetadata()
		{
			if (OnnxValueType != OnnxValueType.ONNX_TYPE_MAP)
			{
				throw new OnnxRuntimeException(ErrorCode.Fail, "Instance does not contain Map metadata");
			}
			return _metadata as MapMetadata;
		}

		public SequenceMetadata AsSequenceMetadata()
		{
			if (OnnxValueType != OnnxValueType.ONNX_TYPE_SEQUENCE)
			{
				throw new OnnxRuntimeException(ErrorCode.Fail, "Instance does not contain Sequence metadata");
			}
			return _metadata as SequenceMetadata;
		}

		public OptionalMetadata AsOptionalMetadata()
		{
			if (OnnxValueType != OnnxValueType.ONNX_TYPE_OPTIONAL)
			{
				throw new OnnxRuntimeException(ErrorCode.Fail, "Instance does not contain Optional metadata");
			}
			return _metadata as OptionalMetadata;
		}
	}
	public class ModelMetadata
	{
		private string _producerName;

		private string _graphName;

		private string _domain;

		private string _description;

		private string _graphDescription;

		private long _version;

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

		public string ProducerName => _producerName;

		public string GraphName => _graphName;

		public string Domain => _domain;

		public string Description => _description;

		public string GraphDescription => _graphDescription;

		public long Version => _version;

		public Dictionary<string, string> CustomMetadataMap => _customMetadataMap;

		internal unsafe ModelMetadata(InferenceSession session)
		{
			OrtAllocator defaultInstance = OrtAllocator.DefaultInstance;
			NativeApiStatus.VerifySuccess(NativeMethods.OrtSessionGetModelMetadata(session.Handle, out var modelMetadata));
			try
			{
				NativeApiStatus.VerifySuccess(NativeMethods.OrtModelMetadataGetProducerName(modelMetadata, defaultInstance.Pointer, out var value));
				_producerName = NativeOnnxValueHelper.StringFromNativeUtf8(value, defaultInstance);
				NativeApiStatus.VerifySuccess(NativeMethods.OrtModelMetadataGetGraphName(modelMetadata, defaultInstance.Pointer, out var value2));
				_graphName = NativeOnnxValueHelper.StringFromNativeUtf8(value2, defaultInstance);
				NativeApiStatus.VerifySuccess(NativeMethods.OrtModelMetadataGetDomain(modelMetadata, defaultInstance.Pointer, out var value3));
				_domain = NativeOnnxValueHelper.StringFromNativeUtf8(value3, defaultInstance);
				NativeApiStatus.VerifySuccess(NativeMethods.OrtModelMetadataGetDescription(modelMetadata, defaultInstance.Pointer, out var value4));
				_description = NativeOnnxValueHelper.StringFromNativeUtf8(value4, defaultInstance);
				NativeApiStatus.VerifySuccess(NativeMethods.OrtModelMetadataGetGraphDescription(modelMetadata, defaultInstance.Pointer, out var value5));
				_graphDescription = NativeOnnxValueHelper.StringFromNativeUtf8(value5, defaultInstance);
				NativeApiStatus.VerifySuccess(NativeMethods.OrtModelMetadataGetVersion(modelMetadata, out _version));
				NativeApiStatus.VerifySuccess(NativeMethods.OrtModelMetadataGetCustomMetadataMapKeys(modelMetadata, defaultInstance.Pointer, out var keys, out var numKeys));
				try
				{
					Span<IntPtr> span = new Span<IntPtr>(keys.ToPointer(), (int)numKeys);
					using DisposableList<OrtMemoryAllocation> disposableList = new DisposableList<OrtMemoryAllocation>((int)numKeys);
					Span<IntPtr> span2 = span;
					for (int i = 0; i < span2.Length; i++)
					{
						IntPtr pointer = span2[i];
						disposableList.Add(new OrtMemoryAllocation(defaultInstance, pointer, 0u));
					}
					Span<IntPtr> span3 = span;
					for (int j = 0; j < span3.Length; j++)
					{
						IntPtr intPtr = span3[j];
						NativeApiStatus.VerifySuccess(NativeMethods.OrtModelMetadataLookupCustomMetadataMap(modelMetadata, defaultInstance.Pointer, intPtr, out var value6));
						string value7 = NativeOnnxValueHelper.StringFromNativeUtf8(value6, defaultInstance);
						string key = NativeOnnxValueHelper.StringFromNativeUtf8(intPtr);
						_customMetadataMap[key] = value7;
					}
				}
				finally
				{
					defaultInstance.FreeMemory(keys);
				}
			}
			finally
			{
				NativeMethods.OrtReleaseModelMetadata(modelMetadata);
			}
		}
	}
	internal class ManagedTypeProjection
	{
		internal static OrtValue CreateProjection(NamedOnnxValue namedOnnxValue, NodeMetadata metadata)
		{
			NodeMetadata nodeMetadata = metadata;
			if (metadata.OnnxValueType == OnnxValueType.ONNX_TYPE_OPTIONAL)
			{
				nodeMetadata = metadata.AsOptionalMetadata().ElementMeta;
			}
			if (namedOnnxValue.ValueType != nodeMetadata.OnnxValueType)
			{
				throw new OnnxRuntimeException(ErrorCode.RuntimeException, $"NamedOnnxValue: {namedOnnxValue.Name} has value type: {namedOnnxValue.ValueType}" + $" expected: {nodeMetadata.OnnxValueType} after optional type adjustment");
			}
			return namedOnnxValue.ValueType switch
			{
				OnnxValueType.ONNX_TYPE_TENSOR => CreateTensorProjection(namedOnnxValue, nodeMetadata), 
				OnnxValueType.ONNX_TYPE_SEQUENCE => CreateSequenceProjection(namedOnnxValue, nodeMetadata), 
				OnnxValueType.ONNX_TYPE_MAP => CreateMapProjection(namedOnnxValue, nodeMetadata), 
				_ => throw new OnnxRuntimeException(ErrorCode.InvalidArgument, "ManagedTypeProjection can only project tensors, sequences, maps and optional types"), 
			};
		}

		private static OrtValue CreateSequenceProjection(NamedOnnxValue namedOnnxValue, NodeMetadata metadata)
		{
			NodeMetadata elementMeta = metadata.AsSequenceMetadata().ElementMeta;
			OnnxValueType onnxValueType = elementMeta.OnnxValueType;
			IEnumerable<NamedOnnxValue> enumerable = namedOnnxValue.AsEnumerable<NamedOnnxValue>() ?? throw new OnnxRuntimeException(ErrorCode.InvalidArgument, "NamedOnnxValue: " + namedOnnxValue.Name + " sequence does not contain NamedOnnxValue elements");
			int count = 0;
			if (enumerable is ICollection<NamedOnnxValue> collection)
			{
				count = collection.Count;
			}
			DisposableList<OrtValue> compositeMembers = new DisposableList<OrtValue>(count);
			try
			{
				foreach (NamedOnnxValue item in enumerable)
				{
					if (onnxValueType != item.ValueType)
					{
						throw new OnnxRuntimeException(ErrorCode.InvalidArgument, $"NamedOnnxValue: {namedOnnxValue.Name} sequence element expected to be {onnxValueType}, received {item.ValueType}");
					}
					compositeMembers.Add(CreateProjection(item, elementMeta));
				}
				return OrtValue.CreateSequence(ref compositeMembers);
			}
			catch (Exception)
			{
				compositeMembers?.Dispose();
				throw;
			}
		}

		private static OrtValue CreateMapProjection(NamedOnnxValue node, NodeMetadata elementMeta)
		{
			MapMetadata mapMetadata = elementMeta.AsMapMetadata();
			NodeMetadata valueMetadata = mapMetadata.ValueMetadata;
			if (valueMetadata.OnnxValueType != OnnxValueType.ONNX_TYPE_TENSOR)
			{
				throw new OnnxRuntimeException(ErrorCode.InvalidArgument, "Node: " + node.Name + " onnxruntime only supports maps with primitive types values");
			}
			Span<OrtValue> disposables = new OrtValue[2];
			DisposableArray<OrtValue> disposableArray = new DisposableArray<OrtValue>(disposables);
			try
			{
				TensorBase dictionaryKeys = node.GetDictionaryKeys();
				disposables[0] = OrtValue.CreateFromTensorObject(dictionaryKeys, out var elementType);
				if (elementType != mapMetadata.KeyDataType)
				{
					throw new OnnxRuntimeException(ErrorCode.InvalidArgument, $"Map key data type supplied: {elementType} metadata expected: {mapMetadata.KeyDataType}");
				}
				TensorBase dictionaryValues = node.GetDictionaryValues();
				disposables[1] = OrtValue.CreateFromTensorObject(dictionaryValues, out var elementType2);
				if (elementType2 != valueMetadata.ElementDataType)
				{
					throw new OnnxRuntimeException(ErrorCode.InvalidArgument, $"Map value data type supplied: {elementType2} metadata expected: {valueMetadata.ElementDataType}");
				}
				return OrtValue.CreateMap(ref disposables[0], ref disposables[1]);
			}
			catch (Exception)
			{
				disposableArray.Dispose();
				throw;
			}
		}

		private static OrtValue CreateTensorProjection(NamedOnnxValue node, NodeMetadata elementMeta)
		{
			if (!(node.Value is TensorBase))
			{
				throw new OnnxRuntimeException(ErrorCode.InvalidArgument, $"NamedOnnxValue contains: {node.Value.GetType()}, expecting a Tensor<T>");
			}
			TensorElementType elementType;
			OrtValue ortValue = OrtValue.CreateFromTensorObject(node.Value as TensorBase, out elementType);
			try
			{
				if (elementType != elementMeta.ElementDataType)
				{
					throw new OnnxRuntimeException(ErrorCode.InvalidArgument, $"Tensor element data type discovered: {elementType} metadata expected: {elementMeta.ElementDataType}");
				}
			}
			catch (Exception)
			{
				ortValue.Dispose();
				throw;
			}
			return ortValue;
		}
	}
	internal class MapHelper
	{
		internal TensorBase Keys { get; }

		internal TensorBase Values { get; }

		internal MapHelper(TensorBase keys, TensorBase values)
		{
			Keys = keys;
			Values = values;
		}
	}
	public class NamedOnnxValue
	{
		private object _value;

		private string _name;

		private MapHelper _mapHelper;

		public OnnxValueType ValueType { get; internal set; }

		public string Name
		{
			get
			{
				return _name;
			}
			set
			{
				_name = value;
			}
		}

		public object Value
		{
			get
			{
				return _value;
			}
			set
			{
				_value = value;
			}
		}

		[Obsolete("Use constructors with valueType or static factory methods")]
		protected NamedOnnxValue(string name, object value)
		{
			_name = name;
			_value = value;
			ValueType = OnnxValueType.ONNX_TYPE_UNKNOWN;
		}

		internal NamedOnnxValue(string name, object value, OnnxValueType valueType)
		{
			_name = name;
			_value = value;
			ValueType = valueType;
			if (valueType == OnnxValueType.ONNX_TYPE_MAP)
			{
				throw new OnnxRuntimeException(ErrorCode.InvalidArgument, "Use another __ctor for maps");
			}
		}

		internal NamedOnnxValue(string name, object value, MapHelper helper)
		{
			_name = name;
			_value = value;
			ValueType = OnnxValueType.ONNX_TYPE_MAP;
			_mapHelper = helper;
		}

		public static NamedOnnxValue CreateFromTensor<T>(string name, Tensor<T> value)
		{
			return new NamedOnnxValue(name, value, OnnxValueType.ONNX_TYPE_TENSOR);
		}

		public static NamedOnnxValue CreateFromSequence<T>(string name, IEnumerable<T> value)
		{
			return new NamedOnnxValue(name, value, OnnxValueType.ONNX_TYPE_SEQUENCE);
		}

		public static NamedOnnxValue CreateFromMap<K, V>(string name, IDictionary<K, V> value)
		{
			return CreateFromMap(name, value.Keys, value.Values);
		}

		internal static NamedOnnxValue CreateFromMap<K, V>(string name, ICollection<K> keys, ICollection<V> values)
		{
			DenseTensor<K> keys2 = new DenseTensor<K>(keys.ToArray(), new int[1] { keys.Count });
			DenseTensor<V> values2 = new DenseTensor<V>(values.ToArray(), new int[1] { values.Count });
			return new NamedOnnxValue(name, values, new MapHelper(keys2, values2));
		}

		public Tensor<T> AsTensor<T>()
		{
			return _value as Tensor<T>;
		}

		public IEnumerable<T> AsEnumerable<T>()
		{
			return _value as IEnumerable<T>;
		}

		public IDictionary<K, V> AsDictionary<K, V>()
		{
			return _value as IDictionary<K, V>;
		}

		internal virtual IntPtr InputToOrtValueHandle(NodeMetadata metadata, out IDisposable memoryOwner)
		{
			return ((OrtValue)(memoryOwner = ManagedTypeProjection.CreateProjection(this, metadata))).Handle;
		}

		internal virtual IntPtr OutputToOrtValueHandle(NodeMetadata metadata, out IDisposable memoryOwner)
		{
			if (metadata.OnnxValueType == OnnxValueType.ONNX_TYPE_TENSOR)
			{
				return ((OrtValue)(memoryOwner = ManagedTypeProjection.CreateProjection(this, metadata))).Handle;
			}
			if (metadata.OnnxValueType == OnnxValueType.ONNX_TYPE_OPTIONAL)
			{
				NodeMetadata elementMeta = metadata.AsOptionalMetadata().ElementMeta;
				if (elementMeta.OnnxValueType == OnnxValueType.ONNX_TYPE_TENSOR)
				{
					return ((OrtValue)(memoryOwner = ManagedTypeProjection.CreateProjection(this, metadata))).Handle;
				}
			}
			throw new OnnxRuntimeException(ErrorCode.NotImplemented, $"Can not create output OrtValue for NamedOnnxValue '{metadata.OnnxValueType}' type." + " Only tensors can be pre-allocated for outputs  Use Run() overloads that return DisposableNamedOnnxValue to get access to all Onnx value types that may be returned as output.");
		}

		internal TensorBase GetDictionaryKeys()
		{
			if (ValueType != OnnxValueType.ONNX_TYPE_MAP)
			{
				throw new OnnxRuntimeException(ErrorCode.Fail, "This NamedOnnxValue instance does not contain a dictionary");
			}
			return _mapHelper.Keys;
		}

		internal TensorBase GetDictionaryValues()
		{
			if (ValueType != OnnxValueType.ONNX_TYPE_MAP)
			{
				throw new OnnxRuntimeException(ErrorCode.Fail, "This NamedOnnxValue instance does not contain a dictionary");
			}
			return _mapHelper.Values;
		}
	}
	internal class NativeApiStatus
	{
		private static string GetErrorMessage(IntPtr status)
		{
			IntPtr nativeUtf = NativeMethods.OrtGetErrorMessage(status);
			return NativeOnnxValueHelper.StringFromNativeUtf8(nativeUtf);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void VerifySuccess(IntPtr nativeStatus)
		{
			if (nativeStatus != IntPtr.Zero)
			{
				try
				{
					ErrorCode errorCode = NativeMethods.OrtGetErrorCode(nativeStatus);
					string errorMessage = GetErrorMessage(nativeStatus);
					throw new OnnxRuntimeException(errorCode, errorMessage);
				}
				finally
				{
					NativeMethods.OrtReleaseStatus(nativeStatus);
				}
			}
		}
	}
	public struct OrtApiBase
	{
		public IntPtr GetApi;

		public IntPtr GetVersionString;
	}
	public struct OrtApi
	{
		public IntPtr CreateStatus;

		public IntPtr GetErrorCode;

		public IntPtr GetErrorMessage;

		public IntPtr CreateEnv;

		public IntPtr CreateEnvWithCustomLogger;

		public IntPtr EnableTelemetryEvents;

		public IntPtr DisableTelemetryEvents;

		public IntPtr CreateSession;

		public IntPtr CreateSessionFromArray;

		public IntPtr Run;

		public IntPtr CreateSessionOptions;

		public IntPtr SetOptimizedModelFilePath;

		public IntPtr CloneSessionOptions;

		public IntPtr SetSessionExecutionMode;

		public IntPtr EnableProfiling;

		public IntPtr DisableProfiling;

		public IntPtr EnableMemPattern;

		public IntPtr DisableMemPattern;

		public IntPtr EnableCpuMemArena;

		public IntPtr DisableCpuMemArena;

		public IntPtr SetSessionLogId;

		public IntPtr SetSessionLogVerbosityLevel;

		public IntPtr SetSessionLogSeverityLevel;

		public IntPtr SetSessionGraphOptimizationLevel;

		public IntPtr SetIntraOpNumThreads;

		public IntPtr SetInterOpNumThreads;

		public IntPtr CreateCustomOpDomain;

		public IntPtr CustomOpDomain_Add;

		public IntPtr AddCustomOpDomain;

		public IntPtr RegisterCustomOpsLibrary;

		public IntPtr SessionGetInputCount;

		public IntPtr SessionGetOutputCount;

		public IntPtr SessionGetOverridableInitializerCount;

		public IntPtr SessionGetInputTypeInfo;

		public IntPtr SessionGetOutputTypeInfo;

		public IntPtr SessionGetOverridableInitializerTypeInfo;

		public IntPtr SessionGetInputName;

		public IntPtr SessionGetOutputName;

		public IntPtr SessionGetOverridableInitializerName;

		public IntPtr CreateRunOptions;

		public IntPtr RunOptionsSetRunLogVerbosityLevel;

		public IntPtr RunOptionsSetRunLogSeverityLevel;

		public IntPtr RunOptionsSetRunTag;

		public IntPtr RunOptionsGetRunLogVerbosityLevel;

		public IntPtr RunOptionsGetRunLogSeverityLevel;

		public IntPtr RunOptionsGetRunTag;

		public IntPtr RunOptionsSetTerminate;

		public IntPtr RunOptionsUnsetTerminate;

		public IntPtr CreateTensorAsOrtValue;

		public IntPtr CreateTensorWithDataAsOrtValue;

		public IntPtr IsTensor;

		public IntPtr GetTensorMutableData;

		public IntPtr FillStringTensor;

		public IntPtr GetStringTensorDataLength;

		public IntPtr GetStringTensorContent;

		public IntPtr CastTypeInfoToTensorInfo;

		public IntPtr GetOnnxTypeFromTypeInfo;

		public IntPtr CreateTensorTypeAndShapeInfo;

		public IntPtr SetTensorElementType;

		public IntPtr SetDimensions;

		public IntPtr GetTensorElementType;

		public IntPtr GetDimensionsCount;

		public IntPtr GetDimensions;

		public IntPtr GetSymbolicDimensions;

		public IntPtr GetTensorShapeElementCount;

		public IntPtr GetTensorTypeAndShape;

		public IntPtr GetTypeInfo;

		public IntPtr GetValueType;

		public IntPtr CreateMemoryInfo;

		public IntPtr CreateCpuMemoryInfo;

		public IntPtr CompareMemoryInfo;

		public IntPtr MemoryInfoGetName;

		public IntPtr MemoryInfoGetId;

		public IntPtr MemoryInfoGetMemType;

		public IntPtr MemoryInfoGetType;

		public IntPtr AllocatorAlloc;

		public IntPtr AllocatorFree;

		public IntPtr AllocatorGetInfo;

		public IntPtr GetAllocatorWithDefaultOptions;

		public IntPtr AddFreeDimensionOverride;

		public IntPtr GetValue;

		public IntPtr GetValueCount;

		public IntPtr CreateValue;

		public IntPtr CreateOpaqueValue;

		public IntPtr GetOpaqueValue;

		public IntPtr KernelInfoGetAttribute_float;

		public IntPtr KernelInfoGetAttribute_int64;

		public IntPtr KernelInfoGetAttribute_string;

		public IntPtr KernelContext_GetInputCount;

		public IntPtr KernelContext_GetOutputCount;

		public IntPtr KernelContext_GetInput;

		public IntPtr KernelContext_GetOutput;

		public IntPtr ReleaseEnv;

		public IntPtr ReleaseStatus;

		public IntPtr ReleaseMemoryInfo;

		public IntPtr ReleaseSession;

		public IntPtr ReleaseValue;

		public IntPtr ReleaseRunOptions;

		public IntPtr ReleaseTypeInfo;

		public IntPtr ReleaseTensorTypeAndShapeInfo;

		public IntPtr ReleaseSessionOptions;

		public IntPtr ReleaseCustomOpDomain;

		public IntPtr GetDenotationFromTypeInfo;

		public IntPtr CastTypeInfoToMapTypeInfo;

		public IntPtr CastTypeInfoToSequenceTypeInfo;

		public IntPtr GetMapKeyType;

		public IntPtr GetMapValueType;

		public IntPtr GetSequenceElementType;

		public IntPtr ReleaseMapTypeInfo;

		public IntPtr ReleaseSequenceTypeInfo;

		public IntPtr SessionEndProfiling;

		public IntPtr SessionGetModelMetadata;

		public IntPtr ModelMetadataGetProducerName;

		public IntPtr ModelMetadataGetGraphName;

		public IntPtr ModelMetadataGetDomain;

		public IntPtr ModelMetadataGetDescription;

		public IntPtr ModelMetadataLookupCustomMetadataMap;

		public IntPtr ModelMetadataGetVersion;

		public IntPtr ReleaseModelMetadata;

		public IntPtr CreateEnvWithGlobalThreadPools;

		public IntPtr DisablePerSessionThreads;

		public IntPtr CreateThreadingOptions;

		public IntPtr ReleaseThreadingOptions;

		public IntPtr ModelMetadataGetCustomMetadataMapKeys;

		public IntPtr AddFreeDimensionOverrideByName;

		public IntPtr GetAvailableProviders;

		public IntPtr ReleaseAvailableProviders;

		public IntPtr GetStringTensorElementLength;

		public IntPtr GetStringTensorElement;

		public IntPtr FillStringTensorElement;

		public IntPtr AddSessionConfigEntry;

		public IntPtr CreateAllocator;

		public IntPtr ReleaseAllocator;

		public IntPtr RunWithBinding;

		public IntPtr CreateIoBinding;

		public IntPtr ReleaseIoBinding;

		public IntPtr BindInput;

		public IntPtr BindOutput;

		public IntPtr BindOutputToDevice;

		public IntPtr GetBoundOutputNames;

		public IntPtr GetBoundOutputValues;

		public IntPtr ClearBoundInputs;

		public IntPtr ClearBoundOutputs;

		public IntPtr TensorAt;

		public IntPtr CreateAndRegisterAllocator;

		public IntPtr SetLanguageProjection;

		public IntPtr SessionGetProfilingStartTimeNs;

		public IntPtr SetGlobalIntraOpNumThreads;

		public IntPtr SetGlobalInterOpNumThreads;

		public IntPtr SetGlobalSpinControl;

		public IntPtr AddInitializer;

		public IntPtr CreateEnvWithCustomLoggerAndGlobalThreadPools;

		public IntPtr SessionOptionsAppendExecutionProvider_CUDA;

		public IntPtr SessionOptionsAppendExecutionProvider_ROCM;

		public IntPtr SessionOptionsAppendExecutionProvider_OpenVINO;

		public IntPtr SetGlobalDenormalAsZero;

		public IntPtr CreateArenaCfg;

		public IntPtr ReleaseArenaCfg;

		public IntPtr ModelMetadataGetGraphDescription;

		public IntPtr SessionOptionsAppendExecutionProvider_TensorRT;

		public IntPtr SetCurrentGpuDeviceId;

		public IntPtr GetCurrentGpuDeviceId;

		public IntPtr KernelInfoGetAttributeArray_float;

		public IntPtr KernelInfoGetAttributeArray_int64;

		public IntPtr CreateArenaCfgV2;

		public IntPtr AddRunConfigEntry;

		public IntPtr CreatePrepackedWeightsContainer;

		public IntPtr ReleasePrepackedWeightsContainer;

		public IntPtr CreateSessionWithPrepackedWeightsContainer;

		public IntPtr CreateSessionFromArrayWithPrepackedWeightsContainer;

		public IntPtr SessionOptionsAppendExecutionProvider_TensorRT_V2;

		public IntPtr CreateTensorRTProviderOptions;

		public IntPtr UpdateTensorRTProviderOptions;

		public IntPtr GetTensorRTProviderOptionsAsString;

		public IntPtr ReleaseTensorRTProviderOptions;

		public IntPtr EnableOrtCustomOps;

		public IntPtr RegisterAllocator;

		public IntPtr UnregisterAllocator;

		public IntPtr IsSparseTensor;

		public IntPtr CreateSparseTensorAsOrtValue;

		public IntPtr FillSparseTensorCoo;

		public IntPtr FillSparseTensorCsr;

		public IntPtr FillSparseTensorBlockSparse;

		public IntPtr CreateSparseTensorWithValuesAsOrtValue;

		public IntPtr UseCooIndices;

		public IntPtr UseCsrIndices;

		public IntPtr UseBlockSparseIndices;

		public IntPtr GetSparseTensorFormat;

		public IntPtr GetSparseTensorValuesTypeAndShape;

		public IntPtr GetSparseTensorValues;

		public IntPtr GetSparseTensorIndicesTypeShape;

		public IntPtr GetSparseTensorIndices;

		public IntPtr HasValue;

		public IntPtr KernelContext_GetGPUComputeStream;

		public IntPtr GetTensorMemoryInfo;

		public IntPtr GetExecutionProviderApi;

		public IntPtr SessionOptionsSetCustomCreateThreadFn;

		public IntPtr SessionOptionsSetCustomThreadCreationOptions;

		public IntPtr SessionOptionsSetCustomJoinThreadFn;

		public IntPtr SetGlobalCustomCreateThreadFn;

		public IntPtr SetGlobalCustomThreadCreationOptions;

		public IntPtr SetGlobalCustomJoinThreadFn;

		public IntPtr SynchronizeBoundInputs;

		public IntPtr SynchronizeBoundOutputs;

		public IntPtr SessionOptionsAppendExecutionProvider_CUDA_V2;

		public IntPtr CreateCUDAProviderOptions;

		public IntPtr UpdateCUDAProviderOptions;

		public IntPtr GetCUDAProviderOptionsAsString;

		public IntPtr ReleaseCUDAProviderOptions;

		public IntPtr SessionOptionsAppendExecutionProvider_MIGraphX;

		public IntPtr AddExternalInitializers;

		public IntPtr CreateOpAttr;

		public IntPtr ReleaseOpAttr;

		public IntPtr CreateOp;

		public IntPtr InvokeOp;

		public IntPtr ReleaseOp;

		public IntPtr SessionOptionsAppendExecutionProvider;

		public IntPtr CopyKernelInfo;

		public IntPtr ReleaseKernelInfo;

		public IntPtr GetTrainingApi;

		public IntPtr SessionOptionsAppendExecutionProvider_CANN;

		public IntPtr CreateCANNProviderOptions;

		public IntPtr UpdateCANNProviderOptions;

		public IntPtr GetCANNProviderOptionsAsString;

		public IntPtr ReleaseCANNProviderOptions;

		public IntPtr MemoryInfoGetDeviceType;

		public IntPtr UpdateEnvWithCustomLogLevel;

		public IntPtr SetGlobalIntraOpThreadAffinity;

		public IntPtr RegisterCustomOpsLibrary_V2;

		public IntPtr RegisterCustomOpsUsingFunction;

		public IntPtr KernelInfo_GetInputCount;

		public IntPtr KernelInfo_GetOutputCount;

		public IntPtr KernelInfo_GetInputName;

		public IntPtr KernelInfo_GetOutputName;

		public IntPtr KernelInfo_GetInputTypeInfo;

		public IntPtr KernelInfo_GetOutputTypeInfo;

		public IntPtr KernelInfoGetAttribute_tensor;

		public IntPtr HasSessionConfigEntry;

		public IntPtr GetSessionConfigEntry;

		public IntPtr SessionOptionsAppendExecutionProvider_Dnnl;

		public IntPtr CreateDnnlProviderOptions;

		public IntPtr UpdateDnnlProviderOptions;

		public IntPtr GetDnnlProviderOptionsAsString;

		public IntPtr ReleaseDnnlProviderOptions;

		public IntPtr KernelInfo_GetNodeName;

		public IntPtr KernelInfo_GetLogger;

		public IntPtr KernelContext_GetLogger;

		public IntPtr Logger_LogMessage;

		public IntPtr Logger_GetLoggingSeverityLevel;

		public IntPtr KernelInfoGetConstantInput_tensor;

		public IntPtr CastTypeInfoToOptionalTypeInfo;

		public IntPtr GetOptionalContainedTypeInfo;

		public IntPtr GetResizedStringTensorElementBuffer;

		public IntPtr KernelContext_GetAllocator;

		public IntPtr GetBuildInfoString;

		public IntPtr CreateROCMProviderOptions;

		public IntPtr UpdateROCMProviderOptions;

		public IntPtr GetROCMProviderOptionsAsString;

		public IntPtr ReleaseROCMProviderOptions;

		public IntPtr CreateAndRegisterAllocatorV2;

		public IntPtr RunAsync;
	}
	internal static class NativeMethods
	{
		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate ref OrtApi DOrtGetApi(uint version);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtGetVersionString();

		internal class NativeLib
		{
			internal const string DllName = "onnxruntime";
		}

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtCreateEnv(OrtLoggingLevel defaultLoggingLevel, byte[] logId, out IntPtr env);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtCreateEnvWithCustomLogger(IntPtr loggingFunction, IntPtr loggerParam, OrtLoggingLevel defaultLoggingLevel, byte[] logId, out IntPtr env);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtCreateEnvWithGlobalThreadPools(OrtLoggingLevel defaultWarningLevel, byte[] logId, IntPtr threadingOptions, out IntPtr env);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtCreateEnvWithCustomLoggerAndGlobalThreadPools(IntPtr loggingFunction, IntPtr loggerParam, OrtLoggingLevel logSeverityLevel, byte[] logId, IntPtr threadingOptions, out IntPtr env);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate void DOrtReleaseEnv(IntPtr env);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtEnableTelemetryEvents(IntPtr env);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtDisableTelemetryEvents(IntPtr env);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtUpdateEnvWithCustomLogLevel(IntPtr env, OrtLoggingLevel custom_log_level);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtCreateTensorRTProviderOptions(out IntPtr trtProviderOptionsInstance);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtUpdateTensorRTProviderOptions(IntPtr trtProviderOptionsInstance, IntPtr[] providerOptionsKeys, IntPtr[] providerOptionsValues, UIntPtr numKeys);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtGetTensorRTProviderOptionsAsString(IntPtr trtProviderOptionsInstance, IntPtr allocator, out IntPtr ptr);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate void DOrtReleaseTensorRTProviderOptions(IntPtr trtProviderOptionsInstance);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtCreateCUDAProviderOptions(out IntPtr cudaProviderOptionsInstance);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtUpdateCUDAProviderOptions(IntPtr cudaProviderOptionsInstance, IntPtr[] providerOptionsKeys, IntPtr[] providerOptionsValues, UIntPtr numKeys);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtGetCUDAProviderOptionsAsString(IntPtr cudaProviderOptionsInstance, IntPtr allocator, out IntPtr ptr);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate void DOrtReleaseCUDAProviderOptions(IntPtr cudaProviderOptionsInstance);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtCreateROCMProviderOptions(out IntPtr rocmProviderOptionsInstance);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtUpdateROCMProviderOptions(IntPtr rocmProviderOptionsInstance, IntPtr[] providerOptionsKeys, IntPtr[] providerOptionsValues, UIntPtr numKeys);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtGetROCMProviderOptionsAsString(IntPtr rocmProviderOptionsInstance, IntPtr allocator, out IntPtr ptr);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate void DOrtReleaseROCMProviderOptions(IntPtr rocmProviderOptionsInstance);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate ErrorCode DOrtGetErrorCode(IntPtr status);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtGetErrorMessage(IntPtr status);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate void DOrtReleaseStatus(IntPtr statusPtr);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtCreateSession(IntPtr environment, byte[] modelPath, IntPtr sessopnOptions, out IntPtr session);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtCreateSessionWithPrepackedWeightsContainer(IntPtr environment, byte[] modelPath, IntPtr sessionOptions, IntPtr prepackedWeightsContainer, out IntPtr session);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtCreateSessionFromArray(IntPtr environment, byte[] modelData, UIntPtr modelSize, IntPtr sessionOptions, out IntPtr session);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtCreateSessionFromArrayWithPrepackedWeightsContainer(IntPtr environment, byte[] modelData, UIntPtr modelSize, IntPtr sessionOptions, IntPtr prepackedWeightsContainer, out IntPtr session);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtRun(IntPtr session, IntPtr runOptions, IntPtr[] inputNames, IntPtr[] inputValues, UIntPtr inputCount, IntPtr[] outputNames, UIntPtr outputCount, IntPtr[] outputValues);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtRunWithBinding(IntPtr session, IntPtr runOptions, IntPtr io_binding);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtSessionGetInputCount(IntPtr session, out UIntPtr count);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtSessionGetOutputCount(IntPtr session, out UIntPtr count);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtSessionGetOverridableInitializerCount(IntPtr session, out UIntPtr count);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtSessionGetInputName(IntPtr session, UIntPtr index, IntPtr allocator, out IntPtr name);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtSessionGetOutputName(IntPtr session, UIntPtr index, IntPtr allocator, out IntPtr name);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtSessionEndProfiling(IntPtr session, IntPtr allocator, out IntPtr profile_file);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtSessionGetOverridableInitializerName(IntPtr session, UIntPtr index, IntPtr allocator, out IntPtr name);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtSessionGetInputTypeInfo(IntPtr session, UIntPtr index, out IntPtr typeInfo);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtSessionGetOutputTypeInfo(IntPtr session, UIntPtr index, out IntPtr typeInfo);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtSessionGetOverridableInitializerTypeInfo(IntPtr session, UIntPtr index, out IntPtr typeInfo);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate void DOrtReleaseTypeInfo(IntPtr session);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate void DOrtReleaseSession(IntPtr session);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtSessionGetProfilingStartTimeNs(IntPtr session, out UIntPtr startTime);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DCreateAndRegisterAllocatorV2(IntPtr environment, IntPtr provider_type, IntPtr mem_info, IntPtr arena_cfg, IntPtr provider_options_keys, IntPtr provider_options_values, UIntPtr num_keys);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtRunAsync(IntPtr session, IntPtr runOptions, IntPtr[] inputNames, IntPtr[] inputValues, UIntPtr inputCount, IntPtr[] outputNames, UIntPtr outputCount, IntPtr[] outputValues, IntPtr callback, IntPtr user_data);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtCreateSessionOptions(out IntPtr sessionOptions);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate void DOrtReleaseSessionOptions(IntPtr session);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtCloneSessionOptions(IntPtr sessionOptions, out IntPtr output);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtSetSessionExecutionMode(IntPtr options, ExecutionMode execution_mode);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtSetOptimizedModelFilePath(IntPtr options, byte[] optimizedModelFilepath);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtEnableProfiling(IntPtr options, byte[] profilePathPrefix);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtDisableProfiling(IntPtr options);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtEnableMemPattern(IntPtr options);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtDisableMemPattern(IntPtr options);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtEnableCpuMemArena(IntPtr options);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtDisableCpuMemArena(IntPtr options);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtSetSessionLogId(IntPtr options, byte[] logId);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtSetSessionLogVerbosityLevel(IntPtr options, int sessionLogVerbosityLevel);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtSetSessionLogSeverityLevel(IntPtr options, OrtLoggingLevel sessionLogSeverityLevel);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtSetIntraOpNumThreads(IntPtr options, int intraOpNumThreads);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtSetInterOpNumThreads(IntPtr options, int interOpNumThreads);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtSetSessionGraphOptimizationLevel(IntPtr options, GraphOptimizationLevel graphOptimizationLevel);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtAddSessionConfigEntry(IntPtr options, byte[] configKey, byte[] configValue);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DSessionOptionsAppendExecutionProvider_TensorRT(IntPtr options, IntPtr trtProviderOptions);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DSessionOptionsAppendExecutionProvider_TensorRT_V2(IntPtr options, IntPtr trtProviderOptions);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DSessionOptionsAppendExecutionProvider_CUDA(IntPtr options, IntPtr cudaProviderOptions);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DSessionOptionsAppendExecutionProvider_CUDA_V2(IntPtr options, IntPtr cudaProviderOptions);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DSessionOptionsAppendExecutionProvider_ROCM(IntPtr options, IntPtr rocmProviderOptions);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtAddFreeDimensionOverride(IntPtr options, byte[] dimDenotation, long dimValue);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtAddFreeDimensionOverrideByName(IntPtr options, byte[] dimName, long dimValue);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtRegisterCustomOpsLibrary(IntPtr options, byte[] libraryPath, out IntPtr libraryHandle);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtRegisterCustomOpsLibrary_V2(IntPtr options, byte[] libraryPath);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtAddInitializer(IntPtr options, byte[] name, IntPtr ortValue);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DSessionOptionsAppendExecutionProvider(IntPtr options, byte[] providerName, IntPtr[] providerOptionsKeys, IntPtr[] providerOptionsValues, UIntPtr numKeys);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtCreateRunOptions(out IntPtr runOptions);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate void DOrtReleaseRunOptions(IntPtr options);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtRunOptionsSetRunLogVerbosityLevel(IntPtr options, int value);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtRunOptionsSetRunLogSeverityLevel(IntPtr options, OrtLoggingLevel value);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtRunOptionsSetRunTag(IntPtr options, byte[] runTag);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtRunOptionsGetRunLogVerbosityLevel(IntPtr options, out int verbosityLevel);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtRunOptionsGetRunLogSeverityLevel(IntPtr options, out OrtLoggingLevel severityLevel);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtRunOptionsGetRunTag(IntPtr options, out IntPtr runtag);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtRunOptionsSetTerminate(IntPtr options);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtRunOptionsUnsetTerminate(IntPtr options);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtAddRunConfigEntry(IntPtr options, byte[] configKey, byte[] configValue);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtCreateThreadingOptions(out IntPtr threadingOptions);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtReleaseThreadingOptions(IntPtr threadingOptions);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtThreadingOptionsSetGlobalInterOpNumThreads(IntPtr threadingOptions, int numThreads);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtThreadingOptionsSetGlobalIntraOpNumThreads(IntPtr threadingOptions, int numThreads);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtThreadingOptionsSetGlobalDenormalAsZero(IntPtr threadingOptions);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtThreadingOptionsSetGlobalSpinControl(IntPtr threadingOptions, int allowSpinning);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtCreateMemoryInfo(byte[] name, OrtAllocatorType allocatorType, int identifier, OrtMemType memType, out IntPtr allocatorInfo);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtCreateCpuMemoryInfo(OrtAllocatorType allocatorType, OrtMemType memoryType, out IntPtr allocatorInfo);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate void DOrtReleaseMemoryInfo(IntPtr allocatorInfo);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtCompareMemoryInfo(IntPtr info1, IntPtr info2, out int result);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtMemoryInfoGetName(IntPtr mem_info, out IntPtr name);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtMemoryInfoGetId(IntPtr mem_info, out int id);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtMemoryInfoGetMemType(IntPtr mem_info, out OrtMemType mem_type);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtMemoryInfoGetType(IntPtr mem_info, out OrtAllocatorType alloc_type);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtGetAllocatorWithDefaultOptions(out IntPtr allocator);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtAllocatorGetInfo(IntPtr ptr, out IntPtr info);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtCreateArenaCfg(UIntPtr maxMemory, int arenaExtendStrategy, int initialChunkSizeBytes, int maxDeadBytesPerChunk, out IntPtr arenaCfg);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate void DOrtReleaseArenaCfg(IntPtr arenaCfg);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtCreateAllocator(IntPtr session, IntPtr info, out IntPtr allocator);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate void DOrtReleaseAllocator(IntPtr allocator);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtAllocatorAlloc(IntPtr allocator, UIntPtr size, out IntPtr p);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtAllocatorFree(IntPtr allocator, IntPtr p);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtCreateIoBinding(IntPtr session, out IntPtr io_binding);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate void DOrtReleaseIoBinding(IntPtr io_binding);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtBindInput(IntPtr io_binding, byte[] name, IntPtr ort_value);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtSynchronizeBoundInputs(IntPtr io_binding);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtBindOutput(IntPtr io_binding, byte[] name, IntPtr ort_value);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtBindOutputToDevice(IntPtr io_binding, byte[] name, IntPtr mem_info);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtSynchronizeBoundOutputs(IntPtr io_binding);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtGetBoundOutputNames(IntPtr io_binding, IntPtr allocator, out IntPtr buffer, out IntPtr lengths, out UIntPtr count);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtGetBoundOutputValues(IntPtr io_binding, IntPtr allocator, out IntPtr ortvalues, out UIntPtr count);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate void DOrtClearBoundInputs(IntPtr io_binding);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate void DOrtClearBoundOutputs(IntPtr io_binding);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate void DOrtTensorAt(IntPtr io_binding);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtCreateAndRegisterAllocator(IntPtr env, IntPtr memInfo, IntPtr arenaCfg);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtSetLanguageProjection(IntPtr environment, int projection);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtSessionGetModelMetadata(IntPtr session, out IntPtr modelMetadata);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtModelMetadataGetProducerName(IntPtr modelMetadata, IntPtr allocator, out IntPtr value);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DOrtModelMetadataGetGraphName(IntPtr modelMetadata, IntPtr allocator, out IntPtr value);

		[UnmanagedFunctionPointer(CallingConvention.Winapi)]
		public delegate IntPtr DO

System.Buffers.dll

Decompiled 14 hours ago
using System;
using System.Diagnostics;
using System.Diagnostics.Tracing;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using FxResources.System.Buffers;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyTitle("System.Buffers")]
[assembly: AssemblyDescription("System.Buffers")]
[assembly: AssemblyDefaultAlias("System.Buffers")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyFileVersion("4.6.28619.01")]
[assembly: AssemblyInformationalVersion("4.6.28619.01 @BuiltBy: dlab14-DDVSOWINAGE069 @Branch: release/2.1 @SrcCode: https://github.com/dotnet/corefx/tree/7601f4f6225089ffb291dc7d58293c7bbf5c5d4f")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.0.3.0")]
[module: UnverifiableCode]
namespace FxResources.System.Buffers
{
	internal static class SR
	{
	}
}
namespace System
{
	internal static class SR
	{
		private static ResourceManager s_resourceManager;

		private static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(ResourceType));

		internal static Type ResourceType { get; } = typeof(SR);


		internal static string ArgumentException_BufferNotFromPool => GetResourceString("ArgumentException_BufferNotFromPool", null);

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static bool UsingResourceKeys()
		{
			return false;
		}

		internal static string GetResourceString(string resourceKey, string defaultString)
		{
			string text = null;
			try
			{
				text = ResourceManager.GetString(resourceKey);
			}
			catch (MissingManifestResourceException)
			{
			}
			if (defaultString != null && resourceKey.Equals(text, StringComparison.Ordinal))
			{
				return defaultString;
			}
			return text;
		}

		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(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);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.All)]
	internal class __BlockReflectionAttribute : Attribute
	{
	}
}
namespace System.Buffers
{
	public abstract class ArrayPool<T>
	{
		private static ArrayPool<T> s_sharedInstance;

		public static ArrayPool<T> Shared
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return Volatile.Read(ref s_sharedInstance) ?? EnsureSharedCreated();
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static ArrayPool<T> EnsureSharedCreated()
		{
			Interlocked.CompareExchange(ref s_sharedInstance, Create(), null);
			return s_sharedInstance;
		}

		public static ArrayPool<T> Create()
		{
			return new DefaultArrayPool<T>();
		}

		public static ArrayPool<T> Create(int maxArrayLength, int maxArraysPerBucket)
		{
			return new DefaultArrayPool<T>(maxArrayLength, maxArraysPerBucket);
		}

		public abstract T[] Rent(int minimumLength);

		public abstract void Return(T[] array, bool clearArray = false);
	}
	[EventSource(Name = "System.Buffers.ArrayPoolEventSource")]
	internal sealed class ArrayPoolEventSource : EventSource
	{
		internal enum BufferAllocatedReason
		{
			Pooled,
			OverMaximumSize,
			PoolExhausted
		}

		internal static readonly System.Buffers.ArrayPoolEventSource Log = new System.Buffers.ArrayPoolEventSource();

		[Event(1, Level = EventLevel.Verbose)]
		internal unsafe void BufferRented(int bufferId, int bufferSize, int poolId, int bucketId)
		{
			EventData* ptr = stackalloc EventData[4];
			*ptr = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferId)
			};
			ptr[1] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferSize)
			};
			ptr[2] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&poolId)
			};
			ptr[3] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bucketId)
			};
			WriteEventCore(1, 4, ptr);
		}

		[Event(2, Level = EventLevel.Informational)]
		internal unsafe void BufferAllocated(int bufferId, int bufferSize, int poolId, int bucketId, BufferAllocatedReason reason)
		{
			EventData* ptr = stackalloc EventData[5];
			*ptr = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferId)
			};
			ptr[1] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferSize)
			};
			ptr[2] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&poolId)
			};
			ptr[3] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bucketId)
			};
			ptr[4] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&reason)
			};
			WriteEventCore(2, 5, ptr);
		}

		[Event(3, Level = EventLevel.Verbose)]
		internal void BufferReturned(int bufferId, int bufferSize, int poolId)
		{
			WriteEvent(3, bufferId, bufferSize, poolId);
		}
	}
	internal sealed class DefaultArrayPool<T> : ArrayPool<T>
	{
		private sealed class Bucket
		{
			internal readonly int _bufferLength;

			private readonly T[][] _buffers;

			private readonly int _poolId;

			private SpinLock _lock;

			private int _index;

			internal int Id => GetHashCode();

			internal Bucket(int bufferLength, int numberOfBuffers, int poolId)
			{
				_lock = new SpinLock(Debugger.IsAttached);
				_buffers = new T[numberOfBuffers][];
				_bufferLength = bufferLength;
				_poolId = poolId;
			}

			internal T[] Rent()
			{
				T[][] buffers = _buffers;
				T[] array = null;
				bool lockTaken = false;
				bool flag = false;
				try
				{
					_lock.Enter(ref lockTaken);
					if (_index < buffers.Length)
					{
						array = buffers[_index];
						buffers[_index++] = null;
						flag = array == null;
					}
				}
				finally
				{
					if (lockTaken)
					{
						_lock.Exit(useMemoryBarrier: false);
					}
				}
				if (flag)
				{
					array = new T[_bufferLength];
					System.Buffers.ArrayPoolEventSource log = System.Buffers.ArrayPoolEventSource.Log;
					if (log.IsEnabled())
					{
						log.BufferAllocated(array.GetHashCode(), _bufferLength, _poolId, Id, System.Buffers.ArrayPoolEventSource.BufferAllocatedReason.Pooled);
					}
				}
				return array;
			}

			internal void Return(T[] array)
			{
				if (array.Length != _bufferLength)
				{
					throw new ArgumentException(System.SR.ArgumentException_BufferNotFromPool, "array");
				}
				bool lockTaken = false;
				try
				{
					_lock.Enter(ref lockTaken);
					if (_index != 0)
					{
						_buffers[--_index] = array;
					}
				}
				finally
				{
					if (lockTaken)
					{
						_lock.Exit(useMemoryBarrier: false);
					}
				}
			}
		}

		private const int DefaultMaxArrayLength = 1048576;

		private const int DefaultMaxNumberOfArraysPerBucket = 50;

		private static T[] s_emptyArray;

		private readonly Bucket[] _buckets;

		private int Id => GetHashCode();

		internal DefaultArrayPool()
			: this(1048576, 50)
		{
		}

		internal DefaultArrayPool(int maxArrayLength, int maxArraysPerBucket)
		{
			if (maxArrayLength <= 0)
			{
				throw new ArgumentOutOfRangeException("maxArrayLength");
			}
			if (maxArraysPerBucket <= 0)
			{
				throw new ArgumentOutOfRangeException("maxArraysPerBucket");
			}
			if (maxArrayLength > 1073741824)
			{
				maxArrayLength = 1073741824;
			}
			else if (maxArrayLength < 16)
			{
				maxArrayLength = 16;
			}
			int id = Id;
			int num = System.Buffers.Utilities.SelectBucketIndex(maxArrayLength);
			Bucket[] array = new Bucket[num + 1];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = new Bucket(System.Buffers.Utilities.GetMaxSizeForBucket(i), maxArraysPerBucket, id);
			}
			_buckets = array;
		}

		public override T[] Rent(int minimumLength)
		{
			if (minimumLength < 0)
			{
				throw new ArgumentOutOfRangeException("minimumLength");
			}
			if (minimumLength == 0)
			{
				return s_emptyArray ?? (s_emptyArray = new T[0]);
			}
			System.Buffers.ArrayPoolEventSource log = System.Buffers.ArrayPoolEventSource.Log;
			T[] array = null;
			int num = System.Buffers.Utilities.SelectBucketIndex(minimumLength);
			if (num < _buckets.Length)
			{
				int num2 = num;
				do
				{
					array = _buckets[num2].Rent();
					if (array != null)
					{
						if (log.IsEnabled())
						{
							log.BufferRented(array.GetHashCode(), array.Length, Id, _buckets[num2].Id);
						}
						return array;
					}
				}
				while (++num2 < _buckets.Length && num2 != num + 2);
				array = new T[_buckets[num]._bufferLength];
			}
			else
			{
				array = new T[minimumLength];
			}
			if (log.IsEnabled())
			{
				int hashCode = array.GetHashCode();
				int bucketId = -1;
				log.BufferRented(hashCode, array.Length, Id, bucketId);
				log.BufferAllocated(hashCode, array.Length, Id, bucketId, (num >= _buckets.Length) ? System.Buffers.ArrayPoolEventSource.BufferAllocatedReason.OverMaximumSize : System.Buffers.ArrayPoolEventSource.BufferAllocatedReason.PoolExhausted);
			}
			return array;
		}

		public override void Return(T[] array, bool clearArray = false)
		{
			if (array == null)
			{
				throw new ArgumentNullException("array");
			}
			if (array.Length == 0)
			{
				return;
			}
			int num = System.Buffers.Utilities.SelectBucketIndex(array.Length);
			if (num < _buckets.Length)
			{
				if (clearArray)
				{
					Array.Clear(array, 0, array.Length);
				}
				_buckets[num].Return(array);
			}
			System.Buffers.ArrayPoolEventSource log = System.Buffers.ArrayPoolEventSource.Log;
			if (log.IsEnabled())
			{
				log.BufferReturned(array.GetHashCode(), array.Length, Id);
			}
		}
	}
	internal static class Utilities
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static int SelectBucketIndex(int bufferSize)
		{
			uint num = (uint)(bufferSize - 1) >> 4;
			int num2 = 0;
			if (num > 65535)
			{
				num >>= 16;
				num2 = 16;
			}
			if (num > 255)
			{
				num >>= 8;
				num2 += 8;
			}
			if (num > 15)
			{
				num >>= 4;
				num2 += 4;
			}
			if (num > 3)
			{
				num >>= 2;
				num2 += 2;
			}
			if (num > 1)
			{
				num >>= 1;
				num2++;
			}
			return num2 + (int)num;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static int GetMaxSizeForBucket(int binIndex)
		{
			return 16 << binIndex;
		}
	}
}

System.Memory.dll

Decompiled 14 hours ago
using System;
using System.Buffers;
using System.Buffers.Binary;
using System.Buffers.Text;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Numerics;
using System.Numerics.Hashing;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using FxResources.System.Memory;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyTitle("System.Memory")]
[assembly: AssemblyDescription("System.Memory")]
[assembly: AssemblyDefaultAlias("System.Memory")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyFileVersion("4.6.31308.01")]
[assembly: AssemblyInformationalVersion("4.6.31308.01 @BuiltBy: cloudtest-841353dfc000000 @Branch: release/2.1-MSRC @SrcCode: https://github.com/dotnet/corefx/tree/32b491939fbd125f304031c35038b1e14b4e3958")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.0.1.2")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsByRefLikeAttribute : Attribute
	{
	}
}
namespace FxResources.System.Memory
{
	internal static class SR
	{
	}
}
namespace System
{
	public readonly struct SequencePosition : IEquatable<SequencePosition>
	{
		private readonly object _object;

		private readonly int _integer;

		public SequencePosition(object @object, int integer)
		{
			_object = @object;
			_integer = integer;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public object GetObject()
		{
			return _object;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public int GetInteger()
		{
			return _integer;
		}

		public bool Equals(SequencePosition other)
		{
			if (_integer == other._integer)
			{
				return object.Equals(_object, other._object);
			}
			return false;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			if (obj is SequencePosition other)
			{
				return Equals(other);
			}
			return false;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			return HashHelpers.Combine(_object?.GetHashCode() ?? 0, _integer);
		}
	}
	internal static class ThrowHelper
	{
		internal static void ThrowArgumentNullException(System.ExceptionArgument argument)
		{
			throw CreateArgumentNullException(argument);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentNullException(System.ExceptionArgument argument)
		{
			return new ArgumentNullException(argument.ToString());
		}

		internal static void ThrowArrayTypeMismatchException()
		{
			throw CreateArrayTypeMismatchException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArrayTypeMismatchException()
		{
			return new ArrayTypeMismatchException();
		}

		internal static void ThrowArgumentException_InvalidTypeWithPointersNotSupported(Type type)
		{
			throw CreateArgumentException_InvalidTypeWithPointersNotSupported(type);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentException_InvalidTypeWithPointersNotSupported(Type type)
		{
			return new ArgumentException(System.SR.Format(System.SR.Argument_InvalidTypeWithPointersNotSupported, type));
		}

		internal static void ThrowArgumentException_DestinationTooShort()
		{
			throw CreateArgumentException_DestinationTooShort();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentException_DestinationTooShort()
		{
			return new ArgumentException(System.SR.Argument_DestinationTooShort);
		}

		internal static void ThrowIndexOutOfRangeException()
		{
			throw CreateIndexOutOfRangeException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateIndexOutOfRangeException()
		{
			return new IndexOutOfRangeException();
		}

		internal static void ThrowArgumentOutOfRangeException()
		{
			throw CreateArgumentOutOfRangeException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException()
		{
			return new ArgumentOutOfRangeException();
		}

		internal static void ThrowArgumentOutOfRangeException(System.ExceptionArgument argument)
		{
			throw CreateArgumentOutOfRangeException(argument);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException(System.ExceptionArgument argument)
		{
			return new ArgumentOutOfRangeException(argument.ToString());
		}

		internal static void ThrowArgumentOutOfRangeException_PrecisionTooLarge()
		{
			throw CreateArgumentOutOfRangeException_PrecisionTooLarge();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException_PrecisionTooLarge()
		{
			return new ArgumentOutOfRangeException("precision", System.SR.Format(System.SR.Argument_PrecisionTooLarge, (byte)99));
		}

		internal static void ThrowArgumentOutOfRangeException_SymbolDoesNotFit()
		{
			throw CreateArgumentOutOfRangeException_SymbolDoesNotFit();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException_SymbolDoesNotFit()
		{
			return new ArgumentOutOfRangeException("symbol", System.SR.Argument_BadFormatSpecifier);
		}

		internal static void ThrowInvalidOperationException()
		{
			throw CreateInvalidOperationException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateInvalidOperationException()
		{
			return new InvalidOperationException();
		}

		internal static void ThrowInvalidOperationException_OutstandingReferences()
		{
			throw CreateInvalidOperationException_OutstandingReferences();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateInvalidOperationException_OutstandingReferences()
		{
			return new InvalidOperationException(System.SR.OutstandingReferences);
		}

		internal static void ThrowInvalidOperationException_UnexpectedSegmentType()
		{
			throw CreateInvalidOperationException_UnexpectedSegmentType();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateInvalidOperationException_UnexpectedSegmentType()
		{
			return new InvalidOperationException(System.SR.UnexpectedSegmentType);
		}

		internal static void ThrowInvalidOperationException_EndPositionNotReached()
		{
			throw CreateInvalidOperationException_EndPositionNotReached();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateInvalidOperationException_EndPositionNotReached()
		{
			return new InvalidOperationException(System.SR.EndPositionNotReached);
		}

		internal static void ThrowArgumentOutOfRangeException_PositionOutOfRange()
		{
			throw CreateArgumentOutOfRangeException_PositionOutOfRange();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException_PositionOutOfRange()
		{
			return new ArgumentOutOfRangeException("position");
		}

		internal static void ThrowArgumentOutOfRangeException_OffsetOutOfRange()
		{
			throw CreateArgumentOutOfRangeException_OffsetOutOfRange();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException_OffsetOutOfRange()
		{
			return new ArgumentOutOfRangeException("offset");
		}

		internal static void ThrowObjectDisposedException_ArrayMemoryPoolBuffer()
		{
			throw CreateObjectDisposedException_ArrayMemoryPoolBuffer();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateObjectDisposedException_ArrayMemoryPoolBuffer()
		{
			return new ObjectDisposedException("ArrayMemoryPoolBuffer");
		}

		internal static void ThrowFormatException_BadFormatSpecifier()
		{
			throw CreateFormatException_BadFormatSpecifier();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateFormatException_BadFormatSpecifier()
		{
			return new FormatException(System.SR.Argument_BadFormatSpecifier);
		}

		internal static void ThrowArgumentException_OverlapAlignmentMismatch()
		{
			throw CreateArgumentException_OverlapAlignmentMismatch();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentException_OverlapAlignmentMismatch()
		{
			return new ArgumentException(System.SR.Argument_OverlapAlignmentMismatch);
		}

		internal static void ThrowNotSupportedException()
		{
			throw CreateThrowNotSupportedException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateThrowNotSupportedException()
		{
			return new NotSupportedException();
		}

		public static bool TryFormatThrowFormatException(out int bytesWritten)
		{
			bytesWritten = 0;
			ThrowFormatException_BadFormatSpecifier();
			return false;
		}

		public static bool TryParseThrowFormatException<T>(out T value, out int bytesConsumed)
		{
			value = default(T);
			bytesConsumed = 0;
			ThrowFormatException_BadFormatSpecifier();
			return false;
		}

		public static void ThrowArgumentValidationException<T>(ReadOnlySequenceSegment<T> startSegment, int startIndex, ReadOnlySequenceSegment<T> endSegment)
		{
			throw CreateArgumentValidationException(startSegment, startIndex, endSegment);
		}

		private static Exception CreateArgumentValidationException<T>(ReadOnlySequenceSegment<T> startSegment, int startIndex, ReadOnlySequenceSegment<T> endSegment)
		{
			if (startSegment == null)
			{
				return CreateArgumentNullException(System.ExceptionArgument.startSegment);
			}
			if (endSegment == null)
			{
				return CreateArgumentNullException(System.ExceptionArgument.endSegment);
			}
			if (startSegment != endSegment && startSegment.RunningIndex > endSegment.RunningIndex)
			{
				return CreateArgumentOutOfRangeException(System.ExceptionArgument.endSegment);
			}
			if ((uint)startSegment.Memory.Length < (uint)startIndex)
			{
				return CreateArgumentOutOfRangeException(System.ExceptionArgument.startIndex);
			}
			return CreateArgumentOutOfRangeException(System.ExceptionArgument.endIndex);
		}

		public static void ThrowArgumentValidationException(Array array, int start)
		{
			throw CreateArgumentValidationException(array, start);
		}

		private static Exception CreateArgumentValidationException(Array array, int start)
		{
			if (array == null)
			{
				return CreateArgumentNullException(System.ExceptionArgument.array);
			}
			if ((uint)start > (uint)array.Length)
			{
				return CreateArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return CreateArgumentOutOfRangeException(System.ExceptionArgument.length);
		}

		public static void ThrowStartOrEndArgumentValidationException(long start)
		{
			throw CreateStartOrEndArgumentValidationException(start);
		}

		private static Exception CreateStartOrEndArgumentValidationException(long start)
		{
			if (start < 0)
			{
				return CreateArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return CreateArgumentOutOfRangeException(System.ExceptionArgument.length);
		}
	}
	internal enum ExceptionArgument
	{
		length,
		start,
		minimumBufferSize,
		elementIndex,
		comparable,
		comparer,
		destination,
		offset,
		startSegment,
		endSegment,
		startIndex,
		endIndex,
		array,
		culture,
		manager
	}
	internal static class DecimalDecCalc
	{
		private static uint D32DivMod1E9(uint hi32, ref uint lo32)
		{
			ulong num = ((ulong)hi32 << 32) | lo32;
			lo32 = (uint)(num / 1000000000);
			return (uint)(num % 1000000000);
		}

		internal static uint DecDivMod1E9(ref MutableDecimal value)
		{
			return D32DivMod1E9(D32DivMod1E9(D32DivMod1E9(0u, ref value.High), ref value.Mid), ref value.Low);
		}

		internal static void DecAddInt32(ref MutableDecimal value, uint i)
		{
			if (D32AddCarry(ref value.Low, i) && D32AddCarry(ref value.Mid, 1u))
			{
				D32AddCarry(ref value.High, 1u);
			}
		}

		private static bool D32AddCarry(ref uint value, uint i)
		{
			uint num = value;
			uint num2 = (value = num + i);
			if (num2 >= num)
			{
				return num2 < i;
			}
			return true;
		}

		internal static void DecMul10(ref MutableDecimal value)
		{
			MutableDecimal d = value;
			DecShiftLeft(ref value);
			DecShiftLeft(ref value);
			DecAdd(ref value, d);
			DecShiftLeft(ref value);
		}

		private static void DecShiftLeft(ref MutableDecimal value)
		{
			uint num = (((value.Low & 0x80000000u) != 0) ? 1u : 0u);
			uint num2 = (((value.Mid & 0x80000000u) != 0) ? 1u : 0u);
			value.Low <<= 1;
			value.Mid = (value.Mid << 1) | num;
			value.High = (value.High << 1) | num2;
		}

		private static void DecAdd(ref MutableDecimal value, MutableDecimal d)
		{
			if (D32AddCarry(ref value.Low, d.Low) && D32AddCarry(ref value.Mid, 1u))
			{
				D32AddCarry(ref value.High, 1u);
			}
			if (D32AddCarry(ref value.Mid, d.Mid))
			{
				D32AddCarry(ref value.High, 1u);
			}
			D32AddCarry(ref value.High, d.High);
		}
	}
	internal static class Number
	{
		private static class DoubleHelper
		{
			public unsafe static uint Exponent(double d)
			{
				return (*(uint*)((byte*)(&d) + 4) >> 20) & 0x7FFu;
			}

			public unsafe static ulong Mantissa(double d)
			{
				return *(uint*)(&d) | ((ulong)(uint)(*(int*)((byte*)(&d) + 4) & 0xFFFFF) << 32);
			}

			public unsafe static bool Sign(double d)
			{
				return *(uint*)((byte*)(&d) + 4) >> 31 != 0;
			}
		}

		internal const int DECIMAL_PRECISION = 29;

		private static readonly ulong[] s_rgval64Power10 = new ulong[30]
		{
			11529215046068469760uL, 14411518807585587200uL, 18014398509481984000uL, 11258999068426240000uL, 14073748835532800000uL, 17592186044416000000uL, 10995116277760000000uL, 13743895347200000000uL, 17179869184000000000uL, 10737418240000000000uL,
			13421772800000000000uL, 16777216000000000000uL, 10485760000000000000uL, 13107200000000000000uL, 16384000000000000000uL, 14757395258967641293uL, 11805916207174113035uL, 9444732965739290428uL, 15111572745182864686uL, 12089258196146291749uL,
			9671406556917033399uL, 15474250491067253438uL, 12379400392853802751uL, 9903520314283042201uL, 15845632502852867522uL, 12676506002282294018uL, 10141204801825835215uL, 16225927682921336344uL, 12980742146337069075uL, 10384593717069655260uL
		};

		private static readonly sbyte[] s_rgexp64Power10 = new sbyte[15]
		{
			4, 7, 10, 14, 17, 20, 24, 27, 30, 34,
			37, 40, 44, 47, 50
		};

		private static readonly ulong[] s_rgval64Power10By16 = new ulong[42]
		{
			10240000000000000000uL, 11368683772161602974uL, 12621774483536188886uL, 14012984643248170708uL, 15557538194652854266uL, 17272337110188889248uL, 9588073174409622172uL, 10644899600020376798uL, 11818212630765741798uL, 13120851772591970216uL,
			14567071740625403792uL, 16172698447808779622uL, 17955302187076837696uL, 9967194951097567532uL, 11065809325636130658uL, 12285516299433008778uL, 13639663065038175358uL, 15143067982934716296uL, 16812182738118149112uL, 9332636185032188787uL,
			10361307573072618722uL, 16615349947311448416uL, 14965776766268445891uL, 13479973333575319909uL, 12141680576410806707uL, 10936253623915059637uL, 9850501549098619819uL, 17745086042373215136uL, 15983352577617880260uL, 14396524142538228461uL,
			12967236152753103031uL, 11679847981112819795uL, 10520271803096747049uL, 9475818434452569218uL, 17070116948172427008uL, 15375394465392026135uL, 13848924157002783096uL, 12474001934591998882uL, 11235582092889474480uL, 10120112665365530972uL,
			18230774251475056952uL, 16420821625123739930uL
		};

		private static readonly short[] s_rgexp64Power10By16 = new short[21]
		{
			54, 107, 160, 213, 266, 319, 373, 426, 479, 532,
			585, 638, 691, 745, 798, 851, 904, 957, 1010, 1064,
			1117
		};

		public static void RoundNumber(ref NumberBuffer number, int pos)
		{
			Span<byte> digits = number.Digits;
			int i;
			for (i = 0; i < pos && digits[i] != 0; i++)
			{
			}
			if (i == pos && digits[i] >= 53)
			{
				while (i > 0 && digits[i - 1] == 57)
				{
					i--;
				}
				if (i > 0)
				{
					digits[i - 1]++;
				}
				else
				{
					number.Scale++;
					digits[0] = 49;
					i = 1;
				}
			}
			else
			{
				while (i > 0 && digits[i - 1] == 48)
				{
					i--;
				}
			}
			if (i == 0)
			{
				number.Scale = 0;
				number.IsNegative = false;
			}
			digits[i] = 0;
		}

		internal static bool NumberBufferToDouble(ref NumberBuffer number, out double value)
		{
			double num = NumberToDouble(ref number);
			uint num2 = DoubleHelper.Exponent(num);
			ulong num3 = DoubleHelper.Mantissa(num);
			switch (num2)
			{
			case 2047u:
				value = 0.0;
				return false;
			case 0u:
				if (num3 == 0L)
				{
					num = 0.0;
				}
				break;
			}
			value = num;
			return true;
		}

		public unsafe static bool NumberBufferToDecimal(ref NumberBuffer number, ref decimal value)
		{
			MutableDecimal source = default(MutableDecimal);
			byte* ptr = number.UnsafeDigits;
			int num = number.Scale;
			if (*ptr == 0)
			{
				if (num > 0)
				{
					num = 0;
				}
			}
			else
			{
				if (num > 29)
				{
					return false;
				}
				while ((num > 0 || (*ptr != 0 && num > -28)) && (source.High < 429496729 || (source.High == 429496729 && (source.Mid < 2576980377u || (source.Mid == 2576980377u && (source.Low < 2576980377u || (source.Low == 2576980377u && *ptr <= 53)))))))
				{
					DecimalDecCalc.DecMul10(ref source);
					if (*ptr != 0)
					{
						DecimalDecCalc.DecAddInt32(ref source, (uint)(*(ptr++) - 48));
					}
					num--;
				}
				if (*(ptr++) >= 53)
				{
					bool flag = true;
					if (*(ptr - 1) == 53 && *(ptr - 2) % 2 == 0)
					{
						int num2 = 20;
						while (*ptr == 48 && num2 != 0)
						{
							ptr++;
							num2--;
						}
						if (*ptr == 0 || num2 == 0)
						{
							flag = false;
						}
					}
					if (flag)
					{
						DecimalDecCalc.DecAddInt32(ref source, 1u);
						if ((source.High | source.Mid | source.Low) == 0)
						{
							source.High = 429496729u;
							source.Mid = 2576980377u;
							source.Low = 2576980378u;
							num++;
						}
					}
				}
			}
			if (num > 0)
			{
				return false;
			}
			if (num <= -29)
			{
				source.High = 0u;
				source.Low = 0u;
				source.Mid = 0u;
				source.Scale = 28;
			}
			else
			{
				source.Scale = -num;
			}
			source.IsNegative = number.IsNegative;
			value = Unsafe.As<MutableDecimal, decimal>(ref source);
			return true;
		}

		public static void DecimalToNumber(decimal value, ref NumberBuffer number)
		{
			ref MutableDecimal reference = ref Unsafe.As<decimal, MutableDecimal>(ref value);
			Span<byte> digits = number.Digits;
			number.IsNegative = reference.IsNegative;
			int num = 29;
			while ((reference.Mid != 0) | (reference.High != 0))
			{
				uint num2 = DecimalDecCalc.DecDivMod1E9(ref reference);
				for (int i = 0; i < 9; i++)
				{
					digits[--num] = (byte)(num2 % 10 + 48);
					num2 /= 10;
				}
			}
			for (uint num3 = reference.Low; num3 != 0; num3 /= 10)
			{
				digits[--num] = (byte)(num3 % 10 + 48);
			}
			int num4 = 29 - num;
			number.Scale = num4 - reference.Scale;
			Span<byte> digits2 = number.Digits;
			int index = 0;
			while (--num4 >= 0)
			{
				digits2[index++] = digits[num++];
			}
			digits2[index] = 0;
		}

		private static uint DigitsToInt(ReadOnlySpan<byte> digits, int count)
		{
			uint value;
			int bytesConsumed;
			bool flag = Utf8Parser.TryParse(digits.Slice(0, count), out value, out bytesConsumed, 'D');
			return value;
		}

		private static ulong Mul32x32To64(uint a, uint b)
		{
			return (ulong)a * (ulong)b;
		}

		private static ulong Mul64Lossy(ulong a, ulong b, ref int pexp)
		{
			ulong num = Mul32x32To64((uint)(a >> 32), (uint)(b >> 32)) + (Mul32x32To64((uint)(a >> 32), (uint)b) >> 32) + (Mul32x32To64((uint)a, (uint)(b >> 32)) >> 32);
			if ((num & 0x8000000000000000uL) == 0L)
			{
				num <<= 1;
				pexp--;
			}
			return num;
		}

		private static int abs(int value)
		{
			if (value < 0)
			{
				return -value;
			}
			return value;
		}

		private unsafe static double NumberToDouble(ref NumberBuffer number)
		{
			ReadOnlySpan<byte> digits = number.Digits;
			int i = 0;
			int numDigits = number.NumDigits;
			int num = numDigits;
			for (; digits[i] == 48; i++)
			{
				num--;
			}
			if (num == 0)
			{
				return 0.0;
			}
			int num2 = Math.Min(num, 9);
			num -= num2;
			ulong num3 = DigitsToInt(digits, num2);
			if (num > 0)
			{
				num2 = Math.Min(num, 9);
				num -= num2;
				uint b = (uint)(s_rgval64Power10[num2 - 1] >> 64 - s_rgexp64Power10[num2 - 1]);
				num3 = Mul32x32To64((uint)num3, b) + DigitsToInt(digits.Slice(9), num2);
			}
			int num4 = number.Scale - (numDigits - num);
			int num5 = abs(num4);
			if (num5 >= 352)
			{
				ulong num6 = ((num4 > 0) ? 9218868437227405312uL : 0);
				if (number.IsNegative)
				{
					num6 |= 0x8000000000000000uL;
				}
				return *(double*)(&num6);
			}
			int pexp = 64;
			if ((num3 & 0xFFFFFFFF00000000uL) == 0L)
			{
				num3 <<= 32;
				pexp -= 32;
			}
			if ((num3 & 0xFFFF000000000000uL) == 0L)
			{
				num3 <<= 16;
				pexp -= 16;
			}
			if ((num3 & 0xFF00000000000000uL) == 0L)
			{
				num3 <<= 8;
				pexp -= 8;
			}
			if ((num3 & 0xF000000000000000uL) == 0L)
			{
				num3 <<= 4;
				pexp -= 4;
			}
			if ((num3 & 0xC000000000000000uL) == 0L)
			{
				num3 <<= 2;
				pexp -= 2;
			}
			if ((num3 & 0x8000000000000000uL) == 0L)
			{
				num3 <<= 1;
				pexp--;
			}
			int num7 = num5 & 0xF;
			if (num7 != 0)
			{
				int num8 = s_rgexp64Power10[num7 - 1];
				pexp += ((num4 < 0) ? (-num8 + 1) : num8);
				ulong b2 = s_rgval64Power10[num7 + ((num4 < 0) ? 15 : 0) - 1];
				num3 = Mul64Lossy(num3, b2, ref pexp);
			}
			num7 = num5 >> 4;
			if (num7 != 0)
			{
				int num9 = s_rgexp64Power10By16[num7 - 1];
				pexp += ((num4 < 0) ? (-num9 + 1) : num9);
				ulong b3 = s_rgval64Power10By16[num7 + ((num4 < 0) ? 21 : 0) - 1];
				num3 = Mul64Lossy(num3, b3, ref pexp);
			}
			if (((uint)(int)num3 & 0x400u) != 0)
			{
				ulong num10 = num3 + 1023 + (ulong)(((int)num3 >> 11) & 1);
				if (num10 < num3)
				{
					num10 = (num10 >> 1) | 0x8000000000000000uL;
					pexp++;
				}
				num3 = num10;
			}
			pexp += 1022;
			num3 = ((pexp <= 0) ? ((pexp == -52 && num3 >= 9223372036854775896uL) ? 1 : ((pexp > -52) ? (num3 >> -pexp + 11 + 1) : 0)) : ((pexp < 2047) ? ((ulong)((long)pexp << 52) + ((num3 >> 11) & 0xFFFFFFFFFFFFFL)) : 9218868437227405312uL));
			if (number.IsNegative)
			{
				num3 |= 0x8000000000000000uL;
			}
			return *(double*)(&num3);
		}
	}
	internal ref struct NumberBuffer
	{
		public int Scale;

		public bool IsNegative;

		public const int BufferSize = 51;

		private byte _b0;

		private byte _b1;

		private byte _b2;

		private byte _b3;

		private byte _b4;

		private byte _b5;

		private byte _b6;

		private byte _b7;

		private byte _b8;

		private byte _b9;

		private byte _b10;

		private byte _b11;

		private byte _b12;

		private byte _b13;

		private byte _b14;

		private byte _b15;

		private byte _b16;

		private byte _b17;

		private byte _b18;

		private byte _b19;

		private byte _b20;

		private byte _b21;

		private byte _b22;

		private byte _b23;

		private byte _b24;

		private byte _b25;

		private byte _b26;

		private byte _b27;

		private byte _b28;

		private byte _b29;

		private byte _b30;

		private byte _b31;

		private byte _b32;

		private byte _b33;

		private byte _b34;

		private byte _b35;

		private byte _b36;

		private byte _b37;

		private byte _b38;

		private byte _b39;

		private byte _b40;

		private byte _b41;

		private byte _b42;

		private byte _b43;

		private byte _b44;

		private byte _b45;

		private byte _b46;

		private byte _b47;

		private byte _b48;

		private byte _b49;

		private byte _b50;

		public unsafe Span<byte> Digits => new Span<byte>(Unsafe.AsPointer(ref _b0), 51);

		public unsafe byte* UnsafeDigits => (byte*)Unsafe.AsPointer(ref _b0);

		public int NumDigits => Digits.IndexOf<byte>(0);

		[Conditional("DEBUG")]
		public void CheckConsistency()
		{
		}

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append('[');
			stringBuilder.Append('"');
			Span<byte> digits = Digits;
			for (int i = 0; i < 51; i++)
			{
				byte b = digits[i];
				if (b == 0)
				{
					break;
				}
				stringBuilder.Append((char)b);
			}
			stringBuilder.Append('"');
			stringBuilder.Append(", Scale = " + Scale);
			stringBuilder.Append(", IsNegative   = " + IsNegative);
			stringBuilder.Append(']');
			return stringBuilder.ToString();
		}
	}
	[DebuggerTypeProxy(typeof(System.MemoryDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	public readonly struct Memory<T>
	{
		private readonly object _object;

		private readonly int _index;

		private readonly int _length;

		private const int RemoveFlagsBitMask = int.MaxValue;

		public static Memory<T> Empty => default(Memory<T>);

		public int Length => _length & 0x7FFFFFFF;

		public bool IsEmpty => (_length & 0x7FFFFFFF) == 0;

		public Span<T> Span
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				Span<T> result;
				if (_index < 0)
				{
					result = ((MemoryManager<T>)_object).GetSpan();
					return result.Slice(_index & 0x7FFFFFFF, _length);
				}
				if (typeof(T) == typeof(char) && _object is string text)
				{
					result = new Span<T>(Unsafe.As<Pinnable<T>>(text), MemoryExtensions.StringAdjustment, text.Length);
					return result.Slice(_index, _length);
				}
				if (_object != null)
				{
					return new Span<T>((T[])_object, _index, _length & 0x7FFFFFFF);
				}
				result = default(Span<T>);
				return result;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory(T[] array)
		{
			if (array == null)
			{
				this = default(Memory<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			_object = array;
			_index = 0;
			_length = array.Length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Memory(T[] array, int start)
		{
			if (array == null)
			{
				if (start != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException();
				}
				this = default(Memory<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			if ((uint)start > (uint)array.Length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = array;
			_index = start;
			_length = array.Length - start;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory(T[] array, int start, int length)
		{
			if (array == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException();
				}
				this = default(Memory<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = array;
			_index = start;
			_length = length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Memory(MemoryManager<T> manager, int length)
		{
			if (length < 0)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = manager;
			_index = int.MinValue;
			_length = length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Memory(MemoryManager<T> manager, int start, int length)
		{
			if (length < 0 || start < 0)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = manager;
			_index = start | int.MinValue;
			_length = length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Memory(object obj, int start, int length)
		{
			_object = obj;
			_index = start;
			_length = length;
		}

		public static implicit operator Memory<T>(T[] array)
		{
			return new Memory<T>(array);
		}

		public static implicit operator Memory<T>(ArraySegment<T> segment)
		{
			return new Memory<T>(segment.Array, segment.Offset, segment.Count);
		}

		public static implicit operator ReadOnlyMemory<T>(Memory<T> memory)
		{
			return Unsafe.As<Memory<T>, ReadOnlyMemory<T>>(ref memory);
		}

		public override string ToString()
		{
			if (typeof(T) == typeof(char))
			{
				if (!(_object is string text))
				{
					return Span.ToString();
				}
				return text.Substring(_index, _length & 0x7FFFFFFF);
			}
			return $"System.Memory<{typeof(T).Name}>[{_length & 0x7FFFFFFF}]";
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory<T> Slice(int start)
		{
			int length = _length;
			int num = length & 0x7FFFFFFF;
			if ((uint)start > (uint)num)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new Memory<T>(_object, _index + start, length - start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory<T> Slice(int start, int length)
		{
			int length2 = _length;
			int num = length2 & 0x7FFFFFFF;
			if ((uint)start > (uint)num || (uint)length > (uint)(num - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			return new Memory<T>(_object, _index + start, length | (length2 & int.MinValue));
		}

		public void CopyTo(Memory<T> destination)
		{
			Span.CopyTo(destination.Span);
		}

		public bool TryCopyTo(Memory<T> destination)
		{
			return Span.TryCopyTo(destination.Span);
		}

		public unsafe MemoryHandle Pin()
		{
			if (_index < 0)
			{
				return ((MemoryManager<T>)_object).Pin(_index & 0x7FFFFFFF);
			}
			if (typeof(T) == typeof(char) && _object is string value)
			{
				GCHandle handle = GCHandle.Alloc(value, GCHandleType.Pinned);
				void* pointer = Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer, handle);
			}
			if (_object is T[] array)
			{
				if (_length < 0)
				{
					void* pointer2 = Unsafe.Add<T>(Unsafe.AsPointer(ref MemoryMarshal.GetReference<T>(array)), _index);
					return new MemoryHandle(pointer2);
				}
				GCHandle handle2 = GCHandle.Alloc(array, GCHandleType.Pinned);
				void* pointer3 = Unsafe.Add<T>((void*)handle2.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer3, handle2);
			}
			return default(MemoryHandle);
		}

		public T[] ToArray()
		{
			return Span.ToArray();
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			if (obj is ReadOnlyMemory<T> readOnlyMemory)
			{
				return readOnlyMemory.Equals(this);
			}
			if (obj is Memory<T> other)
			{
				return Equals(other);
			}
			return false;
		}

		public bool Equals(Memory<T> other)
		{
			if (_object == other._object && _index == other._index)
			{
				return _length == other._length;
			}
			return false;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			if (_object == null)
			{
				return 0;
			}
			int hashCode = _object.GetHashCode();
			int index = _index;
			int hashCode2 = index.GetHashCode();
			index = _length;
			return CombineHashCodes(hashCode, hashCode2, index.GetHashCode());
		}

		private static int CombineHashCodes(int left, int right)
		{
			return ((left << 5) + left) ^ right;
		}

		private static int CombineHashCodes(int h1, int h2, int h3)
		{
			return CombineHashCodes(CombineHashCodes(h1, h2), h3);
		}
	}
	internal sealed class MemoryDebugView<T>
	{
		private readonly ReadOnlyMemory<T> _memory;

		[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
		public T[] Items => _memory.ToArray();

		public MemoryDebugView(Memory<T> memory)
		{
			_memory = memory;
		}

		public MemoryDebugView(ReadOnlyMemory<T> memory)
		{
			_memory = memory;
		}
	}
	public static class MemoryExtensions
	{
		internal static readonly IntPtr StringAdjustment = MeasureStringAdjustment();

		public static ReadOnlySpan<char> Trim(this ReadOnlySpan<char> span)
		{
			return span.TrimStart().TrimEnd();
		}

		public static ReadOnlySpan<char> TrimStart(this ReadOnlySpan<char> span)
		{
			int i;
			for (i = 0; i < span.Length && char.IsWhiteSpace(span[i]); i++)
			{
			}
			return span.Slice(i);
		}

		public static ReadOnlySpan<char> TrimEnd(this ReadOnlySpan<char> span)
		{
			int num = span.Length - 1;
			while (num >= 0 && char.IsWhiteSpace(span[num]))
			{
				num--;
			}
			return span.Slice(0, num + 1);
		}

		public static ReadOnlySpan<char> Trim(this ReadOnlySpan<char> span, char trimChar)
		{
			return span.TrimStart(trimChar).TrimEnd(trimChar);
		}

		public static ReadOnlySpan<char> TrimStart(this ReadOnlySpan<char> span, char trimChar)
		{
			int i;
			for (i = 0; i < span.Length && span[i] == trimChar; i++)
			{
			}
			return span.Slice(i);
		}

		public static ReadOnlySpan<char> TrimEnd(this ReadOnlySpan<char> span, char trimChar)
		{
			int num = span.Length - 1;
			while (num >= 0 && span[num] == trimChar)
			{
				num--;
			}
			return span.Slice(0, num + 1);
		}

		public static ReadOnlySpan<char> Trim(this ReadOnlySpan<char> span, ReadOnlySpan<char> trimChars)
		{
			return span.TrimStart(trimChars).TrimEnd(trimChars);
		}

		public static ReadOnlySpan<char> TrimStart(this ReadOnlySpan<char> span, ReadOnlySpan<char> trimChars)
		{
			if (trimChars.IsEmpty)
			{
				return span.TrimStart();
			}
			int i;
			for (i = 0; i < span.Length; i++)
			{
				int num = 0;
				while (num < trimChars.Length)
				{
					if (span[i] != trimChars[num])
					{
						num++;
						continue;
					}
					goto IL_003c;
				}
				break;
				IL_003c:;
			}
			return span.Slice(i);
		}

		public static ReadOnlySpan<char> TrimEnd(this ReadOnlySpan<char> span, ReadOnlySpan<char> trimChars)
		{
			if (trimChars.IsEmpty)
			{
				return span.TrimEnd();
			}
			int num;
			for (num = span.Length - 1; num >= 0; num--)
			{
				int num2 = 0;
				while (num2 < trimChars.Length)
				{
					if (span[num] != trimChars[num2])
					{
						num2++;
						continue;
					}
					goto IL_0044;
				}
				break;
				IL_0044:;
			}
			return span.Slice(0, num + 1);
		}

		public static bool IsWhiteSpace(this ReadOnlySpan<char> span)
		{
			for (int i = 0; i < span.Length; i++)
			{
				if (!char.IsWhiteSpace(span[i]))
				{
					return false;
				}
			}
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOf<T>(this Span<T> span, T value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.IndexOf(ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, char>(ref value), span.Length);
			}
			return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), value, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOf<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length);
			}
			return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOf<T>(this Span<T> span, T value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.LastIndexOf(ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, char>(ref value), span.Length);
			}
			return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), value, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOf<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length);
			}
			return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool SequenceEqual<T>(this Span<T> span, ReadOnlySpan<T> other) where T : IEquatable<T>
		{
			int length = span.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length == other.Length)
				{
					return System.SpanHelpers.SequenceEqual(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), (NUInt)length * size);
				}
				return false;
			}
			if (length == other.Length)
			{
				return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other), length);
			}
			return false;
		}

		public static int SequenceCompareTo<T>(this Span<T> span, ReadOnlySpan<T> other) where T : IComparable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.SequenceCompareTo(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.SequenceCompareTo(ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			return System.SpanHelpers.SequenceCompareTo(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(other), other.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOf<T>(this ReadOnlySpan<T> span, T value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.IndexOf(ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, char>(ref value), span.Length);
			}
			return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), value, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOf<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length);
			}
			return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOf<T>(this ReadOnlySpan<T> span, T value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.LastIndexOf(ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, char>(ref value), span.Length);
			}
			return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), value, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOf<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOf(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length);
			}
			return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this Span<T> span, T value0, T value1) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), span.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this Span<T> span, T value0, T value1, T value2) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), Unsafe.As<T, byte>(ref value2), span.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this Span<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), span.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1, T value2) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), Unsafe.As<T, byte>(ref value2), span.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this Span<T> span, T value0, T value1) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), span.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this Span<T> span, T value0, T value1, T value2) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), Unsafe.As<T, byte>(ref value2), span.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this Span<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), span.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1, T value2) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), Unsafe.As<T, byte>(ref value0), Unsafe.As<T, byte>(ref value1), Unsafe.As<T, byte>(ref value2), span.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool SequenceEqual<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other) where T : IEquatable<T>
		{
			int length = span.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length == other.Length)
				{
					return System.SpanHelpers.SequenceEqual(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), (NUInt)length * size);
				}
				return false;
			}
			if (length == other.Length)
			{
				return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other), length);
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int SequenceCompareTo<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other) where T : IComparable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.SequenceCompareTo(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.SequenceCompareTo(ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), span.Length, ref Unsafe.As<T, char>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			return System.SpanHelpers.SequenceCompareTo(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(other), other.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool StartsWith<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			int length = value.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length <= span.Length)
				{
					return System.SpanHelpers.SequenceEqual(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length * size);
				}
				return false;
			}
			if (length <= span.Length)
			{
				return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(value), length);
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool StartsWith<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			int length = value.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length <= span.Length)
				{
					return System.SpanHelpers.SequenceEqual(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length * size);
				}
				return false;
			}
			if (length <= span.Length)
			{
				return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(value), length);
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool EndsWith<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			int length = span.Length;
			int length2 = value.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length2 <= length)
				{
					return System.SpanHelpers.SequenceEqual(ref Unsafe.As<T, byte>(ref Unsafe.Add(ref MemoryMarshal.GetReference(span), length - length2)), ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length2 * size);
				}
				return false;
			}
			if (length2 <= length)
			{
				return System.SpanHelpers.SequenceEqual(ref Unsafe.Add(ref MemoryMarshal.GetReference(span), length - length2), ref MemoryMarshal.GetReference(value), length2);
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool EndsWith<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			int length = span.Length;
			int length2 = value.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length2 <= length)
				{
					return System.SpanHelpers.SequenceEqual(ref Unsafe.As<T, byte>(ref Unsafe.Add(ref MemoryMarshal.GetReference(span), length - length2)), ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length2 * size);
				}
				return false;
			}
			if (length2 <= length)
			{
				return System.SpanHelpers.SequenceEqual(ref Unsafe.Add(ref MemoryMarshal.GetReference(span), length - length2), ref MemoryMarshal.GetReference(value), length2);
			}
			return false;
		}

		public static void Reverse<T>(this Span<T> span)
		{
			ref T reference = ref MemoryMarshal.GetReference(span);
			int num = 0;
			int num2 = span.Length - 1;
			while (num < num2)
			{
				T val = Unsafe.Add(ref reference, num);
				Unsafe.Add(ref reference, num) = Unsafe.Add(ref reference, num2);
				Unsafe.Add(ref reference, num2) = val;
				num++;
				num2--;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this T[] array)
		{
			return new Span<T>(array);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this T[] array, int start, int length)
		{
			return new Span<T>(array, start, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this ArraySegment<T> segment)
		{
			return new Span<T>(segment.Array, segment.Offset, segment.Count);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this ArraySegment<T> segment, int start)
		{
			if ((uint)start > segment.Count)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new Span<T>(segment.Array, segment.Offset + start, segment.Count - start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this ArraySegment<T> segment, int start, int length)
		{
			if ((uint)start > segment.Count)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			if ((uint)length > segment.Count - start)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length);
			}
			return new Span<T>(segment.Array, segment.Offset + start, length);
		}

		public static Memory<T> AsMemory<T>(this T[] array)
		{
			return new Memory<T>(array);
		}

		public static Memory<T> AsMemory<T>(this T[] array, int start)
		{
			return new Memory<T>(array, start);
		}

		public static Memory<T> AsMemory<T>(this T[] array, int start, int length)
		{
			return new Memory<T>(array, start, length);
		}

		public static Memory<T> AsMemory<T>(this ArraySegment<T> segment)
		{
			return new Memory<T>(segment.Array, segment.Offset, segment.Count);
		}

		public static Memory<T> AsMemory<T>(this ArraySegment<T> segment, int start)
		{
			if ((uint)start > segment.Count)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new Memory<T>(segment.Array, segment.Offset + start, segment.Count - start);
		}

		public static Memory<T> AsMemory<T>(this ArraySegment<T> segment, int start, int length)
		{
			if ((uint)start > segment.Count)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			if ((uint)length > segment.Count - start)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length);
			}
			return new Memory<T>(segment.Array, segment.Offset + start, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void CopyTo<T>(this T[] source, Span<T> destination)
		{
			new ReadOnlySpan<T>(source).CopyTo(destination);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void CopyTo<T>(this T[] source, Memory<T> destination)
		{
			source.CopyTo(destination.Span);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool Overlaps<T>(this Span<T> span, ReadOnlySpan<T> other)
		{
			return ((ReadOnlySpan<T>)span).Overlaps(other);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool Overlaps<T>(this Span<T> span, ReadOnlySpan<T> other, out int elementOffset)
		{
			return ((ReadOnlySpan<T>)span).Overlaps(other, out elementOffset);
		}

		public static bool Overlaps<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other)
		{
			if (span.IsEmpty || other.IsEmpty)
			{
				return false;
			}
			IntPtr intPtr = Unsafe.ByteOffset(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other));
			if (Unsafe.SizeOf<IntPtr>() == 4)
			{
				if ((uint)(int)intPtr >= (uint)(span.Length * Unsafe.SizeOf<T>()))
				{
					return (uint)(int)intPtr > (uint)(-(other.Length * Unsafe.SizeOf<T>()));
				}
				return true;
			}
			if ((ulong)(long)intPtr >= (ulong)((long)span.Length * (long)Unsafe.SizeOf<T>()))
			{
				return (ulong)(long)intPtr > (ulong)(-((long)other.Length * (long)Unsafe.SizeOf<T>()));
			}
			return true;
		}

		public static bool Overlaps<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other, out int elementOffset)
		{
			if (span.IsEmpty || other.IsEmpty)
			{
				elementOffset = 0;
				return false;
			}
			IntPtr intPtr = Unsafe.ByteOffset(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other));
			if (Unsafe.SizeOf<IntPtr>() == 4)
			{
				if ((uint)(int)intPtr < (uint)(span.Length * Unsafe.SizeOf<T>()) || (uint)(int)intPtr > (uint)(-(other.Length * Unsafe.SizeOf<T>())))
				{
					if ((int)intPtr % Unsafe.SizeOf<T>() != 0)
					{
						System.ThrowHelper.ThrowArgumentException_OverlapAlignmentMismatch();
					}
					elementOffset = (int)intPtr / Unsafe.SizeOf<T>();
					return true;
				}
				elementOffset = 0;
				return false;
			}
			if ((ulong)(long)intPtr < (ulong)((long)span.Length * (long)Unsafe.SizeOf<T>()) || (ulong)(long)intPtr > (ulong)(-((long)other.Length * (long)Unsafe.SizeOf<T>())))
			{
				if ((long)intPtr % Unsafe.SizeOf<T>() != 0L)
				{
					System.ThrowHelper.ThrowArgumentException_OverlapAlignmentMismatch();
				}
				elementOffset = (int)((long)intPtr / Unsafe.SizeOf<T>());
				return true;
			}
			elementOffset = 0;
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T>(this Span<T> span, IComparable<T> comparable)
		{
			return span.BinarySearch<T, IComparable<T>>(comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparable>(this Span<T> span, TComparable comparable) where TComparable : IComparable<T>
		{
			return BinarySearch((ReadOnlySpan<T>)span, comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparer>(this Span<T> span, T value, TComparer comparer) where TComparer : IComparer<T>
		{
			return ((ReadOnlySpan<T>)span).BinarySearch(value, comparer);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T>(this ReadOnlySpan<T> span, IComparable<T> comparable)
		{
			return MemoryExtensions.BinarySearch<T, IComparable<T>>(span, comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparable>(this ReadOnlySpan<T> span, TComparable comparable) where TComparable : IComparable<T>
		{
			return System.SpanHelpers.BinarySearch(span, comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparer>(this ReadOnlySpan<T> span, T value, TComparer comparer) where TComparer : IComparer<T>
		{
			if (comparer == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.comparer);
			}
			System.SpanHelpers.ComparerComparable<T, TComparer> comparable = new System.SpanHelpers.ComparerComparable<T, TComparer>(value, comparer);
			return BinarySearch(span, comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static bool IsTypeComparableAsBytes<T>(out NUInt size)
		{
			if (typeof(T) == typeof(byte) || typeof(T) == typeof(sbyte))
			{
				size = (NUInt)1;
				return true;
			}
			if (typeof(T) == typeof(char) || typeof(T) == typeof(short) || typeof(T) == typeof(ushort))
			{
				size = (NUInt)2;
				return true;
			}
			if (typeof(T) == typeof(int) || typeof(T) == typeof(uint))
			{
				size = (NUInt)4;
				return true;
			}
			if (typeof(T) == typeof(long) || typeof(T) == typeof(ulong))
			{
				size = (NUInt)8;
				return true;
			}
			size = default(NUInt);
			return false;
		}

		public static Span<T> AsSpan<T>(this T[] array, int start)
		{
			return Span<T>.Create(array, start);
		}

		public static bool Contains(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
		{
			return span.IndexOf(value, comparisonType) >= 0;
		}

		public static bool Equals(this ReadOnlySpan<char> span, ReadOnlySpan<char> other, StringComparison comparisonType)
		{
			switch (comparisonType)
			{
			case StringComparison.Ordinal:
				return span.SequenceEqual(other);
			case StringComparison.OrdinalIgnoreCase:
				if (span.Length != other.Length)
				{
					return false;
				}
				return EqualsOrdinalIgnoreCase(span, other);
			default:
				return span.ToString().Equals(other.ToString(), comparisonType);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static bool EqualsOrdinalIgnoreCase(ReadOnlySpan<char> span, ReadOnlySpan<char> other)
		{
			if (other.Length == 0)
			{
				return true;
			}
			return CompareToOrdinalIgnoreCase(span, other) == 0;
		}

		public static int CompareTo(this ReadOnlySpan<char> span, ReadOnlySpan<char> other, StringComparison comparisonType)
		{
			return comparisonType switch
			{
				StringComparison.Ordinal => span.SequenceCompareTo(other), 
				StringComparison.OrdinalIgnoreCase => CompareToOrdinalIgnoreCase(span, other), 
				_ => string.Compare(span.ToString(), other.ToString(), comparisonType), 
			};
		}

		private unsafe static int CompareToOrdinalIgnoreCase(ReadOnlySpan<char> strA, ReadOnlySpan<char> strB)
		{
			int num = Math.Min(strA.Length, strB.Length);
			int num2 = num;
			fixed (char* ptr = &MemoryMarshal.GetReference(strA))
			{
				fixed (char* ptr3 = &MemoryMarshal.GetReference(strB))
				{
					char* ptr2 = ptr;
					char* ptr4 = ptr3;
					while (num != 0 && *ptr2 <= '\u007f' && *ptr4 <= '\u007f')
					{
						int num3 = *ptr2;
						int num4 = *ptr4;
						if (num3 == num4)
						{
							ptr2++;
							ptr4++;
							num--;
							continue;
						}
						if ((uint)(num3 - 97) <= 25u)
						{
							num3 -= 32;
						}
						if ((uint)(num4 - 97) <= 25u)
						{
							num4 -= 32;
						}
						if (num3 != num4)
						{
							return num3 - num4;
						}
						ptr2++;
						ptr4++;
						num--;
					}
					if (num == 0)
					{
						return strA.Length - strB.Length;
					}
					num2 -= num;
					return string.Compare(strA.Slice(num2).ToString(), strB.Slice(num2).ToString(), StringComparison.OrdinalIgnoreCase);
				}
			}
		}

		public static int IndexOf(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
		{
			if (comparisonType == StringComparison.Ordinal)
			{
				return span.IndexOf(value);
			}
			return span.ToString().IndexOf(value.ToString(), comparisonType);
		}

		public static int ToLower(this ReadOnlySpan<char> source, Span<char> destination, CultureInfo culture)
		{
			if (culture == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.culture);
			}
			if (destination.Length < source.Length)
			{
				return -1;
			}
			string text = source.ToString();
			string text2 = text.ToLower(culture);
			AsSpan(text2).CopyTo(destination);
			return source.Length;
		}

		public static int ToLowerInvariant(this ReadOnlySpan<char> source, Span<char> destination)
		{
			return source.ToLower(destination, CultureInfo.InvariantCulture);
		}

		public static int ToUpper(this ReadOnlySpan<char> source, Span<char> destination, CultureInfo culture)
		{
			if (culture == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.culture);
			}
			if (destination.Length < source.Length)
			{
				return -1;
			}
			string text = source.ToString();
			string text2 = text.ToUpper(culture);
			AsSpan(text2).CopyTo(destination);
			return source.Length;
		}

		public static int ToUpperInvariant(this ReadOnlySpan<char> source, Span<char> destination)
		{
			return source.ToUpper(destination, CultureInfo.InvariantCulture);
		}

		public static bool EndsWith(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
		{
			switch (comparisonType)
			{
			case StringComparison.Ordinal:
				return span.EndsWith(value);
			case StringComparison.OrdinalIgnoreCase:
				if (value.Length <= span.Length)
				{
					return EqualsOrdinalIgnoreCase(span.Slice(span.Length - value.Length), value);
				}
				return false;
			default:
			{
				string text = span.ToString();
				string value2 = value.ToString();
				return text.EndsWith(value2, comparisonType);
			}
			}
		}

		public static bool StartsWith(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
		{
			switch (comparisonType)
			{
			case StringComparison.Ordinal:
				return span.StartsWith(value);
			case StringComparison.OrdinalIgnoreCase:
				if (value.Length <= span.Length)
				{
					return EqualsOrdinalIgnoreCase(span.Slice(0, value.Length), value);
				}
				return false;
			default:
			{
				string text = span.ToString();
				string value2 = value.ToString();
				return text.StartsWith(value2, comparisonType);
			}
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ReadOnlySpan<char> AsSpan(this string text)
		{
			if (text == null)
			{
				return default(ReadOnlySpan<char>);
			}
			return new ReadOnlySpan<char>(Unsafe.As<Pinnable<char>>(text), StringAdjustment, text.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ReadOnlySpan<char> AsSpan(this string text, int start)
		{
			if (text == null)
			{
				if (start != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(ReadOnlySpan<char>);
			}
			if ((uint)start > (uint)text.Length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlySpan<char>(Unsafe.As<Pinnable<char>>(text), StringAdjustment + start * 2, text.Length - start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ReadOnlySpan<char> AsSpan(this string text, int start, int length)
		{
			if (text == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(ReadOnlySpan<char>);
			}
			if ((uint)start > (uint)text.Length || (uint)length > (uint)(text.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlySpan<char>(Unsafe.As<Pinnable<char>>(text), StringAdjustment + start * 2, length);
		}

		public static ReadOnlyMemory<char> AsMemory(this string text)
		{
			if (text == null)
			{
				return default(ReadOnlyMemory<char>);
			}
			return new ReadOnlyMemory<char>(text, 0, text.Length);
		}

		public static ReadOnlyMemory<char> AsMemory(this string text, int start)
		{
			if (text == null)
			{
				if (start != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(ReadOnlyMemory<char>);
			}
			if ((uint)start > (uint)text.Length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlyMemory<char>(text, start, text.Length - start);
		}

		public static ReadOnlyMemory<char> AsMemory(this string text, int start, int length)
		{
			if (text == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(ReadOnlyMemory<char>);
			}
			if ((uint)start > (uint)text.Length || (uint)length > (uint)(text.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlyMemory<char>(text, start, length);
		}

		private unsafe static IntPtr MeasureStringAdjustment()
		{
			string text = "a";
			fixed (char* source = text)
			{
				return Unsafe.ByteOffset(ref Unsafe.As<Pinnable<char>>(text).Data, ref Unsafe.AsRef<char>(source));
			}
		}
	}
	[DebuggerTypeProxy(typeof(System.MemoryDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	public readonly struct ReadOnlyMemory<T>
	{
		private readonly object _object;

		private readonly int _index;

		private readonly int _length;

		internal const int RemoveFlagsBitMask = int.MaxValue;

		public static ReadOnlyMemory<T> Empty => default(ReadOnlyMemory<T>);

		public int Length => _length & 0x7FFFFFFF;

		public bool IsEmpty => (_length & 0x7FFFFFFF) == 0;

		public ReadOnlySpan<T> Span
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				if (_index < 0)
				{
					return ((MemoryManager<T>)_object).GetSpan().Slice(_index & 0x7FFFFFFF, _length);
				}
				ReadOnlySpan<T> result;
				if (typeof(T) == typeof(char) && _object is string text)
				{
					result = new ReadOnlySpan<T>(Unsafe.As<Pinnable<T>>(text), MemoryExtensions.StringAdjustment, text.Length);
					return result.Slice(_index, _length);
				}
				if (_object != null)
				{
					return new ReadOnlySpan<T>((T[])_object, _index, _length & 0x7FFFFFFF);
				}
				result = default(ReadOnlySpan<T>);
				return result;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlyMemory(T[] array)
		{
			if (array == null)
			{
				this = default(ReadOnlyMemory<T>);
				return;
			}
			_object = array;
			_index = 0;
			_length = array.Length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlyMemory(T[] array, int start, int length)
		{
			if (array == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException();
				}
				this = default(ReadOnlyMemory<T>);
				return;
			}
			if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = array;
			_index = start;
			_length = length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal ReadOnlyMemory(object obj, int start, int length)
		{
			_object = obj;
			_index = start;
			_length = length;
		}

		public static implicit operator ReadOnlyMemory<T>(T[] array)
		{
			return new ReadOnlyMemory<T>(array);
		}

		public static implicit operator ReadOnlyMemory<T>(ArraySegment<T> segment)
		{
			return new ReadOnlyMemory<T>(segment.Array, segment.Offset, segment.Count);
		}

		public override string ToString()
		{
			if (typeof(T) == typeof(char))
			{
				if (!(_object is string text))
				{
					return Span.ToString();
				}
				return text.Substring(_index, _length & 0x7FFFFFFF);
			}
			return $"System.ReadOnlyMemory<{typeof(T).Name}>[{_length & 0x7FFFFFFF}]";
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlyMemory<T> Slice(int start)
		{
			int length = _length;
			int num = length & 0x7FFFFFFF;
			if ((uint)start > (uint)num)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlyMemory<T>(_object, _index + start, length - start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlyMemory<T> Slice(int start, int length)
		{
			int length2 = _length;
			int num = _length & 0x7FFFFFFF;
			if ((uint)start > (uint)num || (uint)length > (uint)(num - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlyMemory<T>(_object, _index + start, length | (length2 & int.MinValue));
		}

		public void CopyTo(Memory<T> destination)
		{
			Span.CopyTo(destination.Span);
		}

		public bool TryCopyTo(Memory<T> destination)
		{
			return Span.TryCopyTo(destination.Span);
		}

		public unsafe MemoryHandle Pin()
		{
			if (_index < 0)
			{
				return ((MemoryManager<T>)_object).Pin(_index & 0x7FFFFFFF);
			}
			if (typeof(T) == typeof(char) && _object is string value)
			{
				GCHandle handle = GCHandle.Alloc(value, GCHandleType.Pinned);
				void* pointer = Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer, handle);
			}
			if (_object is T[] array)
			{
				if (_length < 0)
				{
					void* pointer2 = Unsafe.Add<T>(Unsafe.AsPointer(ref MemoryMarshal.GetReference<T>(array)), _index);
					return new MemoryHandle(pointer2);
				}
				GCHandle handle2 = GCHandle.Alloc(array, GCHandleType.Pinned);
				void* pointer3 = Unsafe.Add<T>((void*)handle2.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer3, handle2);
			}
			return default(MemoryHandle);
		}

		public T[] ToArray()
		{
			return Span.ToArray();
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			if (obj is ReadOnlyMemory<T> other)
			{
				return Equals(other);
			}
			if (obj is Memory<T> memory)
			{
				return Equals(memory);
			}
			return false;
		}

		public bool Equals(ReadOnlyMemory<T> other)
		{
			if (_object == other._object && _index == other._index)
			{
				return _length == other._length;
			}
			return false;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			if (_object == null)
			{
				return 0;
			}
			int hashCode = _object.GetHashCode();
			int index = _index;
			int hashCode2 = index.GetHashCode();
			index = _length;
			return CombineHashCodes(hashCode, hashCode2, index.GetHashCode());
		}

		private static int CombineHashCodes(int left, int right)
		{
			return ((left << 5) + left) ^ right;
		}

		private static int CombineHashCodes(int h1, int h2, int h3)
		{
			return CombineHashCodes(CombineHashCodes(h1, h2), h3);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal object GetObjectStartLength(out int start, out int length)
		{
			start = _index;
			length = _length;
			return _object;
		}
	}
	[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	public readonly ref struct ReadOnlySpan<T>
	{
		public ref struct Enumerator
		{
			private readonly ReadOnlySpan<T> _span;

			private int _index;

			public ref readonly T Current
			{
				[MethodImpl(MethodImplOptions.AggressiveInlining)]
				get
				{
					return ref _span[_index];
				}
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			internal Enumerator(ReadOnlySpan<T> span)
			{
				_span = span;
				_index = -1;
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public bool MoveNext()
			{
				int num = _index + 1;
				if (num < _span.Length)
				{
					_index = num;
					return true;
				}
				return false;
			}
		}

		private readonly Pinnable<T> _pinnable;

		private readonly IntPtr _byteOffset;

		private readonly int _length;

		public int Length => _length;

		public bool IsEmpty => _length == 0;

		public static ReadOnlySpan<T> Empty => default(ReadOnlySpan<T>);

		public unsafe ref readonly T this[int index]
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				if ((uint)index >= (uint)_length)
				{
					System.ThrowHelper.ThrowIndexOutOfRangeException();
				}
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					return ref Unsafe.Add(ref Unsafe.AsRef<T>(byteOffset.ToPointer()), index);
				}
				return ref Unsafe.Add(ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset), index);
			}
		}

		internal Pinnable<T> Pinnable => _pinnable;

		internal IntPtr ByteOffset => _byteOffset;

		public static bool operator !=(ReadOnlySpan<T> left, ReadOnlySpan<T> right)
		{
			return !(left == right);
		}

		[Obsolete("Equals() on ReadOnlySpan will always throw an exception. Use == instead.")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			throw new NotSupportedException(System.SR.NotSupported_CannotCallEqualsOnSpan);
		}

		[Obsolete("GetHashCode() on ReadOnlySpan will always throw an exception.")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			throw new NotSupportedException(System.SR.NotSupported_CannotCallGetHashCodeOnSpan);
		}

		public static implicit operator ReadOnlySpan<T>(T[] array)
		{
			return new ReadOnlySpan<T>(array);
		}

		public static implicit operator ReadOnlySpan<T>(ArraySegment<T> segment)
		{
			return new ReadOnlySpan<T>(segment.Array, segment.Offset, segment.Count);
		}

		public Enumerator GetEnumerator()
		{
			return new Enumerator(this);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlySpan(T[] array)
		{
			if (array == null)
			{
				this = default(ReadOnlySpan<T>);
				return;
			}
			_length = array.Length;
			_pinnable = Unsafe.As<Pinnable<T>>(array);
			_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlySpan(T[] array, int start, int length)
		{
			if (array == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				this = default(ReadOnlySpan<T>);
				return;
			}
			if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			_length = length;
			_pinnable = Unsafe.As<Pinnable<T>>(array);
			_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment.Add<T>(start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[CLSCompliant(false)]
		public unsafe ReadOnlySpan(void* pointer, int length)
		{
			if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
			{
				System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
			}
			if (length < 0)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			_length = length;
			_pinnable = null;
			_byteOffset = new IntPtr(pointer);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal ReadOnlySpan(Pinnable<T> pinnable, IntPtr byteOffset, int length)
		{
			_length = length;
			_pinnable = pinnable;
			_byteOffset = byteOffset;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public unsafe ref readonly T GetPinnableReference()
		{
			if (_length != 0)
			{
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					return ref Unsafe.AsRef<T>(byteOffset.ToPointer());
				}
				return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset);
			}
			return ref Unsafe.AsRef<T>(null);
		}

		public void CopyTo(Span<T> destination)
		{
			if (!TryCopyTo(destination))
			{
				System.ThrowHelper.ThrowArgumentException_DestinationTooShort();
			}
		}

		public bool TryCopyTo(Span<T> destination)
		{
			int length = _length;
			int length2 = destination.Length;
			if (length == 0)
			{
				return true;
			}
			if ((uint)length > (uint)length2)
			{
				return false;
			}
			ref T src = ref DangerousGetPinnableReference();
			System.SpanHelpers.CopyTo(ref destination.DangerousGetPinnableReference(), length2, ref src, length);
			return true;
		}

		public static bool operator ==(ReadOnlySpan<T> left, ReadOnlySpan<T> right)
		{
			if (left._length == right._length)
			{
				return Unsafe.AreSame(ref left.DangerousGetPinnableReference(), ref right.DangerousGetPinnableReference());
			}
			return false;
		}

		public unsafe override string ToString()
		{
			if (typeof(T) == typeof(char))
			{
				if (_byteOffset == MemoryExtensions.StringAdjustment)
				{
					object obj = Unsafe.As<object>(_pinnable);
					if (obj is string text && _length == text.Length)
					{
						return text;
					}
				}
				fixed (char* value = &Unsafe.As<T, char>(ref DangerousGetPinnableReference()))
				{
					return new string(value, 0, _length);
				}
			}
			return $"System.ReadOnlySpan<{typeof(T).Name}>[{_length}]";
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlySpan<T> Slice(int start)
		{
			if ((uint)start > (uint)_length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = _byteOffset.Add<T>(start);
			int length = _length - start;
			return new ReadOnlySpan<T>(_pinnable, byteOffset, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlySpan<T> Slice(int start, int length)
		{
			if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = _byteOffset.Add<T>(start);
			return new ReadOnlySpan<T>(_pinnable, byteOffset, length);
		}

		public T[] ToArray()
		{
			if (_length == 0)
			{
				return System.SpanHelpers.PerTypeValues<T>.EmptyArray;
			}
			T[] array = new T[_length];
			CopyTo(array);
			return array;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[EditorBrowsable(EditorBrowsableState.Never)]
		internal unsafe ref T DangerousGetPinnableReference()
		{
			if (_pinnable == null)
			{
				IntPtr byteOffset = _byteOffset;
				return ref Unsafe.AsRef<T>(byteOffset.ToPointer());
			}
			return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset);
		}
	}
	[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	public readonly ref struct Span<T>
	{
		public ref struct Enumerator
		{
			private readonly Span<T> _span;

			private int _index;

			public ref T Current
			{
				[MethodImpl(MethodImplOptions.AggressiveInlining)]
				get
				{
					return ref _span[_index];
				}
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			internal Enumerator(Span<T> span)
			{
				_span = span;
				_index = -1;
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public bool MoveNext()
			{
				int num = _index + 1;
				if (num < _span.Length)
				{
					_index = num;
					return true;
				}
				return false;
			}
		}

		private readonly Pinnable<T> _pinnable;

		private readonly IntPtr _byteOffset;

		private readonly int _length;

		public int Length => _length;

		public bool IsEmpty => _length == 0;

		public static Span<T> Empty => default(Span<T>);

		public unsafe ref T this[int index]
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				if ((uint)index >= (uint)_length)
				{
					System.ThrowHelper.ThrowIndexOutOfRangeException();
				}
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					return ref Unsafe.Add(ref Unsafe.AsRef<T>(byteOffset.ToPointer()), index);
				}
				return ref Unsafe.Add(ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset), index);
			}
		}

		internal Pinnable<T> Pinnable => _pinnable;

		internal IntPtr ByteOffset => _byteOffset;

		public static bool operator !=(Span<T> left, Span<T> right)
		{
			return !(left == right);
		}

		[Obsolete("Equals() on Span will always throw an exception. Use == instead.")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			throw new NotSupportedException(System.SR.NotSupported_CannotCallEqualsOnSpan);
		}

		[Obsolete("GetHashCode() on Span will always throw an exception.")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			throw new NotSupportedException(System.SR.NotSupported_CannotCallGetHashCodeOnSpan);
		}

		public static implicit operator Span<T>(T[] array)
		{
			return new Span<T>(array);
		}

		public static implicit operator Span<T>(ArraySegment<T> segment)
		{
			return new Span<T>(segment.Array, segment.Offset, segment.Count);
		}

		public Enumerator GetEnumerator()
		{
			return new Enumerator(this);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span(T[] array)
		{
			if (array == null)
			{
				this = default(Span<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			_length = array.Length;
			_pinnable = Unsafe.As<Pinnable<T>>(array);
			_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static Span<T> Create(T[] array, int start)
		{
			if (array == null)
			{
				if (start != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(Span<T>);
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			if ((uint)start > (uint)array.Length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment.Add<T>(start);
			int length = array.Length - start;
			return new Span<T>(Unsafe.As<Pinnable<T>>(array), byteOffset, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span(T[] array, int start, int length)
		{
			if (array == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				this = default(Span<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			_length = length;
			_pinnable = Unsafe.As<Pinnable<T>>(array);
			_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment.Add<T>(start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[CLSCompliant(false)]
		public unsafe Span(void* pointer, int length)
		{
			if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
			{
				System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
			}
			if (length < 0)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			_length = length;
			_pinnable = null;
			_byteOffset = new IntPtr(pointer);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Span(Pinnable<T> pinnable, IntPtr byteOffset, int length)
		{
			_length = length;
			_pinnable = pinnable;
			_byteOffset = byteOffset;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public unsafe ref T GetPinnableReference()
		{
			if (_length != 0)
			{
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					return ref Unsafe.AsRef<T>(byteOffset.ToPointer());
				}
				return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset);
			}
			return ref Unsafe.AsRef<T>(null);
		}

		public unsafe void Clear()
		{
			int length = _length;
			if (length == 0)
			{
				return;
			}
			UIntPtr byteLength = (UIntPtr)(ulong)((uint)length * Unsafe.SizeOf<T>());
			if ((Unsafe.SizeOf<T>() & (sizeof(IntPtr) - 1)) != 0)
			{
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					byte* ptr = (byte*)byteOffset.ToPointer();
					System.SpanHelpers.ClearLessThanPointerSized(ptr, byteLength);
				}
				else
				{
					System.SpanHelpers.ClearLessThanPointerSized(ref Unsafe.As<T, byte>(ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset)), byteLength);
				}
			}
			else if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
			{
				UIntPtr pointerSizeLength = (UIntPtr)(ulong)(length * Unsafe.SizeOf<T>() / sizeof(IntPtr));
				System.SpanHelpers.ClearPointerSizedWithReferences(ref Unsafe.As<T, IntPtr>(ref DangerousGetPinnableReference()), pointerSizeLength);
			}
			else
			{
				System.SpanHelpers.ClearPointerSizedWithoutReferences(ref Unsafe.As<T, byte>(ref DangerousGetPinnableReference()), byteLength);
			}
		}

		public unsafe void Fill(T value)
		{
			int length = _length;
			if (length == 0)
			{
				return;
			}
			if (Unsafe.SizeOf<T>() == 1)
			{
				byte value2 = Unsafe.As<T, byte>(ref value);
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					Unsafe.InitBlockUnaligned(byteOffset.ToPointer(), value2, (uint)length);
				}
				else
				{
					Unsafe.InitBlockUnaligned(ref Unsafe.As<T, byte>(ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset)), value2, (uint)length);
				}
				return;
			}
			ref T source = ref DangerousGetPinnableReference();
			int i;
			for (i = 0; i < (length & -8); i += 8)
			{
				Unsafe.Add(ref source, i) = value;
				Unsafe.Add(ref source, i + 1) = value;
				Unsafe.Add(ref source, i + 2) = value;
				Unsafe.Add(ref source, i + 3) = value;
				Unsafe.Add(ref source, i + 4) = value;
				Unsafe.Add(ref source, i + 5) = value;
				Unsafe.Add(ref source, i + 6) = value;
				Unsafe.Add(ref source, i + 7) = value;
			}
			if (i < (length & -4))
			{
				Unsafe.Add(ref source, i) = value;
				Unsafe.Add(ref source, i + 1) = value;
				Unsafe.Add(ref source, i + 2) = value;
				Unsafe.Add(ref source, i + 3) = value;
				i += 4;
			}
			for (; i < length; i++)
			{
				Unsafe.Add(ref source, i) = value;
			}
		}

		public void CopyTo(Span<T> destination)
		{
			if (!TryCopyTo(destination))
			{
				System.ThrowHelper.ThrowArgumentException_DestinationTooShort();
			}
		}

		public bool TryCopyTo(Span<T> destination)
		{
			int length = _length;
			int length2 = destination._length;
			if (length == 0)
			{
				return true;
			}
			if ((uint)length > (uint)length2)
			{
				return false;
			}
			ref T src = ref DangerousGetPinnableReference();
			System.SpanHelpers.CopyTo(ref destination.DangerousGetPinnableReference(), length2, ref src, length);
			return true;
		}

		public static bool operator ==(Span<T> left, Span<T> right)
		{
			if (left._length == right._length)
			{
				return Unsafe.AreSame(ref left.DangerousGetPinnableReference(), ref right.DangerousGetPinnableReference());
			}
			return false;
		}

		public static implicit operator ReadOnlySpan<T>(Span<T> span)
		{
			return new ReadOnlySpan<T>(span._pinnable, span._byteOffset, span._length);
		}

		public unsafe override string ToString()
		{
			if (typeof(T) == typeof(char))
			{
				fixed (char* value = &Unsafe.As<T, char>(ref DangerousGetPinnableReference()))
				{
					return new string(value, 0, _length);
				}
			}
			return $"System.Span<{typeof(T).Name}>[{_length}]";
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span<T> Slice(int start)
		{
			if ((uint)start > (uint)_length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = _byteOffset.Add<T>(start);
			int length = _length - start;
			return new Span<T>(_pinnable, byteOffset, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span<T> Slice(int start, int length)
		{
			if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = _byteOffset.Add<T>(start);
			return new Span<T>(_pinnable, byteOffset, length);
		}

		public T[] ToArray()
		{
			if (_length == 0)
			{
				return System.SpanHelpers.PerTypeValues<T>.EmptyArray;
			}
			T[] array = new T[_length];
			CopyTo(array);
			return array;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[EditorBrowsable(EditorBrowsableState.Never)]
		internal unsafe ref T DangerousGetPinnableReference()
		{
			if (_pinnable == null)
			{
				IntPtr byteOffset = _byteOffset;
				return ref Unsafe.AsRef<T>(byteOffset.ToPointer());
			}
			return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset);
		}
	}
	internal sealed class SpanDebugView<T>
	{
		private readonly T[] _array;

		[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
		public T[] Items => _array;

		public SpanDebugView(Span<T> span)
		{
			_array = span.ToArray();
		}

		public SpanDebugView(ReadOnlySpan<T> span)
		{
			_array = span.ToArray();
		}
	}
	internal static class SpanHelpers
	{
		internal struct ComparerComparable<T, TComparer> : IComparable<T> where TComparer : IComparer<T>
		{
			private readonly T _value;

			private readonly TComparer _comparer;

			public ComparerComparable(T value, TComparer comparer)
			{
				_value = value;
				_comparer = comparer;
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public int CompareTo(T other)
			{
				return _comparer.Compare(_value, other);
			}
		}

		[StructLayout(LayoutKind.Sequential, Size = 64)]
		private struct Reg64
		{
		}

		[StructLayout(LayoutKind.Sequential, Size = 32)]
		private struct Reg32
		{
		}

		[StructLayout(LayoutKind.Sequential, Size = 16)]
		private struct Reg16
		{
		}

		public static class PerTypeValues<T>
		{
			public static readonly bool IsReferenceOrContainsReferences = IsReferenceOrContainsReferencesCore(typeof(T));

			public static readonly T[] EmptyArray = new T[0];

			public static readonly IntPtr ArrayAdjustment = MeasureArrayAdjustment();

			private static IntPtr MeasureArrayAdjustment()
			{
				T[] array = new T[1];
				return Unsafe.ByteOffset(ref Unsafe.As<Pinnable<T>>(array).Data, ref array[0]);
			}
		}

		private const ulong XorPowerOfTwoToHighByte = 283686952306184uL;

		private const ulong XorPowerOfTwoToHighChar = 4295098372uL;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparable>(this ReadOnlySpan<T> span, TComparable comparable) where TComparable : IComparable<T>
		{
			if (comparable == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.comparable);
			}
			return BinarySearch(ref MemoryMarshal.GetReference(span), span.Length, comparable);
		}

		public static int BinarySearch<T, TComparable>(ref T spanStart, int length, TComparable comparable) where TComparable : IComparable<T>
		{
			int num = 0;
			int num2 = length - 1;
			while (num <= num2)
			{
				int num3 = num2 + num >>> 1;
				int num4 = comparable.CompareTo(Unsafe.Add(ref spanStart, num3));
				if (num4 == 0)
				{
					return num3;
				}
				if (num4 > 0)
				{
					num = num3 + 1;
				}
				else
				{
					num2 = num3 - 1;
				}
			}
			return ~num;
		}

		public static int IndexOf(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength)
		{
			if (valueLength == 0)
			{
				return 0;
			}
			byte value2 = value;
			ref byte second = ref Unsafe.Add(ref value, 1);
			int num = valueLength - 1;
			int num2 = 0;
			while (true)
			{
				int num3 = searchSpaceLength - num2 - num;
				if (num3 <= 0)
				{
					break;
				}
				int num4 = IndexOf(ref Unsafe.Add(ref searchSpace, num2), value2, num3);
				if (num4 == -1)
				{
					break;
				}
				num2 += num4;
				if (SequenceEqual(ref Unsafe.Add(ref searchSpace, num2 + 1), ref second, num))
				{
					return num2;
				}
				num2++;
			}
			return -1;
		}

		public static int IndexOfAny(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength)
		{
			if (valueLength == 0)
			{
				return 0;
			}
			int num = -1;
			for (int i = 0; i < valueLength; i++)
			{
				int num2 = IndexOf(ref searchSpace, Unsafe.Add(ref value, i), searchSpaceLength);
				if ((uint)num2 < (uint)num)
				{
					num = num2;
					searchSpaceLength = num2;
					if (num == 0)
					{
						break;
					}
				}
			}
			return num;
		}

		public static int LastIndexOfAny(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength)
		{
			if (valueLength == 0)
			{
				return 0;
			}
			int num = -1;
			for (int i = 0; i < valueLength; i++)
			{
				int num2 = LastIndexOf(ref searchSpace, Unsafe.Add(ref value, i), searchSpaceLength);
				if (num2 > num)
				{
					num = num2;
				}
			}
			return num;
		}

		public unsafe static int IndexOf(ref byte searchSpace, byte value, int length)
		{
			IntPtr intPtr = (IntPtr)0;
			IntPtr intPtr2 = (IntPtr)length;
			if (Vector.IsHardwareAccelerated && length >= Vector<byte>.Count * 2)
			{
				int num = (int)Unsafe.AsPointer(ref searchSpace) & (Vector<byte>.Count - 1);
				intPtr2 = (IntPtr)((Vector<byte>.Count - num) & (Vector<byte>.Count - 1));
			}
			while (true)
			{
				if ((nuint)(void*)intPtr2 >= (nuint)8u)
				{
					intPtr2 -= 8;
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr))
					{
						goto IL_0242;
					}
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 1))
					{
						goto IL_024a;
					}
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 2))
					{
						goto IL_0258;
					}
					if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 3))
					{
						if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 4))
						{
							if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 5))
							{
								if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 6))
								{
									if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 7))
									{
										break;
									}
									intPtr += 8;
									continue;
								}
								return (int)(void*)(intPtr + 6);
							}
							return (int)(void*)(intPtr + 5);
						}
						return (int)(void*)(intPtr + 4);
					}
					goto IL_0266;
				}
				if ((nuint)(void*)intPtr2 >= (nuint)4u)
				{
					intPtr2 -= 4;
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr))
					{
						goto IL_0242;
					}
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 1))
					{
						goto IL_024a;
					}
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 2))
					{
						goto IL_0258;
					}
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 3))
					{
						goto IL_0266;
					}
					intPtr += 4;
				}
				while ((void*)intPtr2 != null)
				{
					intPtr2 -= 1;
					if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr))
					{
						intPtr += 1;
						continue;
					}
					goto IL_0242;
				}
				if (Vector.IsHardwareAccelerated && (int)(void*)intPtr < length)
				{
					intPtr2 = (IntPtr)((length - (int)(void*)intPtr) & ~(Vector<byte>.Count - 1));
					Vector<byte> vector = GetVector(value);
					for (; (void*)intPtr2 > (void*)intPtr; intPtr += Vector<byte>.Count)
					{
						Vector<byte> vector2 = Vector.Equals(vector, Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref searchSpace, intPtr)));
						if (!Vector<byte>.Zero.Equals(vector2))
						{
							return (int)(void*)intPtr + LocateFirstFoundByte(vector2);
						}
					}
					if ((int)(void*)intPtr < length)
					{
						intPtr2 = (IntPtr)(length - (int)(void*)intPtr);
						continue;
					}
				}
				return -1;
				IL_0266:
				return (int)(void*)(intPtr + 3);
				IL_0242:
				return (int)(void*)intPtr;
				IL_0258:
				return (int)(void*)(intPtr + 2);
				IL_024a:
				return (int)(void*)(intPtr + 1);
			}
			return (int)(void*)(intPtr + 7);
		}

		public static int LastIndexOf(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength)
		{
			if (valueLength == 0)
			{
				return 0;
			}
			byte value2 = value;
			ref byte second = ref Unsafe.Add(ref value, 1);
			int num = valueLength - 1;
			int num2 = 0;
			while (true)
			{
				int num3 = searchSpaceLength - num2 - num;
				if (num3 <= 0)
				{
					break;
				}
				int num4 = LastIndexOf(ref searchSpace, value2, num3);
				if (num4 == -1)
				{
					break;
				}
				if (SequenceEqual(ref Unsafe.Add(ref searchSpace, num4 + 1), ref second, num))
				{
					return num4;
				}
				num2 += num3 - num4;
			}
			return -1;
		}

		public unsafe static int LastIndexOf(ref byte searchSpace, byte value, int length)
		{
			IntPtr intPtr = (IntPtr)length;
			IntPtr intPtr2 = (IntPtr)length;
			if (Vector.IsHardwareAccelerated && length >= Vector<byte>.Count * 2)
			{
				int num = (int)Unsafe.AsPointer(ref searchSpace) & (Vector<byte>.Count - 1);
				intPtr2 = (IntPtr)(((length & (Vector<byte>.Count - 1)) + num) & (Vector<byte>.Count - 1));
			}
			while (true)
			{
				if ((nuint)(void*)intPtr2 >= (nuint)8u)
				{
					intPtr2 -= 8;
					intPtr -= 8;
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 7))
					{
						break;
					}
					if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 6))
					{
						if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 5))
						{
							if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 4))
							{
								if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 3))
								{
									if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 2))
									{
										if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 1))
										{
											if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr))
											{
												continue;
											}
											goto IL_0254;
										}
										goto IL_025c;
									}
									goto IL_026a;
								}
								goto IL_0278;
							}
							return (int)(void*)(intPtr + 4);
						}
						return (int)(void*)(intPtr + 5);
					}
					return (int)(void*)(intPtr + 6);
				}
				if ((nuint)(void*)intPtr2 >= (nuint)4u)
				{
					intPtr2 -= 4;
					intPtr -= 4;
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 3))
					{
						goto IL_0278;
					}
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 2))
					{
						goto IL_026a;
					}
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 1))
					{
						goto IL_025c;
					}
					if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr))
					{
						goto IL_0254;
					}
				}
				while ((void*)intPtr2 != null)
				{
					intPtr2 -= 1;
					intPtr -= 1;
					if (val

System.Numerics.Vectors.dll

Decompiled 14 hours ago
using System;
using System.Diagnostics;
using System.Globalization;
using System.Numerics.Hashing;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using FxResources.System.Numerics.Vectors;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyTitle("System.Numerics.Vectors")]
[assembly: AssemblyDescription("System.Numerics.Vectors")]
[assembly: AssemblyDefaultAlias("System.Numerics.Vectors")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: AssemblyCopyright("© Microsoft Corporation.  All rights reserved.")]
[assembly: AssemblyFileVersion("4.6.25519.03")]
[assembly: AssemblyInformationalVersion("4.6.25519.03 built by: dlab-DDVSOWINAGE013. Commit Hash: 8321c729934c0f8be754953439b88e6e1c120c24")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.1.3.0")]
[module: UnverifiableCode]
namespace FxResources.System.Numerics.Vectors
{
	internal static class SR
	{
	}
}
namespace System
{
	internal static class MathF
	{
		public const float PI = 3.1415927f;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Abs(float x)
		{
			return Math.Abs(x);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Acos(float x)
		{
			return (float)Math.Acos(x);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Cos(float x)
		{
			return (float)Math.Cos(x);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float IEEERemainder(float x, float y)
		{
			return (float)Math.IEEERemainder(x, y);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Sin(float x)
		{
			return (float)Math.Sin(x);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Sqrt(float x)
		{
			return (float)Math.Sqrt(x);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Tan(float x)
		{
			return (float)Math.Tan(x);
		}
	}
	internal static class SR
	{
		private static ResourceManager s_resourceManager;

		private const string s_resourcesName = "FxResources.System.Numerics.Vectors.SR";

		private static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(ResourceType));

		internal static string Arg_ArgumentOutOfRangeException => GetResourceString("Arg_ArgumentOutOfRangeException", null);

		internal static string Arg_ElementsInSourceIsGreaterThanDestination => GetResourceString("Arg_ElementsInSourceIsGreaterThanDestination", null);

		internal static string Arg_NullArgumentNullRef => GetResourceString("Arg_NullArgumentNullRef", null);

		internal static string Arg_TypeNotSupported => GetResourceString("Arg_TypeNotSupported", null);

		internal static Type ResourceType => typeof(SR);

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static bool UsingResourceKeys()
		{
			return false;
		}

		internal static string GetResourceString(string resourceKey, string defaultString)
		{
			string text = null;
			try
			{
				text = ResourceManager.GetString(resourceKey);
			}
			catch (MissingManifestResourceException)
			{
			}
			if (defaultString != null && resourceKey.Equals(text, StringComparison.Ordinal))
			{
				return defaultString;
			}
			return text;
		}

		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(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);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.All)]
	internal class __BlockReflectionAttribute : Attribute
	{
	}
}
namespace System.Numerics
{
	internal class ConstantHelper
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static byte GetByteWithAllBitsSet()
		{
			byte result = 0;
			result = byte.MaxValue;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static sbyte GetSByteWithAllBitsSet()
		{
			sbyte result = 0;
			result = -1;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ushort GetUInt16WithAllBitsSet()
		{
			ushort result = 0;
			result = ushort.MaxValue;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static short GetInt16WithAllBitsSet()
		{
			short result = 0;
			result = -1;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static uint GetUInt32WithAllBitsSet()
		{
			uint result = 0u;
			result = uint.MaxValue;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int GetInt32WithAllBitsSet()
		{
			int result = 0;
			result = -1;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ulong GetUInt64WithAllBitsSet()
		{
			ulong result = 0uL;
			result = ulong.MaxValue;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static long GetInt64WithAllBitsSet()
		{
			long result = 0L;
			result = -1L;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static float GetSingleWithAllBitsSet()
		{
			float result = 0f;
			*(int*)(&result) = -1;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static double GetDoubleWithAllBitsSet()
		{
			double result = 0.0;
			*(long*)(&result) = -1L;
			return result;
		}
	}
	[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property)]
	internal class JitIntrinsicAttribute : Attribute
	{
	}
	[StructLayout(LayoutKind.Explicit)]
	internal struct Register
	{
		[FieldOffset(0)]
		internal byte byte_0;

		[FieldOffset(1)]
		internal byte byte_1;

		[FieldOffset(2)]
		internal byte byte_2;

		[FieldOffset(3)]
		internal byte byte_3;

		[FieldOffset(4)]
		internal byte byte_4;

		[FieldOffset(5)]
		internal byte byte_5;

		[FieldOffset(6)]
		internal byte byte_6;

		[FieldOffset(7)]
		internal byte byte_7;

		[FieldOffset(8)]
		internal byte byte_8;

		[FieldOffset(9)]
		internal byte byte_9;

		[FieldOffset(10)]
		internal byte byte_10;

		[FieldOffset(11)]
		internal byte byte_11;

		[FieldOffset(12)]
		internal byte byte_12;

		[FieldOffset(13)]
		internal byte byte_13;

		[FieldOffset(14)]
		internal byte byte_14;

		[FieldOffset(15)]
		internal byte byte_15;

		[FieldOffset(0)]
		internal sbyte sbyte_0;

		[FieldOffset(1)]
		internal sbyte sbyte_1;

		[FieldOffset(2)]
		internal sbyte sbyte_2;

		[FieldOffset(3)]
		internal sbyte sbyte_3;

		[FieldOffset(4)]
		internal sbyte sbyte_4;

		[FieldOffset(5)]
		internal sbyte sbyte_5;

		[FieldOffset(6)]
		internal sbyte sbyte_6;

		[FieldOffset(7)]
		internal sbyte sbyte_7;

		[FieldOffset(8)]
		internal sbyte sbyte_8;

		[FieldOffset(9)]
		internal sbyte sbyte_9;

		[FieldOffset(10)]
		internal sbyte sbyte_10;

		[FieldOffset(11)]
		internal sbyte sbyte_11;

		[FieldOffset(12)]
		internal sbyte sbyte_12;

		[FieldOffset(13)]
		internal sbyte sbyte_13;

		[FieldOffset(14)]
		internal sbyte sbyte_14;

		[FieldOffset(15)]
		internal sbyte sbyte_15;

		[FieldOffset(0)]
		internal ushort uint16_0;

		[FieldOffset(2)]
		internal ushort uint16_1;

		[FieldOffset(4)]
		internal ushort uint16_2;

		[FieldOffset(6)]
		internal ushort uint16_3;

		[FieldOffset(8)]
		internal ushort uint16_4;

		[FieldOffset(10)]
		internal ushort uint16_5;

		[FieldOffset(12)]
		internal ushort uint16_6;

		[FieldOffset(14)]
		internal ushort uint16_7;

		[FieldOffset(0)]
		internal short int16_0;

		[FieldOffset(2)]
		internal short int16_1;

		[FieldOffset(4)]
		internal short int16_2;

		[FieldOffset(6)]
		internal short int16_3;

		[FieldOffset(8)]
		internal short int16_4;

		[FieldOffset(10)]
		internal short int16_5;

		[FieldOffset(12)]
		internal short int16_6;

		[FieldOffset(14)]
		internal short int16_7;

		[FieldOffset(0)]
		internal uint uint32_0;

		[FieldOffset(4)]
		internal uint uint32_1;

		[FieldOffset(8)]
		internal uint uint32_2;

		[FieldOffset(12)]
		internal uint uint32_3;

		[FieldOffset(0)]
		internal int int32_0;

		[FieldOffset(4)]
		internal int int32_1;

		[FieldOffset(8)]
		internal int int32_2;

		[FieldOffset(12)]
		internal int int32_3;

		[FieldOffset(0)]
		internal ulong uint64_0;

		[FieldOffset(8)]
		internal ulong uint64_1;

		[FieldOffset(0)]
		internal long int64_0;

		[FieldOffset(8)]
		internal long int64_1;

		[FieldOffset(0)]
		internal float single_0;

		[FieldOffset(4)]
		internal float single_1;

		[FieldOffset(8)]
		internal float single_2;

		[FieldOffset(12)]
		internal float single_3;

		[FieldOffset(0)]
		internal double double_0;

		[FieldOffset(8)]
		internal double double_1;
	}
	public struct Vector<T> : IEquatable<Vector<T>>, IFormattable where T : struct
	{
		private struct VectorSizeHelper
		{
			internal Vector<T> _placeholder;

			internal byte _byte;
		}

		private System.Numerics.Register register;

		private static readonly int s_count = InitializeCount();

		private static readonly Vector<T> zero = new Vector<T>(GetZeroValue());

		private static readonly Vector<T> one = new Vector<T>(GetOneValue());

		private static readonly Vector<T> allOnes = new Vector<T>(GetAllBitsSetValue());

		[JitIntrinsic]
		public static int Count => s_count;

		[JitIntrinsic]
		public static Vector<T> Zero => zero;

		[JitIntrinsic]
		public static Vector<T> One => one;

		internal static Vector<T> AllOnes => allOnes;

		[JitIntrinsic]
		public unsafe T this[int index]
		{
			get
			{
				if (index >= Count || index < 0)
				{
					throw new IndexOutOfRangeException(System.SR.Format(System.SR.Arg_ArgumentOutOfRangeException, index));
				}
				if (typeof(T) == typeof(byte))
				{
					fixed (byte* ptr = &register.byte_0)
					{
						return (T)(object)ptr[index];
					}
				}
				if (typeof(T) == typeof(sbyte))
				{
					fixed (sbyte* ptr2 = &register.sbyte_0)
					{
						return (T)(object)ptr2[index];
					}
				}
				if (typeof(T) == typeof(ushort))
				{
					fixed (ushort* ptr3 = &register.uint16_0)
					{
						return (T)(object)ptr3[index];
					}
				}
				if (typeof(T) == typeof(short))
				{
					fixed (short* ptr4 = &register.int16_0)
					{
						return (T)(object)ptr4[index];
					}
				}
				if (typeof(T) == typeof(uint))
				{
					fixed (uint* ptr5 = &register.uint32_0)
					{
						return (T)(object)ptr5[index];
					}
				}
				if (typeof(T) == typeof(int))
				{
					fixed (int* ptr6 = &register.int32_0)
					{
						return (T)(object)ptr6[index];
					}
				}
				if (typeof(T) == typeof(ulong))
				{
					fixed (ulong* ptr7 = &register.uint64_0)
					{
						return (T)(object)ptr7[index];
					}
				}
				if (typeof(T) == typeof(long))
				{
					fixed (long* ptr8 = &register.int64_0)
					{
						return (T)(object)ptr8[index];
					}
				}
				if (typeof(T) == typeof(float))
				{
					fixed (float* ptr9 = &register.single_0)
					{
						return (T)(object)ptr9[index];
					}
				}
				if (typeof(T) == typeof(double))
				{
					fixed (double* ptr10 = &register.double_0)
					{
						return (T)(object)ptr10[index];
					}
				}
				throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
			}
		}

		private unsafe static int InitializeCount()
		{
			VectorSizeHelper vectorSizeHelper = default(VectorSizeHelper);
			byte* ptr = &vectorSizeHelper._placeholder.register.byte_0;
			byte* ptr2 = &vectorSizeHelper._byte;
			int num = (int)(ptr2 - ptr);
			int num2 = -1;
			if (typeof(T) == typeof(byte))
			{
				num2 = 1;
			}
			else if (typeof(T) == typeof(sbyte))
			{
				num2 = 1;
			}
			else if (typeof(T) == typeof(ushort))
			{
				num2 = 2;
			}
			else if (typeof(T) == typeof(short))
			{
				num2 = 2;
			}
			else if (typeof(T) == typeof(uint))
			{
				num2 = 4;
			}
			else if (typeof(T) == typeof(int))
			{
				num2 = 4;
			}
			else if (typeof(T) == typeof(ulong))
			{
				num2 = 8;
			}
			else if (typeof(T) == typeof(long))
			{
				num2 = 8;
			}
			else if (typeof(T) == typeof(float))
			{
				num2 = 4;
			}
			else
			{
				if (!(typeof(T) == typeof(double)))
				{
					throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
				}
				num2 = 8;
			}
			return num / num2;
		}

		[JitIntrinsic]
		public unsafe Vector(T value)
		{
			this = default(Vector<T>);
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					fixed (byte* ptr = &register.byte_0)
					{
						for (int i = 0; i < Count; i++)
						{
							ptr[i] = (byte)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(sbyte))
				{
					fixed (sbyte* ptr2 = &register.sbyte_0)
					{
						for (int j = 0; j < Count; j++)
						{
							ptr2[j] = (sbyte)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(ushort))
				{
					fixed (ushort* ptr3 = &register.uint16_0)
					{
						for (int k = 0; k < Count; k++)
						{
							ptr3[k] = (ushort)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(short))
				{
					fixed (short* ptr4 = &register.int16_0)
					{
						for (int l = 0; l < Count; l++)
						{
							ptr4[l] = (short)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(uint))
				{
					fixed (uint* ptr5 = &register.uint32_0)
					{
						for (int m = 0; m < Count; m++)
						{
							ptr5[m] = (uint)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(int))
				{
					fixed (int* ptr6 = &register.int32_0)
					{
						for (int n = 0; n < Count; n++)
						{
							ptr6[n] = (int)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(ulong))
				{
					fixed (ulong* ptr7 = &register.uint64_0)
					{
						for (int num = 0; num < Count; num++)
						{
							ptr7[num] = (ulong)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(long))
				{
					fixed (long* ptr8 = &register.int64_0)
					{
						for (int num2 = 0; num2 < Count; num2++)
						{
							ptr8[num2] = (long)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(float))
				{
					fixed (float* ptr9 = &register.single_0)
					{
						for (int num3 = 0; num3 < Count; num3++)
						{
							ptr9[num3] = (float)(object)value;
						}
					}
				}
				else
				{
					if (!(typeof(T) == typeof(double)))
					{
						return;
					}
					fixed (double* ptr10 = &register.double_0)
					{
						for (int num4 = 0; num4 < Count; num4++)
						{
							ptr10[num4] = (double)(object)value;
						}
					}
				}
			}
			else if (typeof(T) == typeof(byte))
			{
				register.byte_0 = (byte)(object)value;
				register.byte_1 = (byte)(object)value;
				register.byte_2 = (byte)(object)value;
				register.byte_3 = (byte)(object)value;
				register.byte_4 = (byte)(object)value;
				register.byte_5 = (byte)(object)value;
				register.byte_6 = (byte)(object)value;
				register.byte_7 = (byte)(object)value;
				register.byte_8 = (byte)(object)value;
				register.byte_9 = (byte)(object)value;
				register.byte_10 = (byte)(object)value;
				register.byte_11 = (byte)(object)value;
				register.byte_12 = (byte)(object)value;
				register.byte_13 = (byte)(object)value;
				register.byte_14 = (byte)(object)value;
				register.byte_15 = (byte)(object)value;
			}
			else if (typeof(T) == typeof(sbyte))
			{
				register.sbyte_0 = (sbyte)(object)value;
				register.sbyte_1 = (sbyte)(object)value;
				register.sbyte_2 = (sbyte)(object)value;
				register.sbyte_3 = (sbyte)(object)value;
				register.sbyte_4 = (sbyte)(object)value;
				register.sbyte_5 = (sbyte)(object)value;
				register.sbyte_6 = (sbyte)(object)value;
				register.sbyte_7 = (sbyte)(object)value;
				register.sbyte_8 = (sbyte)(object)value;
				register.sbyte_9 = (sbyte)(object)value;
				register.sbyte_10 = (sbyte)(object)value;
				register.sbyte_11 = (sbyte)(object)value;
				register.sbyte_12 = (sbyte)(object)value;
				register.sbyte_13 = (sbyte)(object)value;
				register.sbyte_14 = (sbyte)(object)value;
				register.sbyte_15 = (sbyte)(object)value;
			}
			else if (typeof(T) == typeof(ushort))
			{
				register.uint16_0 = (ushort)(object)value;
				register.uint16_1 = (ushort)(object)value;
				register.uint16_2 = (ushort)(object)value;
				register.uint16_3 = (ushort)(object)value;
				register.uint16_4 = (ushort)(object)value;
				register.uint16_5 = (ushort)(object)value;
				register.uint16_6 = (ushort)(object)value;
				register.uint16_7 = (ushort)(object)value;
			}
			else if (typeof(T) == typeof(short))
			{
				register.int16_0 = (short)(object)value;
				register.int16_1 = (short)(object)value;
				register.int16_2 = (short)(object)value;
				register.int16_3 = (short)(object)value;
				register.int16_4 = (short)(object)value;
				register.int16_5 = (short)(object)value;
				register.int16_6 = (short)(object)value;
				register.int16_7 = (short)(object)value;
			}
			else if (typeof(T) == typeof(uint))
			{
				register.uint32_0 = (uint)(object)value;
				register.uint32_1 = (uint)(object)value;
				register.uint32_2 = (uint)(object)value;
				register.uint32_3 = (uint)(object)value;
			}
			else if (typeof(T) == typeof(int))
			{
				register.int32_0 = (int)(object)value;
				register.int32_1 = (int)(object)value;
				register.int32_2 = (int)(object)value;
				register.int32_3 = (int)(object)value;
			}
			else if (typeof(T) == typeof(ulong))
			{
				register.uint64_0 = (ulong)(object)value;
				register.uint64_1 = (ulong)(object)value;
			}
			else if (typeof(T) == typeof(long))
			{
				register.int64_0 = (long)(object)value;
				register.int64_1 = (long)(object)value;
			}
			else if (typeof(T) == typeof(float))
			{
				register.single_0 = (float)(object)value;
				register.single_1 = (float)(object)value;
				register.single_2 = (float)(object)value;
				register.single_3 = (float)(object)value;
			}
			else if (typeof(T) == typeof(double))
			{
				register.double_0 = (double)(object)value;
				register.double_1 = (double)(object)value;
			}
		}

		[JitIntrinsic]
		public Vector(T[] values)
			: this(values, 0)
		{
		}

		public unsafe Vector(T[] values, int index)
		{
			this = default(Vector<T>);
			if (values == null)
			{
				throw new NullReferenceException(System.SR.Arg_NullArgumentNullRef);
			}
			if (index < 0 || values.Length - index < Count)
			{
				throw new IndexOutOfRangeException();
			}
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					fixed (byte* ptr = &register.byte_0)
					{
						for (int i = 0; i < Count; i++)
						{
							ptr[i] = (byte)(object)values[i + index];
						}
					}
				}
				else if (typeof(T) == typeof(sbyte))
				{
					fixed (sbyte* ptr2 = &register.sbyte_0)
					{
						for (int j = 0; j < Count; j++)
						{
							ptr2[j] = (sbyte)(object)values[j + index];
						}
					}
				}
				else if (typeof(T) == typeof(ushort))
				{
					fixed (ushort* ptr3 = &register.uint16_0)
					{
						for (int k = 0; k < Count; k++)
						{
							ptr3[k] = (ushort)(object)values[k + index];
						}
					}
				}
				else if (typeof(T) == typeof(short))
				{
					fixed (short* ptr4 = &register.int16_0)
					{
						for (int l = 0; l < Count; l++)
						{
							ptr4[l] = (short)(object)values[l + index];
						}
					}
				}
				else if (typeof(T) == typeof(uint))
				{
					fixed (uint* ptr5 = &register.uint32_0)
					{
						for (int m = 0; m < Count; m++)
						{
							ptr5[m] = (uint)(object)values[m + index];
						}
					}
				}
				else if (typeof(T) == typeof(int))
				{
					fixed (int* ptr6 = &register.int32_0)
					{
						for (int n = 0; n < Count; n++)
						{
							ptr6[n] = (int)(object)values[n + index];
						}
					}
				}
				else if (typeof(T) == typeof(ulong))
				{
					fixed (ulong* ptr7 = &register.uint64_0)
					{
						for (int num = 0; num < Count; num++)
						{
							ptr7[num] = (ulong)(object)values[num + index];
						}
					}
				}
				else if (typeof(T) == typeof(long))
				{
					fixed (long* ptr8 = &register.int64_0)
					{
						for (int num2 = 0; num2 < Count; num2++)
						{
							ptr8[num2] = (long)(object)values[num2 + index];
						}
					}
				}
				else if (typeof(T) == typeof(float))
				{
					fixed (float* ptr9 = &register.single_0)
					{
						for (int num3 = 0; num3 < Count; num3++)
						{
							ptr9[num3] = (float)(object)values[num3 + index];
						}
					}
				}
				else
				{
					if (!(typeof(T) == typeof(double)))
					{
						return;
					}
					fixed (double* ptr10 = &register.double_0)
					{
						for (int num4 = 0; num4 < Count; num4++)
						{
							ptr10[num4] = (double)(object)values[num4 + index];
						}
					}
				}
			}
			else if (typeof(T) == typeof(byte))
			{
				fixed (byte* ptr11 = &register.byte_0)
				{
					*ptr11 = (byte)(object)values[index];
					ptr11[1] = (byte)(object)values[1 + index];
					ptr11[2] = (byte)(object)values[2 + index];
					ptr11[3] = (byte)(object)values[3 + index];
					ptr11[4] = (byte)(object)values[4 + index];
					ptr11[5] = (byte)(object)values[5 + index];
					ptr11[6] = (byte)(object)values[6 + index];
					ptr11[7] = (byte)(object)values[7 + index];
					ptr11[8] = (byte)(object)values[8 + index];
					ptr11[9] = (byte)(object)values[9 + index];
					ptr11[10] = (byte)(object)values[10 + index];
					ptr11[11] = (byte)(object)values[11 + index];
					ptr11[12] = (byte)(object)values[12 + index];
					ptr11[13] = (byte)(object)values[13 + index];
					ptr11[14] = (byte)(object)values[14 + index];
					ptr11[15] = (byte)(object)values[15 + index];
				}
			}
			else if (typeof(T) == typeof(sbyte))
			{
				fixed (sbyte* ptr12 = &register.sbyte_0)
				{
					*ptr12 = (sbyte)(object)values[index];
					ptr12[1] = (sbyte)(object)values[1 + index];
					ptr12[2] = (sbyte)(object)values[2 + index];
					ptr12[3] = (sbyte)(object)values[3 + index];
					ptr12[4] = (sbyte)(object)values[4 + index];
					ptr12[5] = (sbyte)(object)values[5 + index];
					ptr12[6] = (sbyte)(object)values[6 + index];
					ptr12[7] = (sbyte)(object)values[7 + index];
					ptr12[8] = (sbyte)(object)values[8 + index];
					ptr12[9] = (sbyte)(object)values[9 + index];
					ptr12[10] = (sbyte)(object)values[10 + index];
					ptr12[11] = (sbyte)(object)values[11 + index];
					ptr12[12] = (sbyte)(object)values[12 + index];
					ptr12[13] = (sbyte)(object)values[13 + index];
					ptr12[14] = (sbyte)(object)values[14 + index];
					ptr12[15] = (sbyte)(object)values[15 + index];
				}
			}
			else if (typeof(T) == typeof(ushort))
			{
				fixed (ushort* ptr13 = &register.uint16_0)
				{
					*ptr13 = (ushort)(object)values[index];
					ptr13[1] = (ushort)(object)values[1 + index];
					ptr13[2] = (ushort)(object)values[2 + index];
					ptr13[3] = (ushort)(object)values[3 + index];
					ptr13[4] = (ushort)(object)values[4 + index];
					ptr13[5] = (ushort)(object)values[5 + index];
					ptr13[6] = (ushort)(object)values[6 + index];
					ptr13[7] = (ushort)(object)values[7 + index];
				}
			}
			else if (typeof(T) == typeof(short))
			{
				fixed (short* ptr14 = &register.int16_0)
				{
					*ptr14 = (short)(object)values[index];
					ptr14[1] = (short)(object)values[1 + index];
					ptr14[2] = (short)(object)values[2 + index];
					ptr14[3] = (short)(object)values[3 + index];
					ptr14[4] = (short)(object)values[4 + index];
					ptr14[5] = (short)(object)values[5 + index];
					ptr14[6] = (short)(object)values[6 + index];
					ptr14[7] = (short)(object)values[7 + index];
				}
			}
			else if (typeof(T) == typeof(uint))
			{
				fixed (uint* ptr15 = &register.uint32_0)
				{
					*ptr15 = (uint)(object)values[index];
					ptr15[1] = (uint)(object)values[1 + index];
					ptr15[2] = (uint)(object)values[2 + index];
					ptr15[3] = (uint)(object)values[3 + index];
				}
			}
			else if (typeof(T) == typeof(int))
			{
				fixed (int* ptr16 = &register.int32_0)
				{
					*ptr16 = (int)(object)values[index];
					ptr16[1] = (int)(object)values[1 + index];
					ptr16[2] = (int)(object)values[2 + index];
					ptr16[3] = (int)(object)values[3 + index];
				}
			}
			else if (typeof(T) == typeof(ulong))
			{
				fixed (ulong* ptr17 = &register.uint64_0)
				{
					*ptr17 = (ulong)(object)values[index];
					ptr17[1] = (ulong)(object)values[1 + index];
				}
			}
			else if (typeof(T) == typeof(long))
			{
				fixed (long* ptr18 = &register.int64_0)
				{
					*ptr18 = (long)(object)values[index];
					ptr18[1] = (long)(object)values[1 + index];
				}
			}
			else if (typeof(T) == typeof(float))
			{
				fixed (float* ptr19 = &register.single_0)
				{
					*ptr19 = (float)(object)values[index];
					ptr19[1] = (float)(object)values[1 + index];
					ptr19[2] = (float)(object)values[2 + index];
					ptr19[3] = (float)(object)values[3 + index];
				}
			}
			else if (typeof(T) == typeof(double))
			{
				fixed (double* ptr20 = &register.double_0)
				{
					*ptr20 = (double)(object)values[index];
					ptr20[1] = (double)(object)values[1 + index];
				}
			}
		}

		internal unsafe Vector(void* dataPointer)
			: this(dataPointer, 0)
		{
		}

		internal unsafe Vector(void* dataPointer, int offset)
		{
			this = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				byte* ptr = (byte*)dataPointer;
				ptr += offset;
				fixed (byte* ptr2 = &register.byte_0)
				{
					for (int i = 0; i < Count; i++)
					{
						ptr2[i] = ptr[i];
					}
				}
				return;
			}
			if (typeof(T) == typeof(sbyte))
			{
				sbyte* ptr3 = (sbyte*)dataPointer;
				ptr3 += offset;
				fixed (sbyte* ptr4 = &register.sbyte_0)
				{
					for (int j = 0; j < Count; j++)
					{
						ptr4[j] = ptr3[j];
					}
				}
				return;
			}
			if (typeof(T) == typeof(ushort))
			{
				ushort* ptr5 = (ushort*)dataPointer;
				ptr5 += offset;
				fixed (ushort* ptr6 = &register.uint16_0)
				{
					for (int k = 0; k < Count; k++)
					{
						ptr6[k] = ptr5[k];
					}
				}
				return;
			}
			if (typeof(T) == typeof(short))
			{
				short* ptr7 = (short*)dataPointer;
				ptr7 += offset;
				fixed (short* ptr8 = &register.int16_0)
				{
					for (int l = 0; l < Count; l++)
					{
						ptr8[l] = ptr7[l];
					}
				}
				return;
			}
			if (typeof(T) == typeof(uint))
			{
				uint* ptr9 = (uint*)dataPointer;
				ptr9 += offset;
				fixed (uint* ptr10 = &register.uint32_0)
				{
					for (int m = 0; m < Count; m++)
					{
						ptr10[m] = ptr9[m];
					}
				}
				return;
			}
			if (typeof(T) == typeof(int))
			{
				int* ptr11 = (int*)dataPointer;
				ptr11 += offset;
				fixed (int* ptr12 = &register.int32_0)
				{
					for (int n = 0; n < Count; n++)
					{
						ptr12[n] = ptr11[n];
					}
				}
				return;
			}
			if (typeof(T) == typeof(ulong))
			{
				ulong* ptr13 = (ulong*)dataPointer;
				ptr13 += offset;
				fixed (ulong* ptr14 = &register.uint64_0)
				{
					for (int num = 0; num < Count; num++)
					{
						ptr14[num] = ptr13[num];
					}
				}
				return;
			}
			if (typeof(T) == typeof(long))
			{
				long* ptr15 = (long*)dataPointer;
				ptr15 += offset;
				fixed (long* ptr16 = &register.int64_0)
				{
					for (int num2 = 0; num2 < Count; num2++)
					{
						ptr16[num2] = ptr15[num2];
					}
				}
				return;
			}
			if (typeof(T) == typeof(float))
			{
				float* ptr17 = (float*)dataPointer;
				ptr17 += offset;
				fixed (float* ptr18 = &register.single_0)
				{
					for (int num3 = 0; num3 < Count; num3++)
					{
						ptr18[num3] = ptr17[num3];
					}
				}
				return;
			}
			if (typeof(T) == typeof(double))
			{
				double* ptr19 = (double*)dataPointer;
				ptr19 += offset;
				fixed (double* ptr20 = &register.double_0)
				{
					for (int num4 = 0; num4 < Count; num4++)
					{
						ptr20[num4] = ptr19[num4];
					}
				}
				return;
			}
			throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
		}

		private Vector(ref System.Numerics.Register existingRegister)
		{
			register = existingRegister;
		}

		[JitIntrinsic]
		public void CopyTo(T[] destination)
		{
			CopyTo(destination, 0);
		}

		[JitIntrinsic]
		public unsafe void CopyTo(T[] destination, int startIndex)
		{
			if (destination == null)
			{
				throw new NullReferenceException(System.SR.Arg_NullArgumentNullRef);
			}
			if (startIndex < 0 || startIndex >= destination.Length)
			{
				throw new ArgumentOutOfRangeException("startIndex", System.SR.Format(System.SR.Arg_ArgumentOutOfRangeException, startIndex));
			}
			if (destination.Length - startIndex < Count)
			{
				throw new ArgumentException(System.SR.Format(System.SR.Arg_ElementsInSourceIsGreaterThanDestination, startIndex));
			}
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					fixed (byte* ptr = (byte[])(object)destination)
					{
						for (int i = 0; i < Count; i++)
						{
							ptr[startIndex + i] = (byte)(object)this[i];
						}
					}
				}
				else if (typeof(T) == typeof(sbyte))
				{
					fixed (sbyte* ptr2 = (sbyte[])(object)destination)
					{
						for (int j = 0; j < Count; j++)
						{
							ptr2[startIndex + j] = (sbyte)(object)this[j];
						}
					}
				}
				else if (typeof(T) == typeof(ushort))
				{
					fixed (ushort* ptr3 = (ushort[])(object)destination)
					{
						for (int k = 0; k < Count; k++)
						{
							ptr3[startIndex + k] = (ushort)(object)this[k];
						}
					}
				}
				else if (typeof(T) == typeof(short))
				{
					fixed (short* ptr4 = (short[])(object)destination)
					{
						for (int l = 0; l < Count; l++)
						{
							ptr4[startIndex + l] = (short)(object)this[l];
						}
					}
				}
				else if (typeof(T) == typeof(uint))
				{
					fixed (uint* ptr5 = (uint[])(object)destination)
					{
						for (int m = 0; m < Count; m++)
						{
							ptr5[startIndex + m] = (uint)(object)this[m];
						}
					}
				}
				else if (typeof(T) == typeof(int))
				{
					fixed (int* ptr6 = (int[])(object)destination)
					{
						for (int n = 0; n < Count; n++)
						{
							ptr6[startIndex + n] = (int)(object)this[n];
						}
					}
				}
				else if (typeof(T) == typeof(ulong))
				{
					fixed (ulong* ptr7 = (ulong[])(object)destination)
					{
						for (int num = 0; num < Count; num++)
						{
							ptr7[startIndex + num] = (ulong)(object)this[num];
						}
					}
				}
				else if (typeof(T) == typeof(long))
				{
					fixed (long* ptr8 = (long[])(object)destination)
					{
						for (int num2 = 0; num2 < Count; num2++)
						{
							ptr8[startIndex + num2] = (long)(object)this[num2];
						}
					}
				}
				else if (typeof(T) == typeof(float))
				{
					fixed (float* ptr9 = (float[])(object)destination)
					{
						for (int num3 = 0; num3 < Count; num3++)
						{
							ptr9[startIndex + num3] = (float)(object)this[num3];
						}
					}
				}
				else
				{
					if (!(typeof(T) == typeof(double)))
					{
						return;
					}
					fixed (double* ptr10 = (double[])(object)destination)
					{
						for (int num4 = 0; num4 < Count; num4++)
						{
							ptr10[startIndex + num4] = (double)(object)this[num4];
						}
					}
				}
			}
			else if (typeof(T) == typeof(byte))
			{
				fixed (byte* ptr11 = (byte[])(object)destination)
				{
					ptr11[startIndex] = register.byte_0;
					ptr11[startIndex + 1] = register.byte_1;
					ptr11[startIndex + 2] = register.byte_2;
					ptr11[startIndex + 3] = register.byte_3;
					ptr11[startIndex + 4] = register.byte_4;
					ptr11[startIndex + 5] = register.byte_5;
					ptr11[startIndex + 6] = register.byte_6;
					ptr11[startIndex + 7] = register.byte_7;
					ptr11[startIndex + 8] = register.byte_8;
					ptr11[startIndex + 9] = register.byte_9;
					ptr11[startIndex + 10] = register.byte_10;
					ptr11[startIndex + 11] = register.byte_11;
					ptr11[startIndex + 12] = register.byte_12;
					ptr11[startIndex + 13] = register.byte_13;
					ptr11[startIndex + 14] = register.byte_14;
					ptr11[startIndex + 15] = register.byte_15;
				}
			}
			else if (typeof(T) == typeof(sbyte))
			{
				fixed (sbyte* ptr12 = (sbyte[])(object)destination)
				{
					ptr12[startIndex] = register.sbyte_0;
					ptr12[startIndex + 1] = register.sbyte_1;
					ptr12[startIndex + 2] = register.sbyte_2;
					ptr12[startIndex + 3] = register.sbyte_3;
					ptr12[startIndex + 4] = register.sbyte_4;
					ptr12[startIndex + 5] = register.sbyte_5;
					ptr12[startIndex + 6] = register.sbyte_6;
					ptr12[startIndex + 7] = register.sbyte_7;
					ptr12[startIndex + 8] = register.sbyte_8;
					ptr12[startIndex + 9] = register.sbyte_9;
					ptr12[startIndex + 10] = register.sbyte_10;
					ptr12[startIndex + 11] = register.sbyte_11;
					ptr12[startIndex + 12] = register.sbyte_12;
					ptr12[startIndex + 13] = register.sbyte_13;
					ptr12[startIndex + 14] = register.sbyte_14;
					ptr12[startIndex + 15] = register.sbyte_15;
				}
			}
			else if (typeof(T) == typeof(ushort))
			{
				fixed (ushort* ptr13 = (ushort[])(object)destination)
				{
					ptr13[startIndex] = register.uint16_0;
					ptr13[startIndex + 1] = register.uint16_1;
					ptr13[startIndex + 2] = register.uint16_2;
					ptr13[startIndex + 3] = register.uint16_3;
					ptr13[startIndex + 4] = register.uint16_4;
					ptr13[startIndex + 5] = register.uint16_5;
					ptr13[startIndex + 6] = register.uint16_6;
					ptr13[startIndex + 7] = register.uint16_7;
				}
			}
			else if (typeof(T) == typeof(short))
			{
				fixed (short* ptr14 = (short[])(object)destination)
				{
					ptr14[startIndex] = register.int16_0;
					ptr14[startIndex + 1] = register.int16_1;
					ptr14[startIndex + 2] = register.int16_2;
					ptr14[startIndex + 3] = register.int16_3;
					ptr14[startIndex + 4] = register.int16_4;
					ptr14[startIndex + 5] = register.int16_5;
					ptr14[startIndex + 6] = register.int16_6;
					ptr14[startIndex + 7] = register.int16_7;
				}
			}
			else if (typeof(T) == typeof(uint))
			{
				fixed (uint* ptr15 = (uint[])(object)destination)
				{
					ptr15[startIndex] = register.uint32_0;
					ptr15[startIndex + 1] = register.uint32_1;
					ptr15[startIndex + 2] = register.uint32_2;
					ptr15[startIndex + 3] = register.uint32_3;
				}
			}
			else if (typeof(T) == typeof(int))
			{
				fixed (int* ptr16 = (int[])(object)destination)
				{
					ptr16[startIndex] = register.int32_0;
					ptr16[startIndex + 1] = register.int32_1;
					ptr16[startIndex + 2] = register.int32_2;
					ptr16[startIndex + 3] = register.int32_3;
				}
			}
			else if (typeof(T) == typeof(ulong))
			{
				fixed (ulong* ptr17 = (ulong[])(object)destination)
				{
					ptr17[startIndex] = register.uint64_0;
					ptr17[startIndex + 1] = register.uint64_1;
				}
			}
			else if (typeof(T) == typeof(long))
			{
				fixed (long* ptr18 = (long[])(object)destination)
				{
					ptr18[startIndex] = register.int64_0;
					ptr18[startIndex + 1] = register.int64_1;
				}
			}
			else if (typeof(T) == typeof(float))
			{
				fixed (float* ptr19 = (float[])(object)destination)
				{
					ptr19[startIndex] = register.single_0;
					ptr19[startIndex + 1] = register.single_1;
					ptr19[startIndex + 2] = register.single_2;
					ptr19[startIndex + 3] = register.single_3;
				}
			}
			else if (typeof(T) == typeof(double))
			{
				fixed (double* ptr20 = (double[])(object)destination)
				{
					ptr20[startIndex] = register.double_0;
					ptr20[startIndex + 1] = register.double_1;
				}
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public override bool Equals(object obj)
		{
			if (!(obj is Vector<T>))
			{
				return false;
			}
			return Equals((Vector<T>)obj);
		}

		[JitIntrinsic]
		public bool Equals(Vector<T> other)
		{
			if (Vector.IsHardwareAccelerated)
			{
				for (int i = 0; i < Count; i++)
				{
					if (!ScalarEquals(this[i], other[i]))
					{
						return false;
					}
				}
				return true;
			}
			if (typeof(T) == typeof(byte))
			{
				if (register.byte_0 == other.register.byte_0 && register.byte_1 == other.register.byte_1 && register.byte_2 == other.register.byte_2 && register.byte_3 == other.register.byte_3 && register.byte_4 == other.register.byte_4 && register.byte_5 == other.register.byte_5 && register.byte_6 == other.register.byte_6 && register.byte_7 == other.register.byte_7 && register.byte_8 == other.register.byte_8 && register.byte_9 == other.register.byte_9 && register.byte_10 == other.register.byte_10 && register.byte_11 == other.register.byte_11 && register.byte_12 == other.register.byte_12 && register.byte_13 == other.register.byte_13 && register.byte_14 == other.register.byte_14)
				{
					return register.byte_15 == other.register.byte_15;
				}
				return false;
			}
			if (typeof(T) == typeof(sbyte))
			{
				if (register.sbyte_0 == other.register.sbyte_0 && register.sbyte_1 == other.register.sbyte_1 && register.sbyte_2 == other.register.sbyte_2 && register.sbyte_3 == other.register.sbyte_3 && register.sbyte_4 == other.register.sbyte_4 && register.sbyte_5 == other.register.sbyte_5 && register.sbyte_6 == other.register.sbyte_6 && register.sbyte_7 == other.register.sbyte_7 && register.sbyte_8 == other.register.sbyte_8 && register.sbyte_9 == other.register.sbyte_9 && register.sbyte_10 == other.register.sbyte_10 && register.sbyte_11 == other.register.sbyte_11 && register.sbyte_12 == other.register.sbyte_12 && register.sbyte_13 == other.register.sbyte_13 && register.sbyte_14 == other.register.sbyte_14)
				{
					return register.sbyte_15 == other.register.sbyte_15;
				}
				return false;
			}
			if (typeof(T) == typeof(ushort))
			{
				if (register.uint16_0 == other.register.uint16_0 && register.uint16_1 == other.register.uint16_1 && register.uint16_2 == other.register.uint16_2 && register.uint16_3 == other.register.uint16_3 && register.uint16_4 == other.register.uint16_4 && register.uint16_5 == other.register.uint16_5 && register.uint16_6 == other.register.uint16_6)
				{
					return register.uint16_7 == other.register.uint16_7;
				}
				return false;
			}
			if (typeof(T) == typeof(short))
			{
				if (register.int16_0 == other.register.int16_0 && register.int16_1 == other.register.int16_1 && register.int16_2 == other.register.int16_2 && register.int16_3 == other.register.int16_3 && register.int16_4 == other.register.int16_4 && register.int16_5 == other.register.int16_5 && register.int16_6 == other.register.int16_6)
				{
					return register.int16_7 == other.register.int16_7;
				}
				return false;
			}
			if (typeof(T) == typeof(uint))
			{
				if (register.uint32_0 == other.register.uint32_0 && register.uint32_1 == other.register.uint32_1 && register.uint32_2 == other.register.uint32_2)
				{
					return register.uint32_3 == other.register.uint32_3;
				}
				return false;
			}
			if (typeof(T) == typeof(int))
			{
				if (register.int32_0 == other.register.int32_0 && register.int32_1 == other.register.int32_1 && register.int32_2 == other.register.int32_2)
				{
					return register.int32_3 == other.register.int32_3;
				}
				return false;
			}
			if (typeof(T) == typeof(ulong))
			{
				if (register.uint64_0 == other.register.uint64_0)
				{
					return register.uint64_1 == other.register.uint64_1;
				}
				return false;
			}
			if (typeof(T) == typeof(long))
			{
				if (register.int64_0 == other.register.int64_0)
				{
					return register.int64_1 == other.register.int64_1;
				}
				return false;
			}
			if (typeof(T) == typeof(float))
			{
				if (register.single_0 == other.register.single_0 && register.single_1 == other.register.single_1 && register.single_2 == other.register.single_2)
				{
					return register.single_3 == other.register.single_3;
				}
				return false;
			}
			if (typeof(T) == typeof(double))
			{
				if (register.double_0 == other.register.double_0)
				{
					return register.double_1 == other.register.double_1;
				}
				return false;
			}
			throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
		}

		public override int GetHashCode()
		{
			int num = 0;
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					for (int i = 0; i < Count; i++)
					{
						num = HashHelpers.Combine(num, ((byte)(object)this[i]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(sbyte))
				{
					for (int j = 0; j < Count; j++)
					{
						num = HashHelpers.Combine(num, ((sbyte)(object)this[j]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(ushort))
				{
					for (int k = 0; k < Count; k++)
					{
						num = HashHelpers.Combine(num, ((ushort)(object)this[k]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(short))
				{
					for (int l = 0; l < Count; l++)
					{
						num = HashHelpers.Combine(num, ((short)(object)this[l]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(uint))
				{
					for (int m = 0; m < Count; m++)
					{
						num = HashHelpers.Combine(num, ((uint)(object)this[m]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(int))
				{
					for (int n = 0; n < Count; n++)
					{
						num = HashHelpers.Combine(num, ((int)(object)this[n]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(ulong))
				{
					for (int num2 = 0; num2 < Count; num2++)
					{
						num = HashHelpers.Combine(num, ((ulong)(object)this[num2]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(long))
				{
					for (int num3 = 0; num3 < Count; num3++)
					{
						num = HashHelpers.Combine(num, ((long)(object)this[num3]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(float))
				{
					for (int num4 = 0; num4 < Count; num4++)
					{
						num = HashHelpers.Combine(num, ((float)(object)this[num4]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(double))
				{
					for (int num5 = 0; num5 < Count; num5++)
					{
						num = HashHelpers.Combine(num, ((double)(object)this[num5]).GetHashCode());
					}
					return num;
				}
				throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
			}
			if (typeof(T) == typeof(byte))
			{
				num = HashHelpers.Combine(num, register.byte_0.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_1.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_2.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_3.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_4.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_5.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_6.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_7.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_8.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_9.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_10.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_11.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_12.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_13.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_14.GetHashCode());
				return HashHelpers.Combine(num, register.byte_15.GetHashCode());
			}
			if (typeof(T) == typeof(sbyte))
			{
				num = HashHelpers.Combine(num, register.sbyte_0.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_1.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_2.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_3.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_4.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_5.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_6.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_7.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_8.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_9.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_10.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_11.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_12.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_13.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_14.GetHashCode());
				return HashHelpers.Combine(num, register.sbyte_15.GetHashCode());
			}
			if (typeof(T) == typeof(ushort))
			{
				num = HashHelpers.Combine(num, register.uint16_0.GetHashCode());
				num = HashHelpers.Combine(num, register.uint16_1.GetHashCode());
				num = HashHelpers.Combine(num, register.uint16_2.GetHashCode());
				num = HashHelpers.Combine(num, register.uint16_3.GetHashCode());
				num = HashHelpers.Combine(num, register.uint16_4.GetHashCode());
				num = HashHelpers.Combine(num, register.uint16_5.GetHashCode());
				num = HashHelpers.Combine(num, register.uint16_6.GetHashCode());
				return HashHelpers.Combine(num, register.uint16_7.GetHashCode());
			}
			if (typeof(T) == typeof(short))
			{
				num = HashHelpers.Combine(num, register.int16_0.GetHashCode());
				num = HashHelpers.Combine(num, register.int16_1.GetHashCode());
				num = HashHelpers.Combine(num, register.int16_2.GetHashCode());
				num = HashHelpers.Combine(num, register.int16_3.GetHashCode());
				num = HashHelpers.Combine(num, register.int16_4.GetHashCode());
				num = HashHelpers.Combine(num, register.int16_5.GetHashCode());
				num = HashHelpers.Combine(num, register.int16_6.GetHashCode());
				return HashHelpers.Combine(num, register.int16_7.GetHashCode());
			}
			if (typeof(T) == typeof(uint))
			{
				num = HashHelpers.Combine(num, register.uint32_0.GetHashCode());
				num = HashHelpers.Combine(num, register.uint32_1.GetHashCode());
				num = HashHelpers.Combine(num, register.uint32_2.GetHashCode());
				return HashHelpers.Combine(num, register.uint32_3.GetHashCode());
			}
			if (typeof(T) == typeof(int))
			{
				num = HashHelpers.Combine(num, register.int32_0.GetHashCode());
				num = HashHelpers.Combine(num, register.int32_1.GetHashCode());
				num = HashHelpers.Combine(num, register.int32_2.GetHashCode());
				return HashHelpers.Combine(num, register.int32_3.GetHashCode());
			}
			if (typeof(T) == typeof(ulong))
			{
				num = HashHelpers.Combine(num, register.uint64_0.GetHashCode());
				return HashHelpers.Combine(num, register.uint64_1.GetHashCode());
			}
			if (typeof(T) == typeof(long))
			{
				num = HashHelpers.Combine(num, register.int64_0.GetHashCode());
				return HashHelpers.Combine(num, register.int64_1.GetHashCode());
			}
			if (typeof(T) == typeof(float))
			{
				num = HashHelpers.Combine(num, register.single_0.GetHashCode());
				num = HashHelpers.Combine(num, register.single_1.GetHashCode());
				num = HashHelpers.Combine(num, register.single_2.GetHashCode());
				return HashHelpers.Combine(num, register.single_3.GetHashCode());
			}
			if (typeof(T) == typeof(double))
			{
				num = HashHelpers.Combine(num, register.double_0.GetHashCode());
				return HashHelpers.Combine(num, register.double_1.GetHashCode());
			}
			throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
		}

		public override string ToString()
		{
			return ToString("G", CultureInfo.CurrentCulture);
		}

		public string ToString(string format)
		{
			return ToString(format, CultureInfo.CurrentCulture);
		}

		public string ToString(string format, IFormatProvider formatProvider)
		{
			StringBuilder stringBuilder = new StringBuilder();
			string numberGroupSeparator = NumberFormatInfo.GetInstance(formatProvider).NumberGroupSeparator;
			stringBuilder.Append('<');
			for (int i = 0; i < Count - 1; i++)
			{
				stringBuilder.Append(((IFormattable)(object)this[i]).ToString(format, formatProvider));
				stringBuilder.Append(numberGroupSeparator);
				stringBuilder.Append(' ');
			}
			stringBuilder.Append(((IFormattable)(object)this[Count - 1]).ToString(format, formatProvider));
			stringBuilder.Append('>');
			return stringBuilder.ToString();
		}

		public unsafe static Vector<T>operator +(Vector<T> left, Vector<T> right)
		{
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					byte* ptr = stackalloc byte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)];
					for (int i = 0; i < Count; i++)
					{
						ptr[i] = (byte)(object)ScalarAdd(left[i], right[i]);
					}
					return new Vector<T>(ptr);
				}
				if (typeof(T) == typeof(sbyte))
				{
					sbyte* ptr2 = stackalloc sbyte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)];
					for (int j = 0; j < Count; j++)
					{
						ptr2[j] = (sbyte)(object)ScalarAdd(left[j], right[j]);
					}
					return new Vector<T>(ptr2);
				}
				if (typeof(T) == typeof(ushort))
				{
					ushort* ptr3 = stackalloc ushort[Count];
					for (int k = 0; k < Count; k++)
					{
						ptr3[k] = (ushort)(object)ScalarAdd(left[k], right[k]);
					}
					return new Vector<T>(ptr3);
				}
				if (typeof(T) == typeof(short))
				{
					short* ptr4 = stackalloc short[Count];
					for (int l = 0; l < Count; l++)
					{
						ptr4[l] = (short)(object)ScalarAdd(left[l], right[l]);
					}
					return new Vector<T>(ptr4);
				}
				if (typeof(T) == typeof(uint))
				{
					uint* ptr5 = stackalloc uint[Count];
					for (int m = 0; m < Count; m++)
					{
						ptr5[m] = (uint)(object)ScalarAdd(left[m], right[m]);
					}
					return new Vector<T>(ptr5);
				}
				if (typeof(T) == typeof(int))
				{
					int* ptr6 = stackalloc int[Count];
					for (int n = 0; n < Count; n++)
					{
						ptr6[n] = (int)(object)ScalarAdd(left[n], right[n]);
					}
					return new Vector<T>(ptr6);
				}
				if (typeof(T) == typeof(ulong))
				{
					ulong* ptr7 = stackalloc ulong[Count];
					for (int num = 0; num < Count; num++)
					{
						ptr7[num] = (ulong)(object)ScalarAdd(left[num], right[num]);
					}
					return new Vector<T>(ptr7);
				}
				if (typeof(T) == typeof(long))
				{
					long* ptr8 = stackalloc long[Count];
					for (int num2 = 0; num2 < Count; num2++)
					{
						ptr8[num2] = (long)(object)ScalarAdd(left[num2], right[num2]);
					}
					return new Vector<T>(ptr8);
				}
				if (typeof(T) == typeof(float))
				{
					float* ptr9 = stackalloc float[Count];
					for (int num3 = 0; num3 < Count; num3++)
					{
						ptr9[num3] = (float)(object)ScalarAdd(left[num3], right[num3]);
					}
					return new Vector<T>(ptr9);
				}
				if (typeof(T) == typeof(double))
				{
					double* ptr10 = stackalloc double[Count];
					for (int num4 = 0; num4 < Count; num4++)
					{
						ptr10[num4] = (double)(object)ScalarAdd(left[num4], right[num4]);
					}
					return new Vector<T>(ptr10);
				}
				throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
			}
			Vector<T> result = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				result.register.byte_0 = (byte)(left.register.byte_0 + right.register.byte_0);
				result.register.byte_1 = (byte)(left.register.byte_1 + right.register.byte_1);
				result.register.byte_2 = (byte)(left.register.byte_2 + right.register.byte_2);
				result.register.byte_3 = (byte)(left.register.byte_3 + right.register.byte_3);
				result.register.byte_4 = (byte)(left.register.byte_4 + right.register.byte_4);
				result.register.byte_5 = (byte)(left.register.byte_5 + right.register.byte_5);
				result.register.byte_6 = (byte)(left.register.byte_6 + right.register.byte_6);
				result.register.byte_7 = (byte)(left.register.byte_7 + right.register.byte_7);
				result.register.byte_8 = (byte)(left.register.byte_8 + right.register.byte_8);
				result.register.byte_9 = (byte)(left.register.byte_9 + right.register.byte_9);
				result.register.byte_10 = (byte)(left.register.byte_10 + right.register.byte_10);
				result.register.byte_11 = (byte)(left.register.byte_11 + right.register.byte_11);
				result.register.byte_12 = (byte)(left.register.byte_12 + right.register.byte_12);
				result.register.byte_13 = (byte)(left.register.byte_13 + right.register.byte_13);
				result.register.byte_14 = (byte)(left.register.byte_14 + right.register.byte_14);
				result.register.byte_15 = (byte)(left.register.byte_15 + right.register.byte_15);
			}
			else if (typeof(T) == typeof(sbyte))
			{
				result.register.sbyte_0 = (sbyte)(left.register.sbyte_0 + right.register.sbyte_0);
				result.register.sbyte_1 = (sbyte)(left.register.sbyte_1 + right.register.sbyte_1);
				result.register.sbyte_2 = (sbyte)(left.register.sbyte_2 + right.register.sbyte_2);
				result.register.sbyte_3 = (sbyte)(left.register.sbyte_3 + right.register.sbyte_3);
				result.register.sbyte_4 = (sbyte)(left.register.sbyte_4 + right.register.sbyte_4);
				result.register.sbyte_5 = (sbyte)(left.register.sbyte_5 + right.register.sbyte_5);
				result.register.sbyte_6 = (sbyte)(left.register.sbyte_6 + right.register.sbyte_6);
				result.register.sbyte_7 = (sbyte)(left.register.sbyte_7 + right.register.sbyte_7);
				result.register.sbyte_8 = (sbyte)(left.register.sbyte_8 + right.register.sbyte_8);
				result.register.sbyte_9 = (sbyte)(left.register.sbyte_9 + right.register.sbyte_9);
				result.register.sbyte_10 = (sbyte)(left.register.sbyte_10 + right.register.sbyte_10);
				result.register.sbyte_11 = (sbyte)(left.register.sbyte_11 + right.register.sbyte_11);
				result.register.sbyte_12 = (sbyte)(left.register.sbyte_12 + right.register.sbyte_12);
				result.register.sbyte_13 = (sbyte)(left.register.sbyte_13 + right.register.sbyte_13);
				result.register.sbyte_14 = (sbyte)(left.register.sbyte_14 + right.register.sbyte_14);
				result.register.sbyte_15 = (sbyte)(left.register.sbyte_15 + right.register.sbyte_15);
			}
			else if (typeof(T) == typeof(ushort))
			{
				result.register.uint16_0 = (ushort)(left.register.uint16_0 + right.register.uint16_0);
				result.register.uint16_1 = (ushort)(left.register.uint16_1 + right.register.uint16_1);
				result.register.uint16_2 = (ushort)(left.register.uint16_2 + right.register.uint16_2);
				result.register.uint16_3 = (ushort)(left.register.uint16_3 + right.register.uint16_3);
				result.register.uint16_4 = (ushort)(left.register.uint16_4 + right.register.uint16_4);
				result.register.uint16_5 = (ushort)(left.register.uint16_5 + right.register.uint16_5);
				result.register.uint16_6 = (ushort)(left.register.uint16_6 + right.register.uint16_6);
				result.register.uint16_7 = (ushort)(left.register.uint16_7 + right.register.uint16_7);
			}
			else if (typeof(T) == typeof(short))
			{
				result.register.int16_0 = (short)(left.register.int16_0 + right.register.int16_0);
				result.register.int16_1 = (short)(left.register.int16_1 + right.register.int16_1);
				result.register.int16_2 = (short)(left.register.int16_2 + right.register.int16_2);
				result.register.int16_3 = (short)(left.register.int16_3 + right.register.int16_3);
				result.register.int16_4 = (short)(left.register.int16_4 + right.register.int16_4);
				result.register.int16_5 = (short)(left.register.int16_5 + right.register.int16_5);
				result.register.int16_6 = (short)(left.register.int16_6 + right.register.int16_6);
				result.register.int16_7 = (short)(left.register.int16_7 + right.register.int16_7);
			}
			else if (typeof(T) == typeof(uint))
			{
				result.register.uint32_0 = left.register.uint32_0 + right.register.uint32_0;
				result.register.uint32_1 = left.register.uint32_1 + right.register.uint32_1;
				result.register.uint32_2 = left.register.uint32_2 + right.register.uint32_2;
				result.register.uint32_3 = left.register.uint32_3 + right.register.uint32_3;
			}
			else if (typeof(T) == typeof(int))
			{
				result.register.int32_0 = left.register.int32_0 + right.register.int32_0;
				result.register.int32_1 = left.register.int32_1 + right.register.int32_1;
				result.register.int32_2 = left.register.int32_2 + right.register.int32_2;
				result.register.int32_3 = left.register.int32_3 + right.register.int32_3;
			}
			else if (typeof(T) == typeof(ulong))
			{
				result.register.uint64_0 = left.register.uint64_0 + right.register.uint64_0;
				result.register.uint64_1 = left.register.uint64_1 + right.register.uint64_1;
			}
			else if (typeof(T) == typeof(long))
			{
				result.register.int64_0 = left.register.int64_0 + right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 + right.register.int64_1;
			}
			else if (typeof(T) == typeof(float))
			{
				result.register.single_0 = left.register.single_0 + right.register.single_0;
				result.register.single_1 = left.register.single_1 + right.register.single_1;
				result.register.single_2 = left.register.single_2 + right.register.single_2;
				result.register.single_3 = left.register.single_3 + right.register.single_3;
			}
			else if (typeof(T) == typeof(double))
			{
				result.register.double_0 = left.register.double_0 + right.register.double_0;
				result.register.double_1 = left.register.double_1 + right.register.double_1;
			}
			return result;
		}

		public unsafe static Vector<T>operator -(Vector<T> left, Vector<T> right)
		{
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					byte* ptr = stackalloc byte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)];
					for (int i = 0; i < Count; i++)
					{
						ptr[i] = (byte)(object)ScalarSubtract(left[i], right[i]);
					}
					return new Vector<T>(ptr);
				}
				if (typeof(T) == typeof(sbyte))
				{
					sbyte* ptr2 = stackalloc sbyte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)];
					for (int j = 0; j < Count; j++)
					{
						ptr2[j] = (sbyte)(object)ScalarSubtract(left[j], right[j]);
					}
					return new Vector<T>(ptr2);
				}
				if (typeof(T) == typeof(ushort))
				{
					ushort* ptr3 = stackalloc ushort[Count];
					for (int k = 0; k < Count; k++)
					{
						ptr3[k] = (ushort)(object)ScalarSubtract(left[k], right[k]);
					}
					return new Vector<T>(ptr3);
				}
				if (typeof(T) == typeof(short))
				{
					short* ptr4 = stackalloc short[Count];
					for (int l = 0; l < Count; l++)
					{
						ptr4[l] = (short)(object)ScalarSubtract(left[l], right[l]);
					}
					return new Vector<T>(ptr4);
				}
				if (typeof(T) == typeof(uint))
				{
					uint* ptr5 = stackalloc uint[Count];
					for (int m = 0; m < Count; m++)
					{
						ptr5[m] = (uint)(object)ScalarSubtract(left[m], right[m]);
					}
					return new Vector<T>(ptr5);
				}
				if (typeof(T) == typeof(int))
				{
					int* ptr6 = stackalloc int[Count];
					for (int n = 0; n < Count; n++)
					{
						ptr6[n] = (int)(object)ScalarSubtract(left[n], right[n]);
					}
					return new Vector<T>(ptr6);
				}
				if (typeof(T) == typeof(ulong))
				{
					ulong* ptr7 = stackalloc ulong[Count];
					for (int num = 0; num < Count; num++)
					{
						ptr7[num] = (ulong)(object)ScalarSubtract(left[num], right[num]);
					}
					return new Vector<T>(ptr7);
				}
				if (typeof(T) == typeof(long))
				{
					long* ptr8 = stackalloc long[Count];
					for (int num2 = 0; num2 < Count; num2++)
					{
						ptr8[num2] = (long)(object)ScalarSubtract(left[num2], right[num2]);
					}
					return new Vector<T>(ptr8);
				}
				if (typeof(T) == typeof(float))
				{
					float* ptr9 = stackalloc float[Count];
					for (int num3 = 0; num3 < Count; num3++)
					{
						ptr9[num3] = (float)(object)ScalarSubtract(left[num3], right[num3]);
					}
					return new Vector<T>(ptr9);
				}
				if (typeof(T) == typeof(double))
				{
					double* ptr10 = stackalloc double[Count];
					for (int num4 = 0; num4 < Count; num4++)
					{
						ptr10[num4] = (double)(object)ScalarSubtract(left[num4], right[num4]);
					}
					return new Vector<T>(ptr10);
				}
				throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
			}
			Vector<T> result = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				result.register.byte_0 = (byte)(left.register.byte_0 - right.register.byte_0);
				result.register.byte_1 = (byte)(left.register.byte_1 - right.register.byte_1);
				result.register.byte_2 = (byte)(left.register.byte_2 - right.register.byte_2);
				result.register.byte_3 = (byte)(left.register.byte_3 - right.register.byte_3);
				result.register.byte_4 = (byte)(left.register.byte_4 - right.register.byte_4);
				result.register.byte_5 = (byte)(left.register.byte_5 - right.register.byte_5);
				result.register.byte_6 = (byte)(left.register.byte_6 - right.register.byte_6);
				result.register.byte_7 = (byte)(left.register.byte_7 - right.register.byte_7);
				result.register.byte_8 = (byte)(left.register.byte_8 - right.register.byte_8);
				result.register.byte_9 = (byte)(left.register.byte_9 - right.register.byte_9);
				result.register.byte_10 = (byte)(left.register.byte_10 - right.register.byte_10);
				result.register.byte_11 = (byte)(left.register.byte_11 - right.register.byte_11);
				result.register.byte_12 = (byte)(left.register.byte_12 - right.register.byte_12);
				result.register.byte_13 = (byte)(left.register.byte_13 - right.register.byte_13);
				result.register.byte_14 = (byte)(left.register.byte_14 - right.register.byte_14);
				result.register.byte_15 = (byte)(left.register.byte_15 - right.register.byte_15);
			}
			else if (typeof(T) == typeof(sbyte))
			{
				result.register.sbyte_0 = (sbyte)(left.register.sbyte_0 - right.register.sbyte_0);
				result.register.sbyte_1 = (sbyte)(left.register.sbyte_1 - right.register.sbyte_1);
				result.register.sbyte_2 = (sbyte)(left.register.sbyte_2 - right.register.sbyte_2);
				result.register.sbyte_3 = (sbyte)(left.register.sbyte_3 - right.register.sbyte_3);
				result.register.sbyte_4 = (sbyte)(left.register.sbyte_4 - right.register.sbyte_4);
				result.register.sbyte_5 = (sbyte)(left.register.sbyte_5 - right.register.sbyte_5);
				result.register.sbyte_6 = (sbyte)(left.register.sbyte_6 - right.register.sbyte_6);
				result.register.sbyte_7 = (sbyte)(left.register.sbyte_7 - right.register.sbyte_7);
				result.register.sbyte_8 = (sbyte)(left.register.sbyte_8 - right.register.sbyte_8);
				result.register.sbyte_9 = (sbyte)(left.register.sbyte_9 - right.register.sbyte_9);
				result.register.sbyte_10 = (sbyte)(left.register.sbyte_10 - right.register.sbyte_10);
				result.register.sbyte_11 = (sbyte)(left.register.sbyte_11 - right.register.sbyte_11);
				result.register.sbyte_12 = (sbyte)(left.register.sbyte_12 - right.register.sbyte_12);
				result.register.sbyte_13 = (sbyte)(left.register.sbyte_13 - right.register.sbyte_13);
				result.register.sbyte_14 = (sbyte)(left.register.sbyte_14 - right.register.sbyte_14);
				result.register.sbyte_15 = (sbyte)(left.register.sbyte_15 - right.register.sbyte_15);
			}
			else if (typeof(T) == typeof(ushort))
			{
				result.register.uint16_0 = (ushort)(left.register.uint16_0 - right.register.uint16_0);
				result.register.uint16_1 = (ushort)(left.register.uint16_1 - right.register.uint16_1);
				result.register.uint16_2 = (ushort)(left.register.uint16_2 - right.register.uint16_2);
				result.register.uint16_3 = (ushort)(left.register.uint16_3 - right.register.uint16_3);
				result.register.uint16_4 = (ushort)(left.register.uint16_4 - right.register.uint16_4);
				result.register.uint16_5 = (ushort)(left.register.uint16_5 - right.register.uint16_5);
				result.register.uint16_6 = (ushort)(left.register.uint16_6 - right.register.uint16_6);
				result.register.uint16_7 = (ushort)(left.register.uint16_7 - right.register.uint16_7);
			}
			else if (typeof(T) == typeof(short))
			{
				result.register.int16_0 = (short)(left.register.int16_0 - right.register.int16_0);
				result.register.int16_1 = (short)(left.register.int16_1 - right.register.int16_1);
				result.register.int16_2 = (short)(left.register.int16_2 - right.register.int16_2);
				result.register.int16_3 = (short)(left.register.int16_3 - right.register.int16_3);
				result.register.int16_4 = (short)(left.register.int16_4 - right.register.int16_4);
				result.register.int16_5 = (short)(left.register.int16_5 - right.register.int16_5);
				result.register.int16_6 = (short)(left.register.int16_6 - right.register.int16_6);
				result.register.int16_7 = (short)(left.register.int16_7 - right.register.int16_7);
			}
			else if (typeof(T) == typeof(uint))
			{
				result.register.uint32_0 = left.register.uint32_0 - right.register.uint32_0;
				result.register.uint32_1 = left.register.uint32_1 - right.register.uint32_1;
				result.register.uint32_2 = left.register.uint32_2 - right.register.uint32_2;
				result.register.uint32_3 = left.register.uint32_3 - right.register.uint32_3;
			}
			else if (typeof(T) == typeof(int))
			{
				result.register.int32_0 = left.register.int32_0 - right.register.int32_0;
				result.register.int32_1 = left.register.int32_1 - right.register.int32_1;
				result.register.int32_2 = left.register.int32_2 - right.register.int32_2;
				result.register.int32_3 = left.register.int32_3 - right.register.int32_3;
			}
			else if (typeof(T) == typeof(ulong))
			{
				result.register.uint64_0 = left.register.uint64_0 - right.register.uint64_0;
				result.register.uint64_1 = left.register.uint64_1 - right.register.uint64_1;
			}
			else if (typeof(T) == typeof(long))
			{
				result.register.int64_0 = left.register.int64_0 - right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 - right.register.int64_1;
			}
			else if (typeof(T) == typeof(float))
			{
				result.register.single_0 = left.register.single_0 - right.register.single_0;
				result.register.single_1 = left.register.single_1 - right.register.single_1;
				result.register.single_2 = left.register.single_2 - right.register.single_2;
				result.register.single_3 = left.register.single_3 - right.register.single_3;
			}
			else if (typeof(T) == typeof(double))
			{
				result.register.double_0 = left.register.double_0 - right.register.double_0;
				result.register.double_1 = left.register.double_1 - right.register.double_1;
			}
			return result;
		}

		public unsafe static Vector<T>operator *(Vector<T> left, Vector<T> right)
		{
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					byte* ptr = stackalloc byte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)];
					for (int i = 0; i < Count; i++)
					{
						ptr[i] = (byte)(object)ScalarMultiply(left[i], right[i]);
					}
					return new Vector<T>(ptr);
				}
				if (typeof(T) == typeof(sbyte))
				{
					sbyte* ptr2 = stackalloc sbyte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)];
					for (int j = 0; j < Count; j++)
					{
						ptr2[j] = (sbyte)(object)ScalarMultiply(left[j], right[j]);
					}
					return new Vector<T>(ptr2);
				}
				if (typeof(T) == typeof(ushort))
				{
					ushort* ptr3 = stackalloc ushort[Count];
					for (int k = 0; k < Count; k++)
					{
						ptr3[k] = (ushort)(object)ScalarMultiply(left[k], right[k]);
					}
					return new Vector<T>(ptr3);
				}
				if (typeof(T) == typeof(short))
				{
					short* ptr4 = stackalloc short[Count];
					for (int l = 0; l < Count; l++)
					{
						ptr4[l] = (short)(object)ScalarMultiply(left[l], right[l]);
					}
					return new Vector<T>(ptr4);
				}
				if (typeof(T) == typeof(uint))
				{
					uint* ptr5 = stackalloc uint[Count];
					for (int m = 0; m < Count; m++)
					{
						ptr5[m] = (uint)(object)ScalarMultiply(left[m], right[m]);
					}
					return new Vector<T>(ptr5);
				}
				if (typeof(T) == typeof(int))
				{
					int* ptr6 = stackalloc int[Count];
					for (int n = 0; n < Count; n++)
					{
						ptr6[n] = (int)(object)ScalarMultiply(left[n], right[n]);
					}
					return new Vector<T>(ptr6);
				}
				if (typeof(T) == typeof(ulong))
				{
					ulong* ptr7 = stackalloc ulong[Count];
					for (int num = 0; num < Count; num++)
					{
						ptr7[num] = (ulong)(object)ScalarMultiply(left[num], right[num]);
					}
					return new Vector<T>(ptr7);
				}
				if (typeof(T) == typeof(long))
				{
					long* ptr8 = stackalloc long[Count];
					for (int num2 = 0; num2 < Count; num2++)
					{
						ptr8[num2] = (long)(object)ScalarMultiply(left[num2], right[num2]);
					}
					return new Vector<T>(ptr8);
				}
				if (typeof(T) == typeof(float))
				{
					float* ptr9 = stackalloc float[Count];
					for (int num3 = 0; num3 < Count; num3++)
					{
						ptr9[num3] = (float)(object)ScalarMultiply(left[num3], right[num3]);
					}
					return new Vector<T>(ptr9);
				}
				if (typeof(T) == typeof(double))
				{
					double* ptr10 = stackalloc double[Count];
					for (int num4 = 0; num4 < Count; num4++)
					{
						ptr10[num4] = (double)(object)ScalarMultiply(left[num4], right[num4]);
					}
					return new Vector<T>(ptr10);
				}
				throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
			}
			Vector<T> result = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				result.register.byte_0 = (byte)(left.register.byte_0 * right.register.byte_0);
				result.register.byte_1 = (byte)(left.register.byte_1 * right.register.byte_1);
				result.register.byte_2 = (byte)(left.register.byte_2 * right.register.byte_2);
				result.register.byte_3 = (byte)(left.register.byte_3 * right.register.byte_3);
				result.register.byte_4 = (byte)(left.register.byte_4 * right.register.byte_4);
				result.register.byte_5 = (byte)(left.register.byte_5 * right.register.byte_5);
				result.register.byte_6 = (byte)(left.register.byte_6 * right.register.byte_6);
				result.register.byte_7 = (byte)(left.register.byte_7 * right.register.byte_7);
				result.register.byte_8 = (byte)(left.register.byte_8 * right.register.byte_8);
				result.register.byte_9 = (byte)(left.register.byte_9 * right.register.byte_9);
				result.register.byte_10 = (byte)(left.register.byte_10 * right.register.byte_10);
				result.register.byte_11 = (byte)(left.register.byte_11 * right.register.byte_11);
				result.register.byte_12 = (byte)(left.register.byte_12 * right.register.byte_12);
				result.register.byte_13 = (byte)(left.register.byte_13 * right.register.byte_13);
				result.register.byte_14 = (byte)(left.register.byte_14 * right.register.byte_14);
				result.register.byte_15 = (byte)(left.register.byte_15 * right.register.byte_15);
			}
			else if (typeof(T) == typeof(sbyte))
			{
				result.register.sbyte_0 = (sbyte)(left.register.sbyte_0 * right.register.sbyte_0);
				result.register.sbyte_1 = (sbyte)(left.register.sbyte_1 * right.register.sbyte_1);
				result.register.sbyte_2 = (sbyte)(left.register.sbyte_2 * right.register.sbyte_2);
				result.register.sbyte_3 = (sbyte)(left.register.sbyte_3 * right.register.sbyte_3);
				result.register.sbyte_4 = (sbyte)(left.register.sbyte_4 * right.register.sbyte_4);
				result.register.sbyte_5 = (sbyte)(left.register.sbyte_5 * right.register.sbyte_5);
				result.register.sbyte_6 = (sbyte)(left.register.sbyte_6 * right.register.sbyte_6);
				result.register.sbyte_7 = (sbyte)(left.register.sbyte_7 * right.register.sbyte_7);
				result.register.sbyte_8 = (sbyte)(left.register.sbyte_8 * right.register.sbyte_8);
				result.register.sbyte_9 = (sbyte)(left.register.sbyte_9 * right.register.sbyte_9);
				result.register.sbyte_10 = (sbyte)(left.register.sbyte_10 * right.register.sbyte_10);
				result.register.sbyte_11 = (sbyte)(left.register.sbyte_11 * right.register.sbyte_11);
				result.register.sbyte_12 = (sbyte)(left.register.sbyte_12 * right.register.sbyte_12);
				result.register.sbyte_13 = (sbyte)(left.register.sbyte_13 * right.register.sbyte_13);
				result.register.sbyte_14 = (sbyte)(left.register.sbyte_14 * right.register.sbyte_14);
				result.register.sbyte_15 = (sbyte)(left.register.sbyte_15 * right.register.sbyte_15);
			}
			else if (typeof(T) == typeof(ushort))
			{
				result.register.uint16_0 = (ushort)(left.register.uint16_0 * right.register.uint16_0);
				result.register.uint16_1 = (ushort)(left.register.uint16_1 * right.register.uint16_1);
				result.register.uint16_2 = (ushort)(left.register.uint16_2 * right.register.uint16_2);
				result.register.uint16_3 = (ushort)(left.register.uint16_3 * right.register.uint16_3);
				result.register.uint16_4 = (ushort)(left.register.uint16_4 * right.register.uint16_4);
				result.register.uint16_5 = (ushort)(left.register.uint16_5 * right.register.uint16_5);
				result.register.uint16_6 = (ushort)(left.register.uint16_6 * right.register.uint16_6);
				result.register.uint16_7 = (ushort)(left.register.uint16_7 * right.register.uint16_7);
			}
			else if (typeof(T) == typeof(short))
			{
				result.register.int16_0 = (short)(left.register.int16_0 * right.register.int16_0);
				result.register.int16_1 = (short)(left.register.int16_1 * right.register.int16_1);
				result.register.int16_2 = (short)(left.register.int16_2 * right.register.int16_2);
				result.register.int16_3 = (short)(left.register.int16_3 * right.register.int16_3);
				result.register.int16_4 = (short)(left.register.int16_4 * right.register.int16_4);
				result.register.int16_5 = (short)(left.register.int16_5 * right.register.int16_5);
				result.register.int16_6 = (short)(left.register.int16_6 * right.register.int16_6);
				result.register.int16_7 = (short)(left.register.int16_7 * right.register.int16_7);
			}
			else if (typeof(T) == typeof(uint))
			{
				result.register.uint32_0 = left.register.uint32_0 * right.register.uint32_0;
				result.register.uint32_1 = left.register.uint32_1 * right.register.uint32_1;
				result.register.uint32_2 = left.register.uint32_2 * right.register.uint32_2;
				result.register.uint32_3 = left.register.uint32_3 * right.register.uint32_3;
			}
			else if (typeof(T) == typeof(int))
			{
				result.register.int32_0 = left.register.int32_0 * right.register.int32_0;
				result.register.int32_1 = left.register.int32_1 * right.register.int32_1;
				result.register.int32_2 = left.register.int32_2 * right.register.int32_2;
				result.register.int32_3 = left.register.int32_3 * right.register.int32_3;
			}
			else if (typeof(T) == typeof(ulong))
			{
				result.register.uint64_0 = left.register.uint64_0 * right.register.uint64_0;
				result.register.uint64_1 = left.register.uint64_1 * right.register.uint64_1;
			}
			else if (typeof(T) == typeof(long))
			{
				result.register.int64_0 = left.register.int64_0 * right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 * right.register.int64_1;
			}
			else if (typeof(T) == typeof(float))
			{
				result.register.single_0 = left.register.single_0 * right.register.single_0;
				result.register.single_1 = left.register.single_1 * right.register.single_1;
				result.register.single_2 = left.register.single_2 * right.register.single_2;
				result.register.single_3 = left.register.single_3 * right.register.single_3;
			}
			else if (typeof(T) == typeof(double))
			{
				result.register.double_0 = left.register.double_0 * right.register.double_0;
				result.register.double_1 = left.register.double_1 * right.register.double_1;
			}
			return result;
		}

		public static Vector<T>operator *(Vector<T> value, T factor)
		{
			if (Vector.IsHardwareAccelerated)
			{
				return new Vector<T>(factor) * value;
			}
			Vector<T> result = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				result.register.byte_0 = (byte)(value.register.byte_0 * (byte)(object)factor);
				result.register.byte_1 = (byte)(value.register.byte_1 * (byte)(object)factor);
				result.register.byte_2 = (byte)(value.register.byte_2 * (byte)(object)factor);
				result.register.byte_3 = (byte)(value.register.byte_3 * (byte)(object)factor);
				result.register.byte_4 = (byte)(value.register.byte_4 * (byte)(object)factor);
				result.register.byte_5 = (byte)(value.register.byte_5 * (byte)(object)factor);
				result.register.byte_6 = (byte)(value.register.byte_6 * (byte)(object)factor);
				result.register.byte_7 = (byte)(value.register.byte_7 * (byte)(object)factor);
				result.register.byte_8 = (byte)(value.register.byte_8 * (byte)(object)factor);
				result.register.byte_9 = (byte)(value.register.byte_9 * (byte)(object)factor);
				result.register.byte_10 = (byte)(value.register.byte_10 * (byte)(object)factor);
				result.register.byte_11 = (byte)(value.register.byte_11 * (byte)(object)factor);
				result.register.byte_12 = (byte)(value.register.byte_12 * (byte)(object)factor);
				result.register.byte_13 = (byte)(value.register.byte_13 * (byte)(object)factor);
				result.register.byte_14 = (byte)(value.register.byte_14 * (byte)(object)factor);
				result.register.byte_15 = (byte)(value.register.byte_15 * (byte)(object)factor);
			}
			else if (typeof(T) == typeof(sbyte))
			{
				result.register.sbyte_0 = (sbyte)(value.register.sbyte_0 * (sbyte)(object)factor);
				result.register.sbyte_1 = (sbyte)(value.register.sbyte_1 * (sbyte)(object)factor);
				result.register.sbyte_2 = (sbyte)(value.register.sbyte_2 * (sbyte)(object)factor);
				result.register.sbyte_3 = (sbyte)(value.register.sbyte_3 * (sbyte)(object)factor);
				result.register.sbyte_4 = (sbyte)(value.register.sbyte_4 * (sbyte)(object)factor);
				result.register.sbyte_5 = (sbyte)(value.register.sbyte_5 * (sbyte)(object)factor);
				result.register.sbyte_6 = (sbyte)(value.register.sbyte_6 * (sbyte)(object)factor);
				result.register.sbyte_7 = (sbyte)(value.register.sbyte_7 * (sbyte)(object)factor);
				result.register.sbyte_8 = (sbyte)(value.register.sbyte_8 * (sbyte)(object)factor);
				result.register.sbyte_9 = (sbyte)(value.register.sbyte_9 * (sbyte)(object)factor);
				result.register.sbyte_10 = (sbyte)(value.register.sbyte_10 * (sbyte)(object)factor);
				result.register.sbyte_11 = (sbyte)(value.register.sbyte_11 * (sbyte)(object)factor);
				result.register.sbyte_12 = (sbyte)(value.register.sbyte_12 * (sbyte)(object)factor);
				result.register.sbyte_13 = (sbyte)(value.register.sbyte_13 * (sbyte)(object)factor);
				result.register.sbyte_14 = (sbyte)(value.register.sbyte_14 * (sbyte)(object)factor);
				result.register.sbyte_15 = (sbyte)(value.register.sbyte_15 * (sbyte)(object)factor);
			}
			else if (typeof(T) == typeof(ushort))
			{
				result.register.uint16_0 = (ushort)(value.register.uint16_0 * (ushort)(object)factor);
				result.register.uint16_1 = (ushort)(value.register.uint16_1 * (ushort)(object)factor);
				result.register.uint16_2 = (ushort)(value.register.uint16_2 * (ushort)(object)factor);
				result.register.uint16_3 = (ushort)(value.register.uint16_3 * (ushort)(object)factor);
				result.register.uint16_4 = (ushort)(value.register.uint16_4 * (ushort)(object)factor);
				result.register.uint16_5 = (ushort)(value.register.uint16_5 * (ushort)(object)factor);
				result.register.uint16_6 = (ushort)(value.register.uint16_6 * (ushort)(object)factor);
				result.register.uint16_7 = (ushort)(value.register.uint16_7 * (ushort)(object)factor);
			}
			else if (typeof(T) == typeof(short))
			{
				result.register.int16_0 = (short)(value.register.int16_0 * (short)(object)factor);
				result.register.int16_1 = (short)(value.register.int16_1 * (short)(object)factor);
				result.register.int16_2 = (short)(value.register.int16_2 * (short)(object)factor);
				result.register.int16_3 = (short)(value.register.int16_3 * (short)(object)factor);
				result.register.int16_4 = (short)(value.register.int16_4 * (short)(object)factor);
				result.register.int16_5 = (short)(value.register.int16_5 * (short)(object)factor);
				result.register.int16_6 = (short)(value.register.int16_6 * (short)(object)factor);
				result.register.int16_7 = (short)(value.register.int16_7 * (short)(object)factor);
			}
			else if (typeof(T) == typeof(uint))
			{
				result.register.uint32_0 = value.register.uint32_0 * (uint)(object)factor;
				result.register.uint32_1 = value.register.uint32_1 * (uint)(object)factor;
				result.register.uint32_2 = value.register.uint32_2 * (uint)(object)factor;
				result.register.uint32_3 = value.register.uint32_3 * (uint)(object)factor;
			}
			else if (typeof(T) == typeof(int))
			{
				result.register.int32_0 = value.register.int32_0 * (int)(object)factor;
				result.register.int32_1 = value.register.int32_1 * (int)(object)factor;
				result.register.int32_2 = value.register.int32_2 * (int)(object)factor;
				result.register.int32_3 = value.register.int32_3 * (int)(object)factor;
			}
			else if (typeof(T) == typeof(ulong))
			{
				result.register.uint64_0 = value.register.uint64_0 * (ulong)(object)factor;
				result.register.uint64_1 = value.register.uint64_1 * (ulong)(object)factor;
			}
			else if (typeof(T) == typeof(long))
			{
				result.register.int64_0 = value.register.int64_0 * (long)(object)factor;
				result.register.int64_1 = value.register.int64_1 * (long)(object)factor;
			}
			else if (typeof(T) == typeof(float))
			{
				result.register.single_0 = value.register.single_0 * (float)(object)factor;
				result.register.single_1 = value.register.single_1 * (float)(object)factor;
				result.register.single_2 = value.register.single_2 * (float)(object)factor;
				result.register.single_3 = value.register.single_3 * (float)(object)factor;
			}
			else if (typeof(T) == typeof(double))
			{
				result.register.double_0 = value.register.double_0 * (double)(object)factor;
				result.register.double_1 = value.register.double_1 * (double)(object)factor;
			}
			return result;
		}

		public static Vector<T>operator *(T factor, Vector<T> value)
		{
			if (Vector.IsHardwareAccelerated)
			{
				return new Vector<T>(factor) * value;
			}
			Vector<T> result = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				result.register.byte_0 = (byte)(value.register.byte_0 * (byte)(object)factor);
				result.register.byte_1 = (byte)(value.register.byte_1 * (byte)(object)factor);
				result.register.byte_2 = (byte)(value.register.byte_2 * (byte)(object)factor);
				result.register.byte_3 = (byte)(value.register.byte_3 * (byte)(object)factor);
				result.register.byte_4 = (byte)(value.register.byte_4 * (byte)(object)factor);
				result.register.byte_5 = (byte)(value.register.byte_5 * (byte)(object)factor);
				result.register.byte_6 = (byte)(value.register.byte_6 * (byte)(object)factor);
				result.register.byte_7 = (byte)(value.register.byte_7 * (byte)(object)factor);
				result.register.byte_8 = (byte)(value.register.byte_8 * (byte)(object)factor);
				result.register.byte_9 = (byte)(value.register.byte_9 * (byte)(object)factor);
				result.register.byte_10 = (byte)(value.register.byte_10 * (byte)(object)factor);
				result.register.byte_11 = (byte)(value.register.byte_11 * (byte)(object)factor);
				result.register.byte_12 = (byte)(value.register.byte_12 * (byte)(object)factor);
				result.register.byte_13 = (byte)(value.register.byte_13 * (byte)(object)factor);
				result.register.byte_14 = (byte)(value.register.byte_14 * (byte)(object)factor);
				result.register.byte_15 = (byte)(value.register.byte_15 * (byte)(object)factor);
			}
			else if (typeof(T) == typeof(sbyte))
			{
				result.register.sbyte_0 = (sbyte)(value.register.sbyte_0 * (sbyte)(object)factor);
				result.register.sbyte_1 = (sbyte)(value.register.sbyte_1 * (sbyte)(object)factor);
				result.register.sbyte_2 = (sbyte)(value.register.sbyte_2 * (sbyte)(object)factor);
				result.register.sbyte_3 = (sbyte)(value.register.sbyte_3 * (sbyte)(object)factor);
				result.register.sbyte_4 = (sbyte)(value.register.sbyte_4 * (sbyte)(object)factor);
				result.register.sbyte_5 = (sbyte)(value.register.sbyte_5 * (sbyte)(object)factor);
				result.register.sbyte_6 = (sbyte)(value.register.sbyte_6 * (sbyte)(object)factor);
				result.register.sbyte_7 = (sbyte)(value.register.sbyte_7 * (sbyte)(object)factor);
				result.register.sbyte_8 = (sbyte)(value.register.sbyte_8 * (sbyte)(object)factor);
				result.register.sbyte_9 = (sbyte)(value.register.sbyte_9 * (sbyte)(object)factor);
				result.register.sbyte_10 = (sbyte)(value.register.sbyte_10 * (sbyte)(object)factor);
				result.register.sbyte_11 = (sbyte)(value.register.sbyte_11 * (sbyte)(object)factor);
				result.register.sbyte_12 = (sbyte)(value.register.sbyte_12 * (sbyte)(object)factor);
				result.register.sbyte_13 = (sbyte)(value.register.sbyte_13 * (sbyte)(object)factor);
				result.register.sbyte_14 = (sbyte)(value.register.sbyte_14 * (sbyte)(object)factor);
				result.register.sbyte_15 = (sbyte)(value.register.sbyte_15 * (sbyte)(object)factor);
			}
			else if (typeof(T) == typeof(ushort))
			{
				result.register.uint16_0 = (ushort)(value.register.uint16_0 * (ushort)(object)factor);
				result.register.uint16_1 = (ushort)(value.register.uint16_1 * (ushort)(object)factor);
				result.register.uint16_2 = (ushort)(value.register.uint16_2 * (ushort)(object)factor);
				result.register.uint16_3 = (ushort)(value.register.uint16_3 * (ushort)(object)factor);
				result.register.uint16_4 = (ushort)(value.register.uint16_4 * (ushort)(object)factor);
				result.register.uint16_5 = (ushort)(value.register.uint16_5 * (ushort)(object)factor);
				result.register.uint16_6 = (ushort)(value.register.uint16_6 * (ushort)(object)factor);
				result.register.uint16_7 = (ushort)(value.register.uint16_7 * (ushort)(object)factor);
			}
			else if (typeof(T) == typeof(short))
			{
				result.register.int16_0 = (short)(value.register.int16_0 * (short)(object)factor);
				result.register.int16_1 = (short)(value.register.int16_1 * (short)(object)factor);
				result.register.int16_2 = (short)(value.register.int16_2 * (short)(object)factor);
				result.register.int16_3 = (short)(value.register.int16_3 * (short)(object)factor);
				result.register.int16_4 = (short)(value.register.int16_4 * (short)(object)factor);
				result.register.int16_5 = (short)(value.register.int16_5 * (short)(object)factor);
				result.register.int16_6 = (short)(value.register.int16_6 * (short)(object)factor);
				result.register.int16_7 = (short)(value.register.int16_7 * (short)(object)factor);
			}
			else if (typeof(T) == typeof(uint))
			{
				result.register.uint32_0 = value.register.uint32_0 * (uint)(object)factor;
				result.register.uint32_1 = value.register.uint32_1 * (uint)(object)factor;
				result.register.uint32_2 = value.register.uint32_2 * (uint)(object)factor;
				result.register.uint32_3 = value.register.uint32_3 * (uint)(object)factor;
			}
			else if (typeof(T) == typeof(int))
			{
				result.register.int32_0 = value.register.int32_0 * (int)(object)factor;
				result.register.int32_1 = value.register.int32_1 * (int)(object)factor;
				result.register.int32_2 = value.register.int32_2 * (int)(object)factor;
				result.register.int32_3 = value.register.int32_3 * (int)(object)factor;
			}
			else if (typeof(T) == typeof(ulong))
			{
				result.register.uint64_0 = value.register.uint64_0 * (ulong)(object)factor;
				result.register.uint64_1 = value.register.uint64_1 * (ulong)(object)factor;
			}
			else if (typeof(T) == typeof(long))
			{
				result.register.int64_0 = value.register.int64_0 * (long)(object)factor;
				result.register.int64_1 = value.register.int64_1 * (long)(object)factor;
			}
			else if (typeof(T) == typeof(float))
			{
				result.register.single_0 = value.register.single_0 * (float)(object)factor;
				result.register.single_1 = value.register.single_1 * (float)(object)factor;
				result.register.single_2 = value.register.single_2 * (float)(object)factor;
				result.register.single_3 = value.register.single_3 * (float)(object)factor;
			}
			else if (typeof(T) == typeof(double))
			{
				result.register.double_0 = value.register.double_0 * (double)(object)factor;
				result.register.double_1 = value.register.double_1 * (double)(object)factor;
			}
			return result;
		}

		public unsafe static Vector<T>operator /(Vector<T> left, Vector<T> right)
		{
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					byte* ptr = stackalloc byte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)];
					for (int i = 0; i < Count; i++)
					{
						ptr[i] = (byte)(object)ScalarDivide(left[i], right[i]);
					}
					return new Vector<T>(ptr);
				}
				if (typeof(T) == typeof(sbyte))
				{
					sbyte* ptr2 = stackalloc sbyte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)];
					for (int j = 0; j < Count; j++)
					{
						ptr2[j] = (sbyte)(object)ScalarDivide(left[j], right[j]);
					}
					return new Vector<T>(ptr2);
				}
				if (typeof(T) == typeof(ushort))
				{
					ushort* ptr3 = stackalloc ushort[Count];
					for (int k = 0; k < Count; k++)
					{
						ptr3[k] = (ushort)(object)ScalarDivide(left[k], right[k]);
					}
					return new Vector<T>(ptr3);
				}
				if (typeof(T) == typeof(short))
				{
					short* ptr4 = stackalloc short[Count];
					for (int l = 0; l < Count; l++)
					{
						ptr4[l] = (short)(object)ScalarDivide(left[l], right[l]);
					}
					return new Vector<T>(ptr4);
				}
				if (typeof(T) == typeof(uint))
				{
					uint* ptr5 = stackalloc uint[Count];
					for (int m = 0; m < Count; m++)
					{
						ptr5[m] = (uint)(object)ScalarDivide(left[m], right[m]);
					}
					return new Vector<T>(ptr5);
				}
				if (typeof(T) == typeof(int))
				{
					int* ptr6 = stackalloc int[Count];
					for (int n = 0; n < Count; n++)
					{
						ptr6[n] = (int)(object)ScalarDivide(left[n], right[n]);
					}
					return new Vector<T>(ptr6);
				}
				if (typeof(T) == typeof(ulong))
				{
					ulong* ptr7 = stackalloc ulong[Count];
					for (int num = 0; num < Count; num++)
					{
						ptr7[num] = (ulong)(object)ScalarDivide(left[num], right[num]);
					}
					return new Vector<T>(ptr7);
				}
				if (typeof(T) == typeof(long))
				{
					long* ptr8 = stackalloc long[Count];
					for (int num2 = 0; num2 < Count; num2++)
					{
						ptr8[num2] = (long)(object)ScalarDivide(left[num2], right[num2]);
					}
					return new Vector<T>(ptr8);
				}
				if (typeof(T) == typeof(float))
				{
					float* ptr9 = stackalloc float[Count];
					for (int num3 = 0; num3 < Count; num3++)
					{
						ptr9[num3] = (float)(object)ScalarDivide(left[num3], right[num3]);
					}
					return new Vector<T>(ptr9);
				}
				if (typeof(T) == typeof(double))
				{
					double* ptr10 = stackalloc double[Count];
					for (int num4 = 0; num4 < Count; num4++)
					{
						ptr10[num4] = (double)(object)ScalarDivide(left[num4], right[num4]);
					}
					return new Vector<T>(ptr10);
				}
				throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
			}
			Vector<T> result = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				result.register.byte_0 = (byte)(left.register.byte_0 / right.register.byte_0);
				result.register.byte_1 = (byte)(left.register.byte_1 / right.register.byte_1);
				result.register.byte_2 = (byte)(left.register.byte_2 / right.register.byte_2);
				result.register.byte_3 = (byte)(left.register.byte_3 / right.register.byte_3);
				result.register.byte_4 = (byte)(left.register.byte_4 / right.register.byte_4);
				result.register.byte_5 = (byte)(left.register.byte_5 / right.register.byte_5);
				result.register.byte_6 = (byte)(left.register.byte_6 / right.register.byte_6);
				result.register.byte_7 = (byte)(left.register.byte_7 / right.register.byte_7);
				result.register.byte_8 = (byte)(left.register.byte_8 / right.register.byte_8);
				result.register.byte_9 = (byte)(left.register.byte_9 / right.register.byte_9);
				result.register.byte_10 = (byte)(left.register.byte_10 / right.register.byte_10);
				result.register.byte_11 = (byte)(left.register.byte_11 / right.register.byte_11);
				result.register.byte_12 = (byte)(left.register.byte_12 / right.register.byte_12);
				result.register.byte_13 = (byte)(left.register.byte_13 / right.register.byte_13);
				result.register.byte_14 = (byte)(left.register.byte_14 / right.register.byte_14);
				result.register.byte_15 = (byte)(left.register.byte_15 / right.register.byte_15);
			}
			else if (typeof(T) == typeof(sbyte))
			{
				result.register.sbyte_0 = (sbyte)(left.register.sbyte_0 / right.register.sbyte_0);
				result.register.sbyte_1 = (sbyte)(left.register.sbyte_1 / right.register.sbyte_1);
				result.register.sbyte_2 = (sbyte)(left.register.sbyte_2 / right.register.sbyte_2);
				result.register.sbyte_3 = (sbyte)(left.register.sbyte_3 / right.register.sbyte_3);
				result.register.sbyte_4 = (sbyte)(left.register.sbyte_4 / right.register.sbyte_4);
				result.register.sbyte_5 = (sbyte)(left.register.sbyte_5 / right.register.sbyte_5);
				result.register.sbyte_6 = (sbyte)(left.register.sbyte_6 / right.register.sbyte_6);
				result.register.sbyte_7 = (sbyte)(left.register.sbyte_7 / right.register.sbyte_7);
				result.register.sbyte_8 = (sbyte)(left.register.sbyte_8 / right.register.sbyte_8);
				result.register.sbyte_9 = (sbyte)(left.register.sbyte_9 / right.register.sbyte_9);
				result.register.sbyte_10 = (sbyte)(left.register.sbyte_10 / right.register.sbyte_10);
				result.register.sbyte_11 = (sbyte)(left.register.sbyte_11 / right.register.sbyte_11);
				result.register.sbyte_12 = (sbyte)(left.register.sbyte_12 / right.register.sbyte_12);
				result.register.sbyte_13 = (sbyte)(left.register.sbyte_13 / right.register.sbyte_13);
				result.register.sbyte_14 = (sbyte)(left.register.sbyte_14 / right.register.sbyte_14);
				result.register.sbyte_15 = (sbyte)(left.register.sbyte_15 / right.register.sbyte_15);
			}
			else if (typeof(T) == typeof(ushort))
			{
				result.register.uint16_0 = (ushort)(left.register.uint16_0 / right.register.uint16_0);
				result.register.uint16_1 = (ushort)(left.register.uint16_1 / right.register.uint16_1);
				result.register.uint16_2 = (ushort)(left.register.uint16_2 / right.register.uint16_2);
				result.register.uint16_3 = (ushort)(left.register.uint16_3 / right.register.uint16_3);
				result.register.uint16_4 = (ushort)(left.register.uint16_4 / right.register.uint16_4);
				result.register.uint16_5 = (ushort)(left.register.uint16_5 / right.register.uint16_5);
				result.register.uint16_6 = (ushort)(left.register.uint16_6 / right.register.uint16_6);
				result.register.uint16_7 = (ushort)(left.register.uint16_7 / right.register.uint16_7);
			}
			else if (typeof(T) == typeof(short))
			{
				result.register.int16_0 = (short)(left.register.int16_0 / right.register.int16_0);
				result.register.int16_1 = (short)(left.register.int16_1 / right.register.int16_1);
				result.register.int16_2 = (short)(left.register.int16_2 / right.register.int16_2);
				result.register.int16_3 = (short)(left.register.int16_3 / right.register.int16_3);
				result.register.int16_4 = (short)(left.register.int16_4 / right.register.int16_4);
				result.register.int16_5 = (short)(left.register.int16_5 / right.register.int16_5);
				result.register.int16_6 = (short)(left.register.int16_6 / right.register.int16_6);
				result.register.int16_7 = (short)(left.register.int16_7 / right.register.int16_7);
			}
			else if (typeof(T) == typeof(uint))
			{
				result.register.uint32_0 = left.register.uint32_0 / right.register.uint32_0;
				result.register.uint32_1 = left.register.uint32_1 / right.register.uint32_1;
				result.register.uint32_2 = left.register.uint32_2 / right.register.uint32_2;
				result.register.uint32_3 = left.register.uint32_3 / right.register.uint32_3;
			}
			else if (typeof(T) == typeof(int))
			{
				result.register.int32_0 = left.register.int32_0 / right.register.int32_0;
				result.register.int32_1 = left.register.int32_1 / right.register.int32_1;
				result.register.int32_2 = left.register.int32_2 / right.register.int32_2;
				result.register.int32_3 = left.register.int32_3 / right.register.int32_3;
			}
			else if (typeof(T) == typeof(ulong))
			{
				result.register.uint64_0 = left.register.uint64_0 / right.register.uint64_0;
				result.register.uint64_1 = left.register.uint64_1 / right.register.uint64_1;
			}
			else if (typeof(T) == typeof(long))
			{
				result.register.int64_0 = left.register.int64_0 / right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 / right.register.int64_1;
			}
			else if (typeof(T) == typeof(float))
			{
				result.register.single_0 = left.register.single_0 / right.register.single_0;
				result.register.single_1 = left.register.single_1 / right.register.single_1;
				result.register.single_2 = left.register.single_2 / right.register.single_2;
				result.register.single_3 = left.register.single_3 / right.register.single_3;
			}
			else if (typeof(T) == typeof(double))
			{
				result.register.double_0 = left.register.double_0 / right.register.double_0;
				result.register.double_1 = left.register.double_1 / right.register.double_1;
			}
			return result;
		}

		public static Vector<T>operator -(Vector<T> value)
		{
			return Zero - value;
		}

		[JitIntrinsic]
		public unsafe static Vector<T>operator &(Vector<T> left, Vector<T> right)
		{
			Vector<T> result = default(Vector<T>);
			if (Vector.IsHardwareAccelerated)
			{
				long* ptr = &result.register.int64_0;
				long* ptr2 = &left.register.int64_0;
				long* ptr3 = &right.register.int64_0;
				for (int i = 0; i < Vector<long>.Count; i++)
				{
					ptr[i] = ptr2[i] & ptr3[i];
				}
			}
			else
			{
				result.register.int64_0 = left.register.int64_0 & right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 & right.register.int64_1;
			}
			return result;
		}

		[JitIntrinsic]
		public unsafe static Vector<T>operator |(Vector<T> left, Vector<T> right)
		{
			Vector<T> result = default(Vector<T>);
			if (Vector.IsHardwareAccelerated)
			{
				long* ptr = &result.register.int64_0;
				long* ptr2 = &left.register.int64_0;
				long* ptr3 = &right.register.int64_0;
				for (int i = 0; i < Vector<long>.Count; i++)
				{
					ptr[i] = ptr2[i] | ptr3[i];
				}
			}
			else
			{
				result.register.int64_0 = left.register.int64_0 | right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 | right.register.int64_1;
			}
			return result;
		}

		[JitIntrinsic]
		public unsafe static Vector<T>operator ^(Vector<T> left, Vector<T> right)
		{
			Vector<T> result = default(Vector<T>);
			if (Vector.IsHardwareAccelerated)
			{
				long* ptr = &result.register.int64_0;
				long* ptr2 = &left.register.int64_0;
				long* ptr3 = &right.register.int64_0;
				for (int i = 0; i < Vector<long>.Count; i++)
				{
					ptr[i] = ptr2[i] ^ ptr3[i];
				}
			}
			else
			{
				result.register.int64_0 = left.register.int64_0 ^ right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 ^ right.register.int64_1;
			}
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector<T>operator ~(Vector<T> value)
		{
			return allOnes ^ value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool operator ==(Vector<T> left, Vector<T> right)
		{
			return left.Equals(right);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool operator !=(Vector<T> left, Vector<T> right)
		{
			return !(left == right);
		}

		[JitIntrinsic]
		public static explicit operator Vector<byte>(Vector<T> value)
		{
			return new Vector<byte>(ref value.register);
		}

		[CLSCompliant(false)]
		[JitIntrinsic]
		public static explicit operator Vector<sbyte>(Vector<T> value)
		{
			return new Vector<sbyte>(ref value.register);
		}

		[CLSCompliant(false)]
		[JitIntrinsic]
		public static explicit operator Vector<ushort>(Vector<T> value)
		{
			return new Vector<ushort>(ref value.register);
		}

		[JitIntrinsic]
		public static explicit operator Vector<short>(Vector<T> value)
		{
			return new Vector<short>(ref value.register);
		}

		[CLSCompliant(false)]
		[JitIntrinsic]
		public static explicit operator Vector<uint>(Vector<T> value)
		{
			return new Vector<uint>(ref value.register);
		}

		[JitIntrinsic]
		public static explicit operator Vector<int>(Vector<T> value)
		{
			return new Vector<int>(ref value.register);
		}

		[CLSCompliant(false)]
		[JitIntrinsic]
		public static explicit operator Vector<ulong>(Vector<T> value)
		{
			return new Vector<ulong>(ref value.register);
		}

		[JitIntrinsic]
		public static explicit operator Vector<long>(Vector<T> value)
		{
			return new Vector<long>(ref value.register);
		}

		[JitIntrinsic]
		public static explicit operator Vector<float>(Vector<T> value)
		{
			return new Vector<float>(ref value.register);
		}

		[JitIntrinsic]
		public static explicit operator Vector<double>(Vector<T> value)
		{
			return new Vector<double>(ref value.register);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[JitIntrinsic]
		internal unsafe static Vector<T> Equals(Vector<T> left, Vector<T> right)
		{
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					byte* ptr = stackalloc byte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)];
					for (int i = 0; i < Count; i++)
					{
						ptr[i] = (byte)(ScalarEquals(left[i], right[i]) ? ConstantHelper.GetByteWithAllBitsSet() : 0);
					}
					return new Vector<T>(ptr);
				}
				if (typeof(T) == typeof(sbyte))
				{
					sbyte* ptr2 = stackalloc sbyte[(int)checked(unchecked((nuint)(uint)Count) * (nuint)1u)];
					for (int j = 0; j < Count; j++)
					{
						ptr2[j] = (sbyte)(ScalarEquals(left[j], right[j]) ? ConstantHelper.GetSByteWithAllBitsSet() : 0);
					}
					return new Vector<T>(ptr2);
				}
				if (typeof(T) == typeof(ushort))
				{
					ushort* ptr3 = stackalloc ushort[Count];
					for (int k = 0; k < Count; k++)
					{
						ptr3[k] = (ushort)(ScalarEquals(left[k], right[k]) ? ConstantHelper.GetUInt16WithAllBitsSet() : 0);
					}
					return new Vector<T>(ptr3);
				}
				if (typeof(T) == typeof(short))
				{
					short* ptr4 

System.Runtime.CompilerServices.Unsafe.dll

Decompiled 14 hours ago
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;

[assembly: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyFileVersion("4.0.0.0")]
[assembly: AssemblyInformationalVersion("4.0.0.0")]
[assembly: AssemblyTitle("System.Runtime.CompilerServices.Unsafe")]
[assembly: AssemblyDescription("System.Runtime.CompilerServices.Unsafe")]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyCopyright("© Microsoft Corporation.  All rights reserved.")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: CLSCompliant(false)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyVersion("4.0.4.1")]
namespace System.Runtime.CompilerServices
{
	public static class Unsafe : Object
	{
		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static T Read<T>(void* source)
		{
			return Unsafe.Read<T>(source);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static T ReadUnaligned<T>(void* source)
		{
			return Unsafe.ReadUnaligned<T>(source);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static T ReadUnaligned<T>(ref byte source)
		{
			return Unsafe.ReadUnaligned<T>(ref source);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static void Write<T>(void* destination, T value)
		{
			Unsafe.Write(destination, value);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static void WriteUnaligned<T>(void* destination, T value)
		{
			Unsafe.WriteUnaligned(destination, value);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static void WriteUnaligned<T>(ref byte destination, T value)
		{
			Unsafe.WriteUnaligned(ref destination, value);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static void Copy<T>(void* destination, ref T source)
		{
			Unsafe.Write(destination, source);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static void Copy<T>(ref T destination, void* source)
		{
			destination = Unsafe.Read<T>(source);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static void* AsPointer<T>(ref T value)
		{
			return Unsafe.AsPointer(ref value);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static int SizeOf<T>()
		{
			return Unsafe.SizeOf<T>();
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static void CopyBlock(void* destination, void* source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlock(destination, source, byteCount);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static void CopyBlock(ref byte destination, ref byte source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlock(ref destination, ref source, byteCount);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static void CopyBlockUnaligned(void* destination, void* source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlockUnaligned(destination, source, byteCount);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static void CopyBlockUnaligned(ref byte destination, ref byte source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlockUnaligned(ref destination, ref source, byteCount);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static void InitBlock(void* startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlock(startAddress, value, byteCount);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static void InitBlock(ref byte startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlock(ref startAddress, value, byteCount);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static void InitBlockUnaligned(void* startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlockUnaligned(startAddress, value, byteCount);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static void InitBlockUnaligned(ref byte startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlockUnaligned(ref startAddress, value, byteCount);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static T As<T>(object o) where T : class
		{
			return (T)o;
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static ref T AsRef<T>(void* source)
		{
			return ref *(T*)source;
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static ref T AsRef<T>(in T source)
		{
			return ref source;
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static ref TTo As<TFrom, TTo>(ref TFrom source)
		{
			return ref Unsafe.As<TFrom, TTo>(ref source);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static ref T Add<T>(ref T source, int elementOffset)
		{
			return ref Unsafe.Add(ref source, elementOffset);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static void* Add<T>(void* source, int elementOffset)
		{
			return (byte*)source + (nint)elementOffset * (nint)Unsafe.SizeOf<T>();
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static ref T Add<T>(ref T source, System.IntPtr elementOffset)
		{
			return ref Unsafe.Add(ref source, elementOffset);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static ref T AddByteOffset<T>(ref T source, System.IntPtr byteOffset)
		{
			return ref Unsafe.AddByteOffset(ref source, byteOffset);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static ref T Subtract<T>(ref T source, int elementOffset)
		{
			return ref Unsafe.Subtract(ref source, elementOffset);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public unsafe static void* Subtract<T>(void* source, int elementOffset)
		{
			return (byte*)source - (nint)elementOffset * (nint)Unsafe.SizeOf<T>();
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static ref T Subtract<T>(ref T source, System.IntPtr elementOffset)
		{
			return ref Unsafe.Subtract(ref source, elementOffset);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static ref T SubtractByteOffset<T>(ref T source, System.IntPtr byteOffset)
		{
			return ref Unsafe.SubtractByteOffset(ref source, byteOffset);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static System.IntPtr ByteOffset<T>(ref T origin, ref T target)
		{
			return Unsafe.ByteOffset(target: ref target, origin: ref origin);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static bool AreSame<T>(ref T left, ref T right)
		{
			return Unsafe.AreSame(ref left, ref right);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static bool IsAddressGreaterThan<T>(ref T left, ref T right)
		{
			return Unsafe.IsAddressGreaterThan(ref left, ref right);
		}

		[MethodImpl(256)]
		[NonVersionable]
		public static bool IsAddressLessThan<T>(ref T left, ref T right)
		{
			return Unsafe.IsAddressLessThan(ref left, ref right);
		}
	}
}
namespace System.Runtime.Versioning
{
	[AttributeUsage(/*Could not decode attribute arguments.*/)]
	internal sealed class NonVersionableAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
}

WormtownAI.dll

Decompiled 14 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Dissonance.Integrations.Unity_NFGO;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Microsoft.ML.OnnxRuntime;
using Microsoft.ML.OnnxRuntime.Tensors;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("WormtownAI")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+6ee958d45c268a70f4db457289d12410c4201df6")]
[assembly: AssemblyProduct("WormtownAI")]
[assembly: AssemblyTitle("WormtownAI")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 WormtownAI
{
	public class AiWorm : MonoBehaviour
	{
		public ulong requester_client_id;

		public int owner_slot;

		public AiWormDifficulty difficulty;

		public PlayerCosmeticData cosmetic_data;

		public bool has_cosmetic_data;
	}
	[HarmonyPatch]
	public static class AiWormCosmetics
	{
		private struct CosmeticBankState
		{
			public Dictionary<ulong, PlayerCosmeticData> bank;

			public ulong owner_id;

			public bool had_original;

			public PlayerCosmeticData original;
		}

		private const string GRAY_HEX = "7A7A7A";

		private const string DARK_GRAY_HEX = "727272";

		public static PlayerCosmeticData Create(PlayerCosmeticData source)
		{
			//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_0182: Unknown result type (might be due to invalid IL or missing references)
			PlayerCosmeticData result = source;
			byte[] bytes = Encoding.UTF8.GetBytes("7A7A7A");
			byte[] bytes2 = Encoding.UTF8.GetBytes("727272");
			result.worm_Hat_Model_Index = 0;
			result.worm_Horn_Model_Index = 0;
			result.worm_Eyes_Model_Index = 0;
			result.worm_Teeth_Model_Index = 2;
			result.worm_Head_Model_Index = 0;
			result.worm_Head_Color_Primary_Index = 0;
			result.worm_Head_Color_Secondary_Index = 0;
			result.worm_Head_Color_Primary_Hex = bytes;
			result.worm_Head_Color_Secondary_Hex = bytes;
			result.worm_BodySegment_Model_Index_0 = 0;
			result.worm_BodySegment_Color_Primary_Index_0 = 0;
			result.worm_BodySegment_Color_Secondary_Index_0 = 0;
			result.worm_BodySegment_Color_Primary_Hex_0 = bytes2;
			result.worm_BodySegment_Color_Secondary_Hex_0 = bytes2;
			result.worm_BodySegment_Model_Index_1 = 0;
			result.worm_BodySegment_Color_Primary_Index_1 = 0;
			result.worm_BodySegment_Color_Secondary_Index_1 = 0;
			result.worm_BodySegment_Color_Primary_Hex_1 = bytes;
			result.worm_BodySegment_Color_Secondary_Hex_1 = bytes;
			result.worm_BodySegment_Model_Index_2 = 0;
			result.worm_BodySegment_Color_Primary_Index_2 = 0;
			result.worm_BodySegment_Color_Secondary_Index_2 = 0;
			result.worm_BodySegment_Color_Primary_Hex_2 = bytes2;
			result.worm_BodySegment_Color_Secondary_Hex_2 = bytes2;
			result.worm_BodySegment_Model_Index_3 = 0;
			result.worm_BodySegment_Color_Primary_Index_3 = 0;
			result.worm_BodySegment_Color_Secondary_Index_3 = 0;
			result.worm_BodySegment_Color_Primary_Hex_3 = bytes;
			result.worm_BodySegment_Color_Secondary_Hex_3 = bytes;
			result.worm_BodySegment_Model_Index_4 = 0;
			result.worm_BodySegment_Color_Primary_Index_4 = 0;
			result.worm_BodySegment_Color_Secondary_Index_4 = 0;
			result.worm_BodySegment_Color_Primary_Hex_4 = bytes2;
			result.worm_BodySegment_Color_Secondary_Hex_4 = bytes2;
			result.worm_BodySegment_Model_Index_5 = 0;
			result.worm_BodySegment_Color_Primary_Index_5 = 0;
			result.worm_BodySegment_Color_Secondary_Index_5 = 0;
			result.worm_BodySegment_Color_Primary_Hex_5 = bytes;
			result.worm_BodySegment_Color_Secondary_Hex_5 = bytes;
			result.worm_BodySegment_Model_Index_6 = 0;
			result.worm_BodySegment_Color_Primary_Index_6 = 0;
			result.worm_BodySegment_Color_Secondary_Index_6 = 0;
			result.worm_BodySegment_Color_Primary_Hex_6 = bytes2;
			result.worm_BodySegment_Color_Secondary_Hex_6 = bytes2;
			return result;
		}

		public static bool TryGet(InGameWormCosmeticBuilder builder, out PlayerCosmeticData data)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			data = default(PlayerCosmeticData);
			if (!LobbyAiState.IsLocalHost || (Object)(object)builder == (Object)null)
			{
				return false;
			}
			AiWorm componentInParent = ((Component)builder).GetComponentInParent<AiWorm>();
			if ((Object)(object)componentInParent == (Object)null || !componentInParent.has_cosmetic_data)
			{
				return false;
			}
			data = componentInParent.cosmetic_data;
			return true;
		}

		[HarmonyPatch(typeof(InGameWormCosmeticBuilder), "CreateCosmetics")]
		[HarmonyPrefix]
		public static void CreateCosmetics_Prefix(InGameWormCosmeticBuilder __instance)
		{
			//IL_000b: 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)
			if (TryGet(__instance, out var data))
			{
				__instance.pcr = data;
			}
		}

		[HarmonyPatch(typeof(InGameWormCosmeticBuilder), "RequestPlayerCosmeticDataFromServer_ServerRPC")]
		[HarmonyPrefix]
		private static void RequestPlayerCosmeticData_Prefix(InGameWormCosmeticBuilder __instance, ulong __1, ref CosmeticBankState __state)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			__state = default(CosmeticBankState);
			if (TryGet(__instance, out var data) && !((Object)(object)GameManager.Singleton == (Object)null) && GameManager.Singleton.PlayerCosmeticDataBank != null)
			{
				Dictionary<ulong, PlayerCosmeticData> dictionary = (__state.bank = GameManager.Singleton.PlayerCosmeticDataBank);
				__state.owner_id = __1;
				__state.had_original = dictionary.TryGetValue(__1, out __state.original);
				dictionary[__1] = data;
			}
		}

		[HarmonyPatch(typeof(InGameWormCosmeticBuilder), "RequestPlayerCosmeticDataFromServer_ServerRPC")]
		[HarmonyFinalizer]
		private static Exception RequestPlayerCosmeticData_Finalizer(Exception __exception, CosmeticBankState __state)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if (__state.bank == null)
			{
				return __exception;
			}
			if (__state.had_original)
			{
				__state.bank[__state.owner_id] = __state.original;
			}
			else
			{
				__state.bank.Remove(__state.owner_id);
			}
			return __exception;
		}
	}
	public enum AiWormDifficulty : byte
	{
		Garden,
		Snake,
		Bull
	}
	public static class AiWormDifficultyRules
	{
		public const float BULL_DESTRUCTION_CHANCE = 0.75f;

		public static AiWormDifficulty Clamp(int value)
		{
			return (AiWormDifficulty)Mathf.Clamp(value, 0, 2);
		}

		public static float Multiplier(AiWormDifficulty difficulty)
		{
			return difficulty switch
			{
				AiWormDifficulty.Snake => 1.3f, 
				AiWormDifficulty.Bull => 2f, 
				_ => 1f, 
			};
		}

		public static float BurrowMultiplier(AiWormDifficulty difficulty)
		{
			return difficulty switch
			{
				AiWormDifficulty.Snake => 2f, 
				AiWormDifficulty.Bull => 3f, 
				_ => 1f, 
			};
		}

		public static string DisplayName(AiWormDifficulty difficulty)
		{
			return difficulty switch
			{
				AiWormDifficulty.Snake => "Snake Worm", 
				AiWormDifficulty.Bull => "Bull Worm", 
				_ => "Garden Worm", 
			};
		}

		public static AiWormDifficulty For(Component component)
		{
			AiWorm aiWorm = (((Object)(object)component != (Object)null) ? component.GetComponentInParent<AiWorm>() : null);
			if (!((Object)(object)aiWorm != (Object)null))
			{
				return AiWormDifficulty.Garden;
			}
			return aiWorm.difficulty;
		}

		public static float Multiplier(Component component)
		{
			return Multiplier(For(component));
		}
	}
	[HarmonyPatch]
	public static class AiWormDifficultyPatches
	{
		private const float IMPACT_DEDUP_SECONDS = 0.25f;

		private const float EXPLOSION_RADIUS_MIN = 0.08f;

		private const float EXPLOSION_RADIUS_MID = 0.15f;

		private const float EXPLOSION_RADIUS_MAX = 0.25f;

		private const ulong NO_PLAYER_ID = 1000000uL;

		private static readonly Dictionary<WormMovement, Dictionary<int, float>> impact_retry_at = new Dictionary<WormMovement, Dictionary<int, float>>();

		[HarmonyPatch(typeof(WormAbilityManager), "GetCooldownMultiplier")]
		[HarmonyPostfix]
		public static void GetCooldownMultiplier_Postfix(WormAbilityManager __instance, ref float __result)
		{
			if (AiWormManager.IsActiveAiWorm((Component)(object)__instance))
			{
				__result *= AiWormDifficultyRules.Multiplier((Component)(object)__instance);
			}
		}

		[HarmonyPatch(typeof(WormMovement), "OnCollisionEnter")]
		[HarmonyPostfix]
		public static void OnCollisionEnter_Postfix(WormMovement __instance, Collision other)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_0062: Invalid comparison between Unknown and I4
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager singleton = NetworkManager.Singleton;
			AiWorm aiWorm = (((Object)(object)__instance != (Object)null) ? ((Component)__instance).GetComponentInParent<AiWorm>() : null);
			if ((Object)(object)singleton == (Object)null || !singleton.IsHost || !AiWormManager.IsActiveAiWorm((Component)(object)__instance) || (Object)(object)aiWorm == (Object)null || aiWorm.difficulty != AiWormDifficulty.Bull || other == null || (Object)(object)other.collider == (Object)null)
			{
				return;
			}
			WormMovementState wormMovementState = __instance.wormMovementState;
			if ((int)wormMovementState != 0 && (int)wormMovementState != 2)
			{
				return;
			}
			GameObject val = ResolveDestructible(other.collider);
			if ((Object)(object)val == (Object)null || !CanDestroy(val) || !BeginImpactRoll(__instance, val) || Random.value >= 0.75f)
			{
				return;
			}
			if (!TryFindContainedExplosion(other, val, out var explosion_pos, out var radius))
			{
				Plugin.log.LogWarning((object)("[worm] bull impact could not isolate " + ((Object)val).name + " for destruction"));
				return;
			}
			GameManager singleton2 = GameManager.Singleton;
			if (!((Object)(object)singleton2 == (Object)null))
			{
				singleton2.CreateExplosionAtPosition_ServerRPC(explosion_pos, radius, 1000000uL, 1000000uL, false);
				Plugin.log.LogInfo((object)("[worm] bull destroyed " + ((Object)val).name));
			}
		}

		public static void ForgetImpacts(WormMovement worm)
		{
			if ((Object)(object)worm != (Object)null)
			{
				impact_retry_at.Remove(worm);
			}
		}

		public static void ResetImpacts()
		{
			impact_retry_at.Clear();
		}

		private static GameObject ResolveDestructible(Collider collider)
		{
			Transform root = ((Component)collider).transform.root;
			if (((Component)root).CompareTag("Rock") || ((Component)root).CompareTag("Cactus"))
			{
				GameObject gameObject = ((Component)root).gameObject;
				if (!((Object)(object)gameObject.GetComponent<BrokenPrefabHolder>() != (Object)null))
				{
					return null;
				}
				return gameObject;
			}
			RootFinder componentInParent = ((Component)collider).GetComponentInParent<RootFinder>();
			GameObject val = (((Object)(object)componentInParent != (Object)null) ? ((Component)componentInParent).gameObject : null);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			if (val.CompareTag("CollapsibleBuilding") && (Object)(object)val.GetComponent<CollapsibleBuilding>() != (Object)null)
			{
				return val;
			}
			if (val.CompareTag("DestructibleTrain") && (Object)(object)val.GetComponent<DestructibleTrain>() != (Object)null)
			{
				return val;
			}
			return null;
		}

		private static bool CanDestroy(GameObject target)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			CollapsibleBuilding component = target.GetComponent<CollapsibleBuilding>();
			if ((Object)(object)component != (Object)null)
			{
				return !component.GetHasCollapsed();
			}
			DestructibleTrain component2 = target.GetComponent<DestructibleTrain>();
			if ((Object)(object)component2 != (Object)null)
			{
				return !component2.GetDestroyedState();
			}
			return target.transform.position.y < 5000f;
		}

		private static bool BeginImpactRoll(WormMovement worm, GameObject target)
		{
			if (!impact_retry_at.TryGetValue(worm, out var value))
			{
				value = new Dictionary<int, float>();
				impact_retry_at[worm] = value;
			}
			int instanceID = ((Object)target).GetInstanceID();
			if (value.TryGetValue(instanceID, out var value2) && Time.time < value2)
			{
				return false;
			}
			value[instanceID] = Time.time + 0.25f;
			return true;
		}

		private static bool TryFindContainedExplosion(Collision collision, GameObject target, out Vector3 explosion_pos, out float radius)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			Collider collider = collision.collider;
			Vector3 val;
			if (collision.contactCount <= 0)
			{
				val = collider.ClosestPoint(collision.transform.position);
			}
			else
			{
				ContactPoint contact = collision.GetContact(0);
				val = ((ContactPoint)(ref contact)).point;
			}
			Vector3 val2 = val;
			Bounds bounds = collider.bounds;
			Vector3 val3 = ((Bounds)(ref bounds)).center - val2;
			Vector3 val4 = ((((Vector3)(ref val3)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref val3)).normalized : Vector3.zero);
			Vector3[] obj = new Vector3[4]
			{
				val2 + val4 * 0.2f,
				val2 + val4 * 0.4f,
				default(Vector3),
				default(Vector3)
			};
			bounds = collider.bounds;
			obj[2] = collider.ClosestPoint(((Bounds)(ref bounds)).center);
			bounds = collider.bounds;
			obj[3] = ((Bounds)(ref bounds)).center;
			Vector3[] array = (Vector3[])(object)obj;
			float[] array2 = new float[3] { 0.08f, 0.15f, 0.25f };
			foreach (float num in array2)
			{
				Vector3[] array3 = array;
				foreach (Vector3 val5 in array3)
				{
					if (IsContainedTargetSphere(val5, num, target))
					{
						explosion_pos = val5;
						radius = num;
						return true;
					}
				}
			}
			explosion_pos = Vector3.zero;
			radius = 0f;
			return false;
		}

		private static bool IsContainedTargetSphere(Vector3 position, float radius, GameObject target)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			bool result = false;
			Collider[] array = Physics.OverlapSphere(position, radius, -1, (QueryTriggerInteraction)1);
			foreach (Collider val in array)
			{
				if (((Component)val).CompareTag("Player") || ((Component)val).CompareTag("WormPlayer") || ((Component)val).CompareTag("PickUp"))
				{
					return false;
				}
				GameObject val2 = ResolveDestructible(val);
				if ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)target)
				{
					return false;
				}
				if ((Object)(object)val2 == (Object)(object)target)
				{
					result = true;
				}
			}
			return result;
		}
	}
	[HarmonyPatch]
	public static class AiWormLoadoutPatches
	{
		[HarmonyPatch(typeof(WormAbilityManager), "Start", new Type[] { })]
		[HarmonyPostfix]
		public static void Start_Postfix(WormAbilityManager __instance)
		{
			if (!AiWormManager.IsAiWorm((Component)(object)__instance))
			{
				return;
			}
			try
			{
				if (LobbyAiState.ApplyAiLoadout(__instance))
				{
					Plugin.log.LogInfo((object)"[ai-toggle] applied required powers to spawned ai worm");
				}
				else
				{
					Plugin.log.LogWarning((object)"[ai-toggle] could not apply powers to spawned ai worm");
				}
			}
			catch (Exception ex)
			{
				Plugin.log.LogWarning((object)("[ai-toggle] spawned worm loadout failed: " + ex.Message));
			}
		}
	}
	[HarmonyPatch]
	public static class AiWormManager
	{
		public static readonly List<GameObject> ai_worms = new List<GameObject>();

		private static readonly Dictionary<ulong, GameObject> ai_worms_by_client = new Dictionary<ulong, GameObject>();

		private static readonly Dictionary<ulong, int> owner_slots_by_client = new Dictionary<ulong, int>();

		private static readonly Dictionary<ulong, AiWormDifficulty> pending_start_clients = new Dictionary<ulong, AiWormDifficulty>();

		public static bool IsAiWorm(Component c)
		{
			if (LobbyAiState.IsLocalHost && (Object)(object)c != (Object)null)
			{
				return (Object)(object)c.GetComponentInParent<AiWorm>() != (Object)null;
			}
			return false;
		}

		public static bool IsActiveAiWorm(Component c)
		{
			if (!IsAiWorm(c))
			{
				return false;
			}
			AiWorm componentInParent = c.GetComponentInParent<AiWorm>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				return ai_worms.Contains(((Component)componentInParent).gameObject);
			}
			return false;
		}

		[HarmonyPatch(typeof(LobbyManager), "SpawnPlayersAndStartGame")]
		[HarmonyPostfix]
		public static void SpawnPlayersAndStartGame_Postfix()
		{
			ReconcileSpawnedWorms(allow_start_hook: true);
		}

		public static void ReconcileSpawnedWorms()
		{
			ReconcileSpawnedWorms(allow_start_hook: false);
		}

		public static void CaptureStartRoster()
		{
			pending_start_clients.Clear();
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsHost || !LobbyAiState.IsHostEnabled)
			{
				return;
			}
			foreach (ulong enabledClientId in LobbyAiState.GetEnabledClientIds())
			{
				if (singleton.ConnectedClients.ContainsKey(enabledClientId))
				{
					pending_start_clients[enabledClientId] = LobbyAiState.GetClientDifficulty(enabledClientId);
				}
			}
		}

		public static void ClearStartRoster()
		{
			pending_start_clients.Clear();
		}

		private static void ReconcileSpawnedWorms(bool allow_start_hook)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Invalid comparison between Unknown and I4
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Invalid comparison between Unknown and I4
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsHost)
			{
				return;
			}
			GameManager singleton2 = GameManager.Singleton;
			if ((Object)(object)singleton2 == (Object)null || (!allow_start_hook && (int)singleton2.gameState != 1 && (int)singleton2.gameState != 3))
			{
				return;
			}
			RemoveMissingEntries();
			Dictionary<ulong, AiWormDifficulty> dictionary = new Dictionary<ulong, AiWormDifficulty>();
			if (allow_start_hook && pending_start_clients.Count > 0)
			{
				foreach (KeyValuePair<ulong, AiWormDifficulty> pending_start_client in pending_start_clients)
				{
					if (singleton.ConnectedClients.ContainsKey(pending_start_client.Key))
					{
						dictionary[pending_start_client.Key] = pending_start_client.Value;
					}
				}
				pending_start_clients.Clear();
			}
			else if (LobbyAiState.IsHostEnabled)
			{
				foreach (ulong enabledClientId in LobbyAiState.GetEnabledClientIds())
				{
					if (singleton.ConnectedClients.ContainsKey(enabledClientId))
					{
						dictionary[enabledClientId] = LobbyAiState.GetClientDifficulty(enabledClientId);
					}
				}
			}
			List<ulong> list = new List<ulong>(dictionary.Keys);
			list.Sort();
			if (list.Count > 16)
			{
				list.RemoveRange(16, list.Count - 16);
			}
			HashSet<ulong> hashSet = new HashSet<ulong>(list);
			foreach (ulong item in new List<ulong>(ai_worms_by_client.Keys))
			{
				if (!hashSet.Contains(item))
				{
					RemoveForClient(item);
				}
			}
			if (list.Count == 0 || !allow_start_hook)
			{
				return;
			}
			Plugin.EnsurePolicyLoaded();
			LobbyAiState.EnsureAiLoadout();
			GameObject wormPrefab = singleton2.wormPrefab;
			if ((Object)(object)wormPrefab == (Object)null)
			{
				Plugin.log.LogError((object)"wormPrefab null; cannot spawn ai worm");
				return;
			}
			int count = ai_worms.Count;
			for (int i = 0; i < list.Count; i++)
			{
				ulong num = list[i];
				if (!ai_worms_by_client.ContainsKey(num))
				{
					int num2 = NextAvailableOwnerSlot();
					if (num2 < 0)
					{
						Plugin.log.LogWarning((object)"no reserved owner id remained for another ai worm");
						break;
					}
					TrySpawnOne(wormPrefab, num, num2, dictionary[num]);
				}
			}
			if (ai_worms.Count != count)
			{
				Plugin.log.LogInfo((object)$"spawned {ai_worms.Count} ai worm(s)");
			}
		}

		[HarmonyPatch(typeof(GameManager), "SwitchGameStateServerRPC")]
		[HarmonyPostfix]
		public static void SwitchGameState_Postfix(int gameStateInt)
		{
			if (LobbyAiState.IsLocalHost && (gameStateInt == 2 || gameStateInt == 0))
			{
				DespawnAll();
			}
		}

		public static void DespawnAll()
		{
			AiWormDifficultyPatches.ResetImpacts();
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsHost)
			{
				return;
			}
			foreach (GameObject ai_worm in ai_worms)
			{
				if (!((Object)(object)ai_worm == (Object)null))
				{
					WormMovement componentInChildren = ai_worm.GetComponentInChildren<WormMovement>();
					WormPerception.Remove(componentInChildren);
					AiWormDifficultyPatches.ForgetImpacts(componentInChildren);
					DespawnOne(ai_worm);
				}
			}
			ai_worms.Clear();
			ai_worms_by_client.Clear();
			owner_slots_by_client.Clear();
			pending_start_clients.Clear();
			WormPerception.Reset();
		}

		public static void RemoveForClient(ulong client_id)
		{
			if (!ai_worms_by_client.TryGetValue(client_id, out var value))
			{
				owner_slots_by_client.Remove(client_id);
				return;
			}
			ai_worms_by_client.Remove(client_id);
			owner_slots_by_client.Remove(client_id);
			ai_worms.Remove(value);
			WormMovement worm = (((Object)(object)value != (Object)null) ? value.GetComponentInChildren<WormMovement>() : null);
			WormPerception.Remove(worm);
			AiWormDifficultyPatches.ForgetImpacts(worm);
			DespawnOne(value);
		}

		private static void DespawnOne(GameObject go)
		{
			if ((Object)(object)go == (Object)null)
			{
				return;
			}
			WormMouth componentInChildren = go.GetComponentInChildren<WormMouth>(true);
			if (GrabReleasePatches.ReleaseBeforeDespawn(componentInChildren))
			{
				try
				{
					((MonoBehaviour)componentInChildren).StartCoroutine(DespawnAfterRelease(go));
					return;
				}
				catch (Exception ex)
				{
					Plugin.log.LogWarning((object)("delayed ai worm despawn failed: " + ex.Message));
				}
			}
			DespawnNow(go);
		}

		private static IEnumerator DespawnAfterRelease(GameObject go)
		{
			yield return null;
			yield return null;
			DespawnNow(go);
		}

		private static void DespawnNow(GameObject go)
		{
			try
			{
				NetworkObject val = (((Object)(object)go != (Object)null) ? go.GetComponent<NetworkObject>() : null);
				if ((Object)(object)val != (Object)null && val.IsSpawned)
				{
					val.Despawn(true);
				}
				else if ((Object)(object)go != (Object)null)
				{
					Object.Destroy((Object)(object)go);
				}
			}
			catch (Exception ex)
			{
				Plugin.log.LogWarning((object)("ai worm despawn failed: " + ex.Message));
			}
		}

		private static void RemoveMissingEntries()
		{
			ai_worms.RemoveAll((GameObject worm) => (Object)(object)worm == (Object)null);
			foreach (ulong item in new List<ulong>(ai_worms_by_client.Keys))
			{
				if ((Object)(object)ai_worms_by_client[item] == (Object)null)
				{
					ai_worms_by_client.Remove(item);
					owner_slots_by_client.Remove(item);
				}
			}
		}

		private static int NextAvailableOwnerSlot()
		{
			HashSet<int> hashSet = new HashSet<int>(owner_slots_by_client.Values);
			for (int i = 0; i < 16; i++)
			{
				if (!hashSet.Contains(i))
				{
					return i;
				}
			}
			return -1;
		}

		private static void TrySpawnOne(GameObject prefab, ulong requester_client_id, int owner_slot, AiWormDifficulty difficulty)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = null;
			try
			{
				int num = owner_slot % 4;
				int num2 = owner_slot / 4;
				Vector3 val2 = default(Vector3);
				((Vector3)(ref val2))..ctor(((float)num - 1.5f) * 8f, 0f, -12f - (float)num2 * 8f);
				val = Object.Instantiate<GameObject>(prefab, val2, Quaternion.identity);
				if ((Object)(object)MenuToGameBridger.Singleton == (Object)null)
				{
					throw new InvalidOperationException("MenuToGameBridger null");
				}
				AiWorm aiWorm = val.AddComponent<AiWorm>();
				aiWorm.requester_client_id = requester_client_id;
				aiWorm.owner_slot = owner_slot;
				aiWorm.difficulty = difficulty;
				aiWorm.cosmetic_data = AiWormCosmetics.Create(MenuToGameBridger.Singleton.localPlayerCosmeticData);
				aiWorm.has_cosmetic_data = true;
				ApplyDifficulty(val, difficulty);
				NetworkObject component = val.GetComponent<NetworkObject>();
				if ((Object)(object)component == (Object)null)
				{
					throw new InvalidOperationException("worm prefab has no NetworkObject");
				}
				component.SpawnWithOwnership(AiWormNetworkIdentity.OwnerIdFor(owner_slot), false);
				ai_worms.Add(val);
				ai_worms_by_client[requester_client_id] = val;
				owner_slots_by_client[requester_client_id] = owner_slot;
				Plugin.log.LogInfo((object)("spawned " + AiWormDifficultyRules.DisplayName(difficulty) + " " + $"for client {requester_client_id}"));
			}
			catch (Exception arg)
			{
				try
				{
					if ((Object)(object)val != (Object)null)
					{
						NetworkObject component2 = val.GetComponent<NetworkObject>();
						if ((Object)(object)component2 != (Object)null && component2.IsSpawned)
						{
							component2.Despawn(true);
						}
						else
						{
							Object.Destroy((Object)(object)val);
						}
					}
				}
				catch (Exception ex)
				{
					Plugin.log.LogWarning((object)("ai worm spawn cleanup failed: " + ex.Message));
				}
				Plugin.log.LogError((object)$"ai worm spawn failed: {arg}");
			}
		}

		private static void ApplyDifficulty(GameObject go, AiWormDifficulty difficulty)
		{
			WormMovement componentInChildren = go.GetComponentInChildren<WormMovement>(true);
			if ((Object)(object)componentInChildren == (Object)null)
			{
				throw new InvalidOperationException("worm prefab has no WormMovement");
			}
			float num = AiWormDifficultyRules.Multiplier(difficulty);
			float num2 = AiWormDifficultyRules.BurrowMultiplier(difficulty);
			if (!Mathf.Approximately(num, 1f) || !Mathf.Approximately(num2, 1f))
			{
				string[] obj = new string[5] { "surfaceSpeed", "surfaceSpeed_Sneak", "divePower", "aboveGroundDivePower", "diveUpwardsPower" };
				Traverse val = Traverse.Create((object)componentInChildren);
				string[] array = obj;
				foreach (string text in array)
				{
					Traverse obj2 = val.Field(text);
					obj2.SetValue((object)(obj2.GetValue<float>() * num));
				}
				array = new string[2] { "burrowSpeed", "burrowSpeed_Sneak" };
				foreach (string text2 in array)
				{
					Traverse obj3 = val.Field(text2);
					obj3.SetValue((object)(obj3.GetValue<float>() * num2));
				}
				componentInChildren.diveCooldown /= num;
			}
		}
	}
	[HarmonyPatch]
	public static class AiWormNetworkIdentity
	{
		private struct NetworkOwnerState
		{
			public NetworkObject network_object;

			public ulong owner_id;
		}

		public const int MAX_AI_WORMS = 16;

		private const ulong FIRST_OWNER_ID = 18446744073709550591uL;

		public static ulong OwnerIdFor(int index)
		{
			return 18446744073709550591uL - (ulong)index;
		}

		private static bool IsReservedOwnerId(ulong owner_id)
		{
			if (owner_id <= 18446744073709550591uL)
			{
				return owner_id >= 18446744073709550576uL;
			}
			return false;
		}

		[HarmonyPatch(typeof(NetworkBehaviour), "UpdateNetworkProperties")]
		[HarmonyPostfix]
		private static void UpdateNetworkProperties_Postfix(NetworkBehaviour __instance)
		{
			NetworkManager singleton = NetworkManager.Singleton;
			if (!((Object)(object)singleton == (Object)null) && singleton.IsHost && !((Object)(object)__instance == (Object)null) && !((Object)(object)((Component)__instance).GetComponentInParent<AiWorm>() == (Object)null))
			{
				Traverse obj = Traverse.Create((object)__instance);
				obj.Property("IsOwner", (object[])null).SetValue((object)true);
				obj.Property("OwnerClientId", (object[])null).SetValue((object)singleton.LocalClientId);
			}
		}

		[HarmonyPatch(typeof(NetworkVariableBase), "CanClientWrite")]
		[HarmonyPostfix]
		private static void CanClientWrite_Postfix(NetworkVariableBase __instance, ulong clientId, ref bool __result)
		{
			if (!__result)
			{
				NetworkManager singleton = NetworkManager.Singleton;
				NetworkBehaviour val = ((__instance != null) ? __instance.GetBehaviour() : null);
				if ((Object)(object)singleton != (Object)null && singleton.IsHost && clientId == singleton.LocalClientId && (Object)(object)val != (Object)null && (Object)(object)((Component)val).GetComponentInParent<AiWorm>() != (Object)null)
				{
					__result = true;
				}
			}
		}

		[HarmonyPatch(typeof(WormPlayer), "DamageWorm_ServerRPC")]
		[HarmonyPrefix]
		private static void DamageWorm_Prefix(WormPlayer __instance, ref NetworkOwnerState __state)
		{
			__state = default(NetworkOwnerState);
			NetworkManager singleton = NetworkManager.Singleton;
			if (!((Object)(object)singleton == (Object)null) && singleton.IsHost && !((Object)(object)__instance == (Object)null) && !((Object)(object)((Component)__instance).GetComponentInParent<AiWorm>() == (Object)null))
			{
				NetworkObject networkObject = ((NetworkBehaviour)__instance).NetworkObject;
				if (!((Object)(object)networkObject == (Object)null))
				{
					__state.network_object = networkObject;
					__state.owner_id = networkObject.OwnerClientId;
					Traverse.Create((object)networkObject).Property("OwnerClientId", (object[])null).SetValue((object)singleton.LocalClientId);
				}
			}
		}

		[HarmonyPatch(typeof(WormPlayer), "DamageWorm_ServerRPC")]
		[HarmonyFinalizer]
		private static Exception DamageWorm_Finalizer(Exception __exception, NetworkOwnerState __state)
		{
			if ((Object)(object)__state.network_object != (Object)null)
			{
				Traverse.Create((object)__state.network_object).Property("OwnerClientId", (object[])null).SetValue((object)__state.owner_id);
			}
			return __exception;
		}

		[HarmonyPatch(typeof(EventFeedManager), "GetPlayerNamesFromServerAndCreateEventStringsWithThem_ServerRPC")]
		[HarmonyPrefix]
		private static void EventFeed_Prefix(ref ulong _playerID1, ref ulong _playerID2)
		{
			NetworkManager singleton = NetworkManager.Singleton;
			if (!((Object)(object)singleton == (Object)null) && singleton.IsHost)
			{
				if (IsReservedOwnerId(_playerID1))
				{
					_playerID1 = singleton.LocalClientId;
				}
				if (IsReservedOwnerId(_playerID2))
				{
					_playerID2 = singleton.LocalClientId;
				}
			}
		}
	}
	[HarmonyPatch]
	public static class BileBombRedirect
	{
		private const float ARM_WINDOW_SECONDS = 0.5f;

		private const float TRAVEL_SPEED = 40f;

		private const float ARRIVAL_RADIUS = 1f;

		private static bool armed;

		private static Vector3 armed_target;

		private static float armed_at = float.NegativeInfinity;

		private static readonly Dictionary<BileBombProjectile, Vector3> redirects = new Dictionary<BileBombProjectile, Vector3>();

		public static void Arm(Vector3 target)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			armed = true;
			armed_target = target;
			armed_at = Time.time;
		}

		[HarmonyPatch(typeof(BileBombProjectile), "OnNetworkSpawn")]
		[HarmonyPostfix]
		public static void OnNetworkSpawn_Postfix(BileBombProjectile __instance)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (armed && !((Object)(object)__instance == (Object)null))
			{
				armed = false;
				if (Time.time - armed_at <= 0.5f)
				{
					redirects[__instance] = armed_target;
				}
			}
		}

		[HarmonyPatch(typeof(BileBombProjectile), "Update")]
		[HarmonyPrefix]
		public static void Update_Prefix(BileBombProjectile __instance)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			if ((Object)(object)__instance == (Object)null || !redirects.TryGetValue(__instance, out var value))
			{
				return;
			}
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsHost)
			{
				return;
			}
			Rigidbody component = ((Component)__instance).GetComponent<Rigidbody>();
			if (!((Object)(object)component == (Object)null))
			{
				Collider component2 = ((Component)__instance).GetComponent<Collider>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.isTrigger = true;
				}
				component.useGravity = false;
				component.angularVelocity = Vector3.zero;
				Vector3 val = value - ((Component)__instance).transform.position;
				float magnitude = ((Vector3)(ref val)).magnitude;
				component.velocity = ((magnitude <= 1f) ? Vector3.zero : (val / magnitude * 40f));
			}
		}
	}
	[HarmonyPatch]
	public static class GrabReleasePatches
	{
		private class ForcedRelease
		{
			public ulong worm_owner_id;

			public float expires_at;
		}

		private static readonly Dictionary<ulong, WormMouth> ai_grabber = new Dictionary<ulong, WormMouth>();

		private static readonly Dictionary<ulong, ForcedRelease> forced_releases = new Dictionary<ulong, ForcedRelease>();

		private static readonly MethodInfo mini_game_ended_client_rpc = AccessTools.Method(typeof(StruggleMiniGameHandler), "MiniGameEnded_ClientRPC", new Type[1] { typeof(ulong) }, (Type[])null);

		private static WormMouth last_ai_mouth;

		[HarmonyPatch(typeof(WormMouth), "GrabPlayer_Server")]
		[HarmonyPrefix]
		public static bool GrabPlayer_Server_Prefix(WormMouth __instance, NetworkObject pObject, ref bool __result)
		{
			if ((Object)(object)pObject != (Object)null && forced_releases.TryGetValue(pObject.OwnerClientId, out var value))
			{
				if (Time.unscaledTime <= value.expires_at)
				{
					__result = false;
					return false;
				}
				forced_releases.Remove(pObject.OwnerClientId);
			}
			if (AiWormManager.IsAiWorm((Component)(object)__instance))
			{
				last_ai_mouth = __instance;
			}
			return true;
		}

		[HarmonyPatch(typeof(WormMouth), "GrabPlayer_Server")]
		[HarmonyPostfix]
		public static void GrabPlayer_Server_Postfix(WormMouth __instance, NetworkObject pObject, bool __result)
		{
			if (__result && AiWormManager.IsAiWorm((Component)(object)__instance) && (Object)(object)pObject != (Object)null)
			{
				ai_grabber[pObject.OwnerClientId] = __instance;
				Player componentInParent = ((Component)pObject).GetComponentInParent<Player>();
				if ((Object)(object)componentInParent != (Object)null)
				{
					WormPerception.OnTargetGrabbed(((Component)__instance).GetComponentInParent<WormMovement>(), componentInParent);
				}
			}
		}

		[HarmonyPatch(typeof(StruggleMiniGameHandler), "StartNewStruggleMiniGame_ClientRPC")]
		[HarmonyPrefix]
		public static void StartStruggle_Prefix(ref ulong _wormPlayerObjectID)
		{
			if (!LobbyAiState.IsLocalHost || (Object)(object)last_ai_mouth == (Object)null || (Object)(object)((NetworkBehaviour)last_ai_mouth).NetworkObject == (Object)null)
			{
				return;
			}
			NetworkManager singleton = NetworkManager.Singleton;
			if (!((Object)(object)singleton == (Object)null))
			{
				Dictionary<ulong, NetworkObject> spawnedObjects = singleton.SpawnManager.SpawnedObjects;
				if (!spawnedObjects.ContainsKey(_wormPlayerObjectID) || !((Object)(object)((Component)spawnedObjects[_wormPlayerObjectID]).GetComponentInChildren<WormMouth>() != (Object)null))
				{
					_wormPlayerObjectID = ((NetworkBehaviour)last_ai_mouth).NetworkObject.NetworkObjectId;
				}
			}
		}

		[HarmonyPatch(typeof(StruggleMiniGameHandler), "InformWormTheMiniGameIsOver_ServerRPC")]
		[HarmonyPrefix]
		public static bool InformWormTheMiniGameIsOver_Prefix(StruggleMiniGameHandler __instance, ulong _wormPlayerID, ulong _humanPlayerID, int _damage)
		{
			if (forced_releases.TryGetValue(_humanPlayerID, out var value))
			{
				if (Time.unscaledTime <= value.expires_at && value.worm_owner_id == _wormPlayerID)
				{
					forced_releases.Remove(_humanPlayerID);
					ai_grabber.Remove(_humanPlayerID);
					ClearGrabbedFlag(_humanPlayerID);
					return false;
				}
				if (Time.unscaledTime > value.expires_at)
				{
					forced_releases.Remove(_humanPlayerID);
				}
			}
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsHost || !ai_grabber.TryGetValue(_humanPlayerID, out var value2) || (Object)(object)value2 == (Object)null)
			{
				return true;
			}
			try
			{
				value2.PlayerMiniGameEnded_ServerRPC(_damage);
				if ((Object)(object)LobbyManager.Singleton != (Object)null && LobbyManager.Singleton.cachedClients.ContainsKey(_humanPlayerID))
				{
					Player component = ((Component)LobbyManager.Singleton.cachedClients[_humanPlayerID].PlayerObject).GetComponent<Player>();
					if ((Object)(object)component != (Object)null)
					{
						component.currentlyInWormMouth.Value = false;
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.log.LogWarning((object)("ai grab-release reroute failed: " + ex.Message));
			}
			((MonoBehaviour)__instance).StartCoroutine(BroadcastMiniGameEndedNextFrame(__instance, _humanPlayerID));
			ai_grabber.Remove(_humanPlayerID);
			return false;
		}

		public static bool ReleaseBeforeDespawn(WormMouth mouth)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			if ((Object)(object)mouth == (Object)null || (int)mouth.thingInMouthType.Value != 2 || mouth.playerIDInMouth == 1000000)
			{
				return false;
			}
			ulong playerIDInMouth = mouth.playerIDInMouth;
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsHost || !singleton.ConnectedClients.ContainsKey(playerIDInMouth))
			{
				return false;
			}
			forced_releases[playerIDInMouth] = new ForcedRelease
			{
				worm_owner_id = ((NetworkBehaviour)mouth).OwnerClientId,
				expires_at = Time.unscaledTime + 10f
			};
			ai_grabber.Remove(playerIDInMouth);
			if ((Object)(object)last_ai_mouth == (Object)(object)mouth)
			{
				last_ai_mouth = null;
			}
			ClearGrabbedFlag(playerIDInMouth);
			try
			{
				mouth.DropPlayerInOurMouth_ServerRPC();
				return true;
			}
			catch (Exception ex)
			{
				forced_releases.Remove(playerIDInMouth);
				Plugin.log.LogWarning((object)("ai grab release before despawn failed: " + ex.Message));
				return false;
			}
		}

		public static void ReconcileMouthFlags()
		{
			NetworkManager singleton = NetworkManager.Singleton;
			GameManager singleton2 = GameManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsHost || (Object)(object)singleton2 == (Object)null || singleton2.humanPlayerScripts == null)
			{
				return;
			}
			foreach (Player humanPlayerScript in singleton2.humanPlayerScripts)
			{
				if ((Object)(object)humanPlayerScript == (Object)null)
				{
					continue;
				}
				bool value;
				try
				{
					value = humanPlayerScript.currentlyInWormMouth.Value;
				}
				catch
				{
					continue;
				}
				if (value && !IsHeldByAnyMouth(((NetworkBehaviour)humanPlayerScript).OwnerClientId))
				{
					try
					{
						humanPlayerScript.currentlyInWormMouth.Value = false;
					}
					catch
					{
					}
				}
			}
		}

		private static bool IsHeldByAnyMouth(ulong owner_id)
		{
			foreach (GameObject ai_worm in AiWormManager.ai_worms)
			{
				if ((Object)(object)ai_worm != (Object)null && MouthHolds(ai_worm.GetComponentInChildren<WormMouth>(true), owner_id))
				{
					return true;
				}
			}
			GameManager singleton = GameManager.Singleton;
			if ((Object)(object)singleton != (Object)null && singleton.wormPlayerScripts != null)
			{
				foreach (WormPlayer wormPlayerScript in singleton.wormPlayerScripts)
				{
					if ((Object)(object)wormPlayerScript != (Object)null && MouthHolds(((Component)wormPlayerScript).GetComponentInChildren<WormMouth>(true), owner_id))
					{
						return true;
					}
				}
			}
			return false;
		}

		private static bool MouthHolds(WormMouth mouth, ulong owner_id)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			if ((Object)(object)mouth != (Object)null && (int)mouth.thingInMouthType.Value == 2)
			{
				return mouth.playerIDInMouth == owner_id;
			}
			return false;
		}

		private static void ClearGrabbedFlag(ulong human_player_id)
		{
			if (!((Object)(object)LobbyManager.Singleton == (Object)null) && LobbyManager.Singleton.cachedClients.ContainsKey(human_player_id))
			{
				Player component = ((Component)LobbyManager.Singleton.cachedClients[human_player_id].PlayerObject).GetComponent<Player>();
				if ((Object)(object)component != (Object)null)
				{
					component.currentlyInWormMouth.Value = false;
				}
			}
		}

		private static IEnumerator BroadcastMiniGameEndedNextFrame(StruggleMiniGameHandler handler, ulong human_player_id)
		{
			yield return null;
			if ((Object)(object)handler == (Object)null || mini_game_ended_client_rpc == null)
			{
				Plugin.log.LogWarning((object)"ai grab-release cleanup rpc was unavailable");
				yield break;
			}
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsHost || !singleton.IsListening || !singleton.ConnectedClients.TryGetValue(human_player_id, out var value) || (Object)(object)value.PlayerObject == (Object)null || !singleton.SpawnManager.SpawnedObjects.ContainsKey(value.PlayerObject.NetworkObjectId))
			{
				yield break;
			}
			try
			{
				mini_game_ended_client_rpc.Invoke(handler, new object[1] { value.PlayerObject.NetworkObjectId });
			}
			catch (Exception ex)
			{
				Plugin.log.LogWarning((object)("ai grab-release cleanup broadcast failed: " + ex.Message));
			}
		}
	}
	[HarmonyPatch]
	public static class HeartJarDropPatches
	{
		private const ulong NO_JAR = 1000000uL;

		[HarmonyPatch(typeof(HeartJarManager), "HandleDictionaryTimesAndSpawningJars")]
		[HarmonyPrefix]
		public static void HandleDictionaryTimes_Prefix(HeartJarManager __instance)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager singleton = NetworkManager.Singleton;
			GameManager singleton2 = GameManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsHost || (Object)(object)singleton2 == (Object)null || (int)singleton2.gameState != 1 || __instance.heartJarInfo_MasterDictionary == null)
			{
				return;
			}
			List<HeartJarInfo> list = null;
			foreach (HeartJarInfo value in __instance.heartJarInfo_MasterDictionary.Values)
			{
				if (value != null && (int)value.lastCauseOfDeath == 0 && !(value.timeBeforeDigested > 0f) && IsSpawnable(value.heartJarState) && !VanillaCanResolve(singleton, value.wormIdWhoAteThem))
				{
					(list ?? (list = new List<HeartJarInfo>())).Add(value);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (HeartJarInfo item in list)
			{
				try
				{
					DropEatenJar(__instance, singleton, singleton2, item);
				}
				catch (Exception ex)
				{
					Plugin.log.LogWarning((object)("ai heart-jar drop failed: " + ex.Message));
				}
			}
		}

		private static void DropEatenJar(HeartJarManager manager, NetworkManager nm, GameManager gm, HeartJarInfo info)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: 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)
			Vector3 val = ResolveDropPosition(nm, info);
			float num = gm.CalculateSurfacedYPosition(val);
			if (val.y <= num)
			{
				val.y = num;
			}
			NetworkObject value;
			if ((int)info.heartJarState == 0)
			{
				Traverse.Create((object)manager).Method("SpawnPlayerHeartJar_ServerRPC", new object[3] { info.ownerID, val, true }).GetValue();
			}
			else if (info.spawnedJarObjectID != 1000000 && nm.SpawnManager.SpawnedObjects.TryGetValue(info.spawnedJarObjectID, out value) && (Object)(object)value != (Object)null)
			{
				Traverse.Create((object)manager).Method("SetHeartJarToInteractable_ServerRPC", new object[1] { info.spawnedJarObjectID }).GetValue();
				Rigidbody component = ((Component)value).GetComponent<Rigidbody>();
				if ((Object)(object)component != (Object)null)
				{
					component.velocity = Vector3.zero;
				}
				Component component2 = ((Component)value).GetComponent("NetworkTransform");
				if ((Object)(object)component2 != (Object)null)
				{
					Traverse.Create((object)component2).Method("Teleport", new object[3]
					{
						val,
						((Component)value).transform.rotation,
						((Component)value).transform.localScale
					}).GetValue();
				}
				else
				{
					((Component)value).transform.position = val;
				}
				if ((Object)(object)component != (Object)null)
				{
					Traverse.Create((object)manager).Method("HeartJarBoopUpwardForce", new object[1] { component }).GetValue();
				}
			}
			info.heartJarState = (HeartJarState)3;
		}

		private static Vector3 ResolveDropPosition(NetworkManager nm, HeartJarInfo info)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			foreach (GameObject ai_worm in AiWormManager.ai_worms)
			{
				if (!((Object)(object)ai_worm == (Object)null))
				{
					InGameWormCosmeticBuilder componentInChildren = ai_worm.GetComponentInChildren<InGameWormCosmeticBuilder>(true);
					if ((Object)(object)componentInChildren != (Object)null)
					{
						return componentInChildren.GetWormTailPosition() + Vector3.up;
					}
				}
			}
			if (nm.ConnectedClients.TryGetValue(info.ownerID, out var value) && (Object)(object)value.PlayerObject != (Object)null)
			{
				return ((Component)value.PlayerObject).transform.position + Vector3.up;
			}
			return new Vector3(0f, 10f, 0f);
		}

		private static bool VanillaCanResolve(NetworkManager nm, ulong worm_id)
		{
			if (nm.ConnectedClients.TryGetValue(worm_id, out var value) && (Object)(object)value.PlayerObject != (Object)null)
			{
				return (Object)(object)((Component)value.PlayerObject).GetComponent<InGameWormCosmeticBuilder>() != (Object)null;
			}
			return false;
		}

		private static bool IsSpawnable(HeartJarState state)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Invalid comparison between Unknown and I4
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			if ((int)state != 0 && (int)state != 1)
			{
				return (int)state == 2;
			}
			return true;
		}
	}
	public class LobbyAiState : MonoBehaviour
	{
		private const string PREFERENCE_MESSAGE = "com.wormtown.ai.preference.v3";

		private const string PREFERENCE_ACK_MESSAGE = "com.wormtown.ai.preference-ack.v3";

		private const byte PROTOCOL_VERSION = 3;

		private const float PREFERENCE_RETRY_INITIAL_SECONDS = 1f;

		private const float PREFERENCE_RETRY_MAX_SECONDS = 10f;

		private const float PREFERENCE_CHANGE_COOLDOWN = 0.25f;

		private const float MOUTH_RECONCILE_INTERVAL = 0.5f;

		private const string SERVICE_OBJECT_NAME = "WormtownAI Runtime Services";

		private static LobbyAiState instance;

		private readonly Dictionary<ulong, AiWormDifficulty> enabled_clients = new Dictionary<ulong, AiWormDifficulty>();

		private readonly Dictionary<ulong, float> next_preference_change_time = new Dictionary<ulong, float>();

		private NetworkManager network_manager;

		private bool registered_as_host;

		private bool preference_acknowledged;

		private float next_preference_send_time;

		private float preference_retry_seconds;

		private float next_mouth_reconcile;

		private WormAbilityPickerBank applied_picker;

		private bool loadout_saved;

		private bool logged_loadout_error;

		private int bile_bomb_index = -1;

		private int sand_storm_index = -1;

		public static bool IsLocalHost
		{
			get
			{
				NetworkManager singleton = NetworkManager.Singleton;
				if ((Object)(object)singleton != (Object)null)
				{
					return singleton.IsHost;
				}
				return false;
			}
		}

		public static bool IsHostEnabled
		{
			get
			{
				MenuToGameBridger singleton = MenuToGameBridger.Singleton;
				if (IsLocalHost && EnabledWormCount > 0)
				{
					if (!((Object)(object)singleton == (Object)null))
					{
						if (!singleton.isWormTutorial)
						{
							return !singleton.isPardnerTutorial;
						}
						return false;
					}
					return true;
				}
				return false;
			}
		}

		public static int EnabledWormCount
		{
			get
			{
				if (!IsLocalHost)
				{
					return 0;
				}
				if ((Object)(object)instance != (Object)null && instance.registered_as_host)
				{
					return instance.enabled_clients.Count;
				}
				return Settings.ai_enabled ? 1 : 0;
			}
		}

		public static bool IsClientEnabled(ulong client_id)
		{
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null)
			{
				return false;
			}
			if (client_id == singleton.LocalClientId)
			{
				if (Settings.ai_enabled)
				{
					if (!singleton.IsHost)
					{
						if ((Object)(object)instance != (Object)null && (Object)(object)instance.network_manager == (Object)(object)singleton)
						{
							return instance.preference_acknowledged;
						}
						return false;
					}
					return true;
				}
				return false;
			}
			if (singleton.IsHost && (Object)(object)instance != (Object)null && instance.registered_as_host)
			{
				return instance.enabled_clients.ContainsKey(client_id);
			}
			return false;
		}

		public static AiWormDifficulty GetClientDifficulty(ulong client_id)
		{
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton != (Object)null && client_id == singleton.LocalClientId)
			{
				return Settings.ai_difficulty;
			}
			if ((Object)(object)singleton != (Object)null && singleton.IsHost && (Object)(object)instance != (Object)null && instance.enabled_clients.TryGetValue(client_id, out var value))
			{
				return value;
			}
			return AiWormDifficulty.Garden;
		}

		public static IEnumerable<ulong> GetEnabledClientIds()
		{
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsHost)
			{
				yield break;
			}
			if ((Object)(object)instance != (Object)null && instance.registered_as_host)
			{
				foreach (ulong key in instance.enabled_clients.Keys)
				{
					yield return key;
				}
			}
			else if (Settings.ai_enabled)
			{
				yield return singleton.LocalClientId;
			}
		}

		public static void Initialize(bool enabled, AiWormDifficulty difficulty)
		{
			Settings.ai_enabled = enabled;
			Settings.ai_difficulty = AiWormDifficultyRules.Clamp((int)difficulty);
		}

		public static bool EnsureAvailable()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			if ((Object)(object)instance != (Object)null)
			{
				return true;
			}
			try
			{
				LobbyAiState lobbyAiState = Object.FindObjectOfType<LobbyAiState>();
				GameObject val = (((Object)(object)lobbyAiState != (Object)null) ? ((Component)lobbyAiState).gameObject : GameObject.Find("WormtownAI Runtime Services"));
				if ((Object)(object)val == (Object)null)
				{
					val = new GameObject("WormtownAI Runtime Services");
					Object.DontDestroyOnLoad((Object)(object)val);
				}
				lobbyAiState = val.GetComponent<LobbyAiState>();
				if ((Object)(object)lobbyAiState == (Object)null)
				{
					lobbyAiState = val.AddComponent<LobbyAiState>();
				}
				instance = lobbyAiState;
				return (Object)(object)instance != (Object)null;
			}
			catch (Exception ex)
			{
				Plugin.log.LogWarning((object)("[ai-toggle] coordinator creation failed: " + ex.Message));
				return false;
			}
		}

		public static void SetLocalEnabled(bool enabled)
		{
			if (!EnsureAvailable())
			{
				Plugin.log.LogWarning((object)"[ai-toggle] coordinator unavailable; setting unchanged");
				return;
			}
			Settings.ai_enabled = enabled;
			Plugin.SaveLocalPreferences();
			instance.applied_picker = null;
			instance.loadout_saved = false;
			TeamPatches.ResetAssignments();
			if ((Object)(object)instance.network_manager != (Object)null && instance.registered_as_host)
			{
				if (instance.SetClientPreference(instance.network_manager.LocalClientId, enabled, Settings.ai_difficulty))
				{
					instance.OnEnabledClientsChanged();
				}
			}
			else
			{
				instance.ResetPreferenceSends();
				instance.TrySendLocalPreference();
			}
			Plugin.log.LogInfo((object)$"[ai-toggle] local AI Worm enabled = {enabled}");
		}

		public static void SetLocalDifficulty(AiWormDifficulty difficulty)
		{
			difficulty = AiWormDifficultyRules.Clamp((int)difficulty);
			if (difficulty == Settings.ai_difficulty || !EnsureAvailable())
			{
				return;
			}
			Settings.ai_difficulty = difficulty;
			Plugin.SaveLocalPreferences();
			if ((Object)(object)instance.network_manager != (Object)null && instance.registered_as_host)
			{
				if (instance.SetClientPreference(instance.network_manager.LocalClientId, Settings.ai_enabled, difficulty))
				{
					instance.OnEnabledClientsChanged();
				}
			}
			else
			{
				instance.ResetPreferenceSends();
				instance.TrySendLocalPreference();
			}
			Plugin.log.LogInfo((object)("[ai-toggle] local AI Worm difficulty = " + AiWormDifficultyRules.DisplayName(difficulty)));
		}

		public static bool EnsureAiLoadout()
		{
			if ((Object)(object)instance != (Object)null && IsHostEnabled)
			{
				if (!instance.loadout_saved)
				{
					return instance.TryApplyAiLoadout();
				}
				return true;
			}
			return false;
		}

		public static bool ApplyAiLoadout(WormAbilityManager ability_manager)
		{
			if ((Object)(object)ability_manager == (Object)null || !IsLocalHost)
			{
				return false;
			}
			int num = (((Object)(object)instance != (Object)null) ? instance.bile_bomb_index : (-1));
			int num2 = (((Object)(object)instance != (Object)null) ? instance.sand_storm_index : (-1));
			if (num < 0 || num2 < 0)
			{
				WormAbility[] value = Traverse.Create((object)ability_manager).Field("abilityBank").GetValue<WormAbility[]>();
				num = FindAbilityIndex<WormAbility_BileBomb>(value);
				num2 = FindAbilityIndex<WormAbility_SandStorm>(value);
				if (num < 0 || num2 < 0)
				{
					return false;
				}
				if ((Object)(object)instance != (Object)null)
				{
					instance.bile_bomb_index = num;
					instance.sand_storm_index = num2;
				}
			}
			ability_manager.AddAbility(1, num);
			ability_manager.AddAbility(2, num2);
			return true;
		}

		private void Awake()
		{
			if ((Object)(object)instance != (Object)null && (Object)(object)instance != (Object)(object)this)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			instance = this;
			Plugin.log.LogInfo((object)"[ai-toggle] coordinator ready");
		}

		private void OnDestroy()
		{
			UnregisterNetworkManager();
			if ((Object)(object)instance == (Object)(object)this)
			{
				instance = null;
				Plugin.log.LogInfo((object)"[ai-toggle] coordinator stopped");
			}
		}

		private void Update()
		{
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)network_manager != (Object)null && ((Object)(object)network_manager != (Object)(object)singleton || !network_manager.IsListening))
			{
				UnregisterNetworkManager();
			}
			if ((Object)(object)network_manager == (Object)null && (Object)(object)singleton != (Object)null && singleton.IsListening)
			{
				RegisterNetworkManager(singleton);
			}
			if ((Object)(object)network_manager == (Object)null)
			{
				return;
			}
			if (registered_as_host)
			{
				if (IsHostEnabled)
				{
					TeamPatches.EnsureEnabledPlayersArePardners();
					if (!loadout_saved || (Object)(object)applied_picker != (Object)(object)WormAbilityPickerBank.Singleton)
					{
						TryApplyAiLoadout();
					}
					if (Time.unscaledTime >= next_mouth_reconcile)
					{
						next_mouth_reconcile = Time.unscaledTime + 0.5f;
						GrabReleasePatches.ReconcileMouthFlags();
					}
				}
			}
			else
			{
				TrySendLocalPreference();
			}
		}

		private void RegisterNetworkManager(NetworkManager manager)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			network_manager = manager;
			registered_as_host = manager.IsHost;
			preference_acknowledged = false;
			enabled_clients.Clear();
			next_preference_change_time.Clear();
			manager.CustomMessagingManager.RegisterNamedMessageHandler("com.wormtown.ai.preference.v3", new HandleNamedMessageDelegate(ReceivePreference));
			manager.CustomMessagingManager.RegisterNamedMessageHandler("com.wormtown.ai.preference-ack.v3", new HandleNamedMessageDelegate(ReceivePreferenceAck));
			manager.OnClientConnectedCallback += OnClientConnected;
			manager.OnClientDisconnectCallback += OnClientDisconnected;
			TeamPatches.ResetAssignments();
			if (registered_as_host)
			{
				SetClientPreference(manager.LocalClientId, Settings.ai_enabled, Settings.ai_difficulty);
				OnEnabledClientsChanged();
			}
			else
			{
				ResetPreferenceSends();
			}
		}

		private void UnregisterNetworkManager()
		{
			if (!((Object)(object)network_manager == (Object)null))
			{
				try
				{
					network_manager.CustomMessagingManager.UnregisterNamedMessageHandler("com.wormtown.ai.preference.v3");
					network_manager.CustomMessagingManager.UnregisterNamedMessageHandler("com.wormtown.ai.preference-ack.v3");
					network_manager.OnClientConnectedCallback -= OnClientConnected;
					network_manager.OnClientDisconnectCallback -= OnClientDisconnected;
				}
				catch
				{
				}
				network_manager = null;
				registered_as_host = false;
				preference_acknowledged = false;
				enabled_clients.Clear();
				next_preference_change_time.Clear();
				applied_picker = null;
				TeamPatches.ResetAssignments();
			}
		}

		private void OnClientConnected(ulong client_id)
		{
			if (!registered_as_host && (Object)(object)network_manager != (Object)null && client_id == network_manager.LocalClientId)
			{
				ResetPreferenceSends();
			}
		}

		private void OnClientDisconnected(ulong client_id)
		{
			next_preference_change_time.Remove(client_id);
			if (registered_as_host && enabled_clients.Remove(client_id))
			{
				OnEnabledClientsChanged();
			}
		}

		private bool SetClientPreference(ulong client_id, bool enabled, AiWormDifficulty difficulty)
		{
			if (!enabled)
			{
				return enabled_clients.Remove(client_id);
			}
			difficulty = AiWormDifficultyRules.Clamp((int)difficulty);
			if (enabled_clients.TryGetValue(client_id, out var value) && value == difficulty)
			{
				return false;
			}
			enabled_clients[client_id] = difficulty;
			return true;
		}

		private void OnEnabledClientsChanged()
		{
			applied_picker = null;
			loadout_saved = false;
			TeamPatches.ResetAssignments();
			if (IsHostEnabled)
			{
				try
				{
					ApplyEnabledEffects();
				}
				catch (Exception ex)
				{
					Plugin.log.LogWarning((object)("[ai-toggle] enable side effect failed: " + ex.Message));
				}
			}
			AiWormManager.ReconcileSpawnedWorms();
		}

		private void ResetPreferenceSends()
		{
			preference_acknowledged = false;
			next_preference_send_time = Time.unscaledTime;
			preference_retry_seconds = 1f;
		}

		private unsafe void TrySendLocalPreference()
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			if (registered_as_host || preference_acknowledged || (Object)(object)network_manager == (Object)null || !network_manager.IsConnectedClient || Time.unscaledTime < next_preference_send_time)
			{
				return;
			}
			try
			{
				FastBufferWriter val = default(FastBufferWriter);
				((FastBufferWriter)(ref val))..ctor(3, (Allocator)2, 3);
				try
				{
					((FastBufferWriter)(ref val)).WriteByteSafe((byte)3);
					((FastBufferWriter)(ref val)).WriteByteSafe(Settings.ai_enabled ? ((byte)1) : ((byte)0));
					((FastBufferWriter)(ref val)).WriteByteSafe((byte)Settings.ai_difficulty);
					network_manager.CustomMessagingManager.SendNamedMessage("com.wormtown.ai.preference.v3", 0uL, val, (NetworkDelivery)2);
				}
				finally
				{
					((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
				}
			}
			catch
			{
			}
			next_preference_send_time = Time.unscaledTime + preference_retry_seconds;
			preference_retry_seconds = Mathf.Min(10f, preference_retry_seconds * 2f);
		}

		private void ReceivePreference(ulong sender_client_id, FastBufferReader reader)
		{
			if (!registered_as_host || (Object)(object)network_manager == (Object)null || !network_manager.IsHost || !network_manager.ConnectedClients.ContainsKey(sender_client_id) || ((FastBufferReader)(ref reader)).Length < 3)
			{
				return;
			}
			byte b = default(byte);
			byte b2 = default(byte);
			byte b3 = default(byte);
			try
			{
				((FastBufferReader)(ref reader)).ReadByteSafe(ref b);
				((FastBufferReader)(ref reader)).ReadByteSafe(ref b2);
				((FastBufferReader)(ref reader)).ReadByteSafe(ref b3);
			}
			catch
			{
				return;
			}
			if (b != 3 || b2 > 1 || b3 > 2)
			{
				return;
			}
			bool flag = b2 != 0;
			AiWormDifficulty aiWormDifficulty = (AiWormDifficulty)b3;
			AiWormDifficulty value;
			bool flag2 = enabled_clients.TryGetValue(sender_client_id, out value);
			bool flag3 = flag2 != flag;
			if (flag3 || (flag && value != aiWormDifficulty))
			{
				if (!IsPreferenceChangeAllowed() || (flag3 && next_preference_change_time.TryGetValue(sender_client_id, out var value2) && Time.unscaledTime < value2))
				{
					SendPreferenceAck(sender_client_id, flag2, flag2 ? value : aiWormDifficulty);
					return;
				}
				if (flag3)
				{
					next_preference_change_time[sender_client_id] = Time.unscaledTime + 0.25f;
				}
				SetClientPreference(sender_client_id, flag, aiWormDifficulty);
				OnEnabledClientsChanged();
				Plugin.log.LogInfo((object)($"[ai-toggle] client {sender_client_id} AI Worm enabled = {flag}, " + "difficulty = " + AiWormDifficultyRules.DisplayName(aiWormDifficulty)));
			}
			SendPreferenceAck(sender_client_id, flag, aiWormDifficulty);
		}

		private void ReceivePreferenceAck(ulong sender_client_id, FastBufferReader reader)
		{
			if (!registered_as_host && !((Object)(object)network_manager == (Object)null) && sender_client_id == 0L && ((FastBufferReader)(ref reader)).Length >= 3)
			{
				byte b = default(byte);
				byte b2 = default(byte);
				byte b3 = default(byte);
				try
				{
					((FastBufferReader)(ref reader)).ReadByteSafe(ref b);
					((FastBufferReader)(ref reader)).ReadByteSafe(ref b2);
					((FastBufferReader)(ref reader)).ReadByteSafe(ref b3);
				}
				catch
				{
					return;
				}
				if (b == 3 && b2 != 0 == Settings.ai_enabled && (uint)b3 == (uint)Settings.ai_difficulty)
				{
					preference_acknowledged = true;
				}
			}
		}

		private static bool IsPreferenceChangeAllowed()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			GameManager singleton = GameManager.Singleton;
			MenuToGameBridger singleton2 = MenuToGameBridger.Singleton;
			if ((Object)(object)singleton != (Object)null && (int)singleton.gameState == 0)
			{
				if (!((Object)(object)singleton2 == (Object)null))
				{
					if (!singleton2.isWormTutorial)
					{
						return !singleton2.isPardnerTutorial;
					}
					return false;
				}
				return true;
			}
			return false;
		}

		private unsafe void SendPreferenceAck(ulong client_id, bool enabled, AiWormDifficulty difficulty)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				FastBufferWriter val = default(FastBufferWriter);
				((FastBufferWriter)(ref val))..ctor(3, (Allocator)2, 3);
				try
				{
					((FastBufferWriter)(ref val)).WriteByteSafe((byte)3);
					((FastBufferWriter)(ref val)).WriteByteSafe(enabled ? ((byte)1) : ((byte)0));
					((FastBufferWriter)(ref val)).WriteByteSafe((byte)difficulty);
					network_manager.CustomMessagingManager.SendNamedMessage("com.wormtown.ai.preference-ack.v3", client_id, val, (NetworkDelivery)2);
				}
				finally
				{
					((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
				}
			}
			catch
			{
			}
		}

		private void ApplyEnabledEffects()
		{
			if (IsHostEnabled)
			{
				Plugin.EnsurePolicyLoaded();
				TeamPatches.EnsureEnabledPlayersArePardners();
				TryApplyAiLoadout();
			}
		}

		private bool TryApplyAiLoadout()
		{
			try
			{
				MenuToGameBridger singleton = MenuToGameBridger.Singleton;
				if (!IsHostEnabled || (Object)(object)singleton == (Object)null || singleton.savedWormAbilitySet == null || !TryResolveAiLoadout(null))
				{
					return false;
				}
				singleton.savedWormAbilitySet.savedSlotAbilityIndex_1 = bile_bomb_index;
				singleton.savedWormAbilitySet.savedSlotAbilityIndex_2 = sand_storm_index;
				loadout_saved = true;
				WormAbilityPickerBank singleton2 = WormAbilityPickerBank.Singleton;
				if ((Object)(object)singleton2 == (Object)null)
				{
					return true;
				}
				if (singleton2.slotButtons == null || singleton2.slotButtons.Length < 3 || singleton2.pickerBank == null || bile_bomb_index >= singleton2.pickerBank.Length || sand_storm_index >= singleton2.pickerBank.Length)
				{
					LogLoadoutError("could not refresh the worm ability picker");
					return true;
				}
				singleton2.AssignNewAbility(1, bile_bomb_index);
				singleton2.AssignNewAbility(2, sand_storm_index);
				applied_picker = singleton2;
				logged_loadout_error = false;
				Plugin.log.LogInfo((object)"[ai-toggle] set worm powers to Bile Bomb and Sandstorm");
				return true;
			}
			catch (Exception ex)
			{
				LogLoadoutError("could not assign the required worm abilities: " + ex.Message);
				return false;
			}
		}

		private bool TryResolveAiLoadout(WormAbilityManager ability_manager)
		{
			if (bile_bomb_index >= 0 && sand_storm_index >= 0)
			{
				return true;
			}
			if ((Object)(object)ability_manager == (Object)null && (Object)(object)GameManager.Singleton != (Object)null && (Object)(object)GameManager.Singleton.wormPrefab != (Object)null)
			{
				ability_manager = GameManager.Singleton.wormPrefab.GetComponentInChildren<WormAbilityManager>(true);
			}
			WormAbility[] ability_bank = (((Object)(object)ability_manager != (Object)null) ? Traverse.Create((object)ability_manager).Field("abilityBank").GetValue<WormAbility[]>() : null);
			bile_bomb_index = FindAbilityIndex<WormAbility_BileBomb>(ability_bank);
			sand_storm_index = FindAbilityIndex<WormAbility_SandStorm>(ability_bank);
			if (bile_bomb_index >= 0 && sand_storm_index >= 0)
			{
				return true;
			}
			WormAbilityPickerBank singleton = WormAbilityPickerBank.Singleton;
			WormAbilityUIPicker[] picker_bank = (((Object)(object)singleton != (Object)null) ? singleton.pickerBank : null);
			bile_bomb_index = FindPickerAbilityIndex(picker_bank, "bilebomb");
			sand_storm_index = FindPickerAbilityIndex(picker_bank, "sandstorm");
			if (bile_bomb_index >= 0 && sand_storm_index >= 0)
			{
				return true;
			}
			LogLoadoutError("could not resolve the required worm abilities");
			return false;
		}

		private void LogLoadoutError(string message)
		{
			if (!logged_loadout_error)
			{
				logged_loadout_error = true;
				Plugin.log.LogWarning((object)("[ai-toggle] " + message));
			}
		}

		private static int FindAbilityIndex<TAbility>(WormAbility[] ability_bank) where TAbility : WormAbility
		{
			if (ability_bank == null)
			{
				return -1;
			}
			for (int i = 0; i < ability_bank.Length; i++)
			{
				if (ability_bank[i] is TAbility)
				{
					return i;
				}
			}
			return -1;
		}

		private static int FindPickerAbilityIndex(WormAbilityUIPicker[] picker_bank, string ability_key)
		{
			if (picker_bank == null)
			{
				return -1;
			}
			for (int i = 0; i < picker_bank.Length; i++)
			{
				WormAbilityUIPicker val = picker_bank[i];
				if ((Object)(object)val != (Object)null && (NormalizeAbilityKey(val.abilityName).Contains(ability_key) || NormalizeAbilityKey(((Object)val).name).Contains(ability_key)))
				{
					return i;
				}
			}
			return -1;
		}

		private static string NormalizeAbilityKey(string value)
		{
			if (string.IsNullOrEmpty(value))
			{
				return string.Empty;
			}
			char[] array = new char[value.Length];
			int length = 0;
			foreach (char c in value)
			{
				if (char.IsLetterOrDigit(c))
				{
					array[length++] = char.ToLowerInvariant(c);
				}
			}
			return new string(array, 0, length);
		}
	}
	[HarmonyPatch]
	public static class LobbyAiStatePatches
	{
		[HarmonyPatch(typeof(LobbyManager), "OnNetworkSpawn", new Type[] { })]
		[HarmonyPostfix]
		public static void OnNetworkSpawn_Postfix()
		{
			LobbyAiState.EnsureAvailable();
		}
	}
	[HarmonyPatch]
	public static class LobbySettingsUI
	{
		private const string PANEL_NAME = "Worm AI Panel";

		private const string TOGGLE_BUTTON_NAME = "Toggle Button (ITS A BUTTON, Toggles are dumb)";

		private const float PANEL_HEIGHT = 220f;

		private const float PANEL_GAP = 12f;

		private const float TITLE_Y = 72f;

		private const float TOGGLE_Y = 5f;

		private const float DIFFICULTY_Y = -63f;

		[HarmonyPatch(typeof(ConnectedPlayerLobbyPanel), "SetupPanel")]
		[HarmonyPostfix]
		public static void SetupPanel_Postfix()
		{
			EnsurePanel();
		}

		[HarmonyPatch(typeof(MatchSettingsManager), "OnNetworkSpawn")]
		[HarmonyPostfix]
		public static void MatchSettingsManager_OnNetworkSpawn_Postfix()
		{
			EnsurePanel();
		}

		private static void EnsurePanel()
		{
			try
			{
				LobbyAiState.EnsureAvailable();
				TryAdd();
			}
			catch (Exception ex)
			{
				Plugin.log.LogWarning((object)("[ai-toggle] failed: " + ex.Message));
			}
		}

		private static void TryAdd()
		{
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Expected O, but got Unknown
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0404: Expected O, but got Unknown
			//IL_0494: Unknown result type (might be due to invalid IL or missing references)
			//IL_0544: Unknown result type (might be due to invalid IL or missing references)
			//IL_054e: Expected O, but got Unknown
			//IL_05c8: Unknown result type (might be due to invalid IL or missing references)
			MatchSettingsManager val = Object.FindObjectOfType<MatchSettingsManager>();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			GameObject val2 = RefGameObject(val, "WormAbilityScream_CheckBox_CheckMarkImage");
			Transform val3 = (((Object)(object)val2 != (Object)null) ? val2.transform.parent : null);
			Transform val4 = (((Object)(object)val3 != (Object)null) ? val3.parent : null);
			Transform val5 = (((Object)(object)val4 != (Object)null) ? val4.parent : null);
			if ((Object)(object)val4 == (Object)null || (Object)(object)val5 == (Object)null || (Object)(object)val5.Find("Worm AI Panel") != (Object)null)
			{
				return;
			}
			Transform val6 = val5.Find("Backer");
			Transform val7 = val5.Find("Worm Settings Header");
			Transform val8 = FindMapGroup(val);
			Transform val9 = (((Object)(object)val8 != (Object)null) ? val8.Find("Backer") : null);
			Transform val10 = (((Object)(object)val9 != (Object)null) ? val9 : val6);
			Component val11 = RefComponent(HudManager.Singleton, "matchSettings_WormAbilityCooldown_DifficultyText");
			Transform val12 = (((Object)(object)val11 != (Object)null) ? FindDirectChildAncestor(val11.transform, val5) : null);
			if ((Object)(object)val6 == (Object)null || (Object)(object)val7 == (Object)null || (Object)(object)val10 == (Object)null || (Object)(object)val12 == (Object)null)
			{
				Plugin.log.LogWarning((object)"[ai-toggle] source panel objects not found");
				return;
			}
			GameObject val13 = null;
			try
			{
				val13 = new GameObject("Worm AI Panel", new Type[1] { typeof(RectTransform) });
				val13.transform.SetParent(val5, false);
				RectTransform component = val13.GetComponent<RectTransform>();
				RectTransform component2 = ((Component)val6).GetComponent<RectTransform>();
				Rect rect = component2.rect;
				float num = Mathf.Abs(((Rect)(ref rect)).width);
				if (num < 1f)
				{
					num = Mathf.Abs(component2.sizeDelta.x);
				}
				rect = component2.rect;
				float num2 = Mathf.Abs(((Rect)(ref rect)).height);
				if (num2 < 1f)
				{
					num2 = Mathf.Abs(component2.sizeDelta.y);
				}
				float num3 = component2.anchoredPosition.y - num2 * component2.pivot.y;
				component.anchorMin = component2.anchorMin;
				component.anchorMax = component2.anchorMax;
				component.pivot = new Vector2(0.5f, 0.5f);
				component.sizeDelta = new Vector2(num, 220f);
				component.anchoredPosition = new Vector2(component2.anchoredPosition.x, num3 - 12f - 110f);
				((Transform)component).localScale = Vector3.one;
				GameObject val14 = Object.Instantiate<GameObject>(((Component)val10).gameObject, val13.transform);
				((Object)val14).name = "Backer";
				PlaceChild(val14, Vector2.zero, (Vector2?)new Vector2(num, 220f));
				Image component3 = val14.GetComponent<Image>();
				if ((Object)(object)component3 != (Object)null)
				{
					((Graphic)component3).raycastTarget = false;
				}
				GameObject val15 = Object.Instantiate<GameObject>(((Component)val7).gameObject, val13.transform);
				((Object)val15).name = "Worm AI Header";
				StripLocalizers(val15);
				PlaceChild(val15, new Vector2(0f, 72f), null);
				SetFirstLabel(val15, "Worm AI");
				GameObject val16 = Object.Instantiate<GameObject>(((Component)val4).gameObject, val13.transform);
				((Object)val16).name = "Enable Worm AI Group";
				StripLocalizers(val16);
				RemoveChild(val16.transform, "Sub Label");
				PlaceChild(val16, new Vector2(0f, 5f), null);
				SetFirstLabel(val16, "Enable AI Worm");
				Transform val17 = val16.transform.Find("Toggle Button (ITS A BUTTON, Toggles are dumb)");
				Button val18 = (((Object)(object)val17 != (Object)null) ? ((Component)val17).GetComponent<Button>() : null);
				Transform val19 = (((Object)(object)val17 != (Object)null) ? val17.Find("Checkmark") : null);
				GameObject checkmark = (((Object)(object)val19 != (Object)null) ? ((Component)val19).gameObject : null);
				if ((Object)(object)val18 == (Object)null)
				{
					throw new InvalidOperationException("cloned toggle button not found");
				}
				val18.onClick = new ButtonClickedEvent();
				val16.AddComponent<LobbyAiToggleBinding>().Initialize(val18, checkmark);
				string text = RelativePath(val12, val11.transform);
				GameObject val20 = RefGameObject(val, "wormAbilityCooldownMultiplier_CustomSettingsGroup");
				string text2 = (((Object)(object)val20 != (Object)null) ? RelativePath(val12, val20.transform) : null);
				GameObject val21 = Object.Instantiate<GameObject>(((Component)val12).gameObject, val13.transform);
				((Object)val21).name = "Worm AI Difficulty Group";
				StripLocalizers(val21);
				if (text2 != null)
				{
					RemoveChild(val21.transform, text2);
				}
				PlaceChild(val21, new Vector2(0f, -63f), null);
				Transform val22 = ((text != null) ? val21.transform.Find(text) : null);
				Component val23 = (((Object)(object)val22 != (Object)null) ? ((Component)val22).GetComponent(((object)val11).GetType()) : null);
				SetFirstLabelExcept(val21, val23, "Difficulty");
				Button[] componentsInChildren = val21.GetComponentsInChildren<Button>(false);
				if ((Object)(object)val23 == (Object)null || componentsInChildren.Length < 2)
				{
					throw new InvalidOperationException("cloned difficulty controls not found");
				}
				Array.Sort(componentsInChildren, (Button left, Button right) => ((Component)left).transform.position.x.CompareTo(((Component)right).transform.position.x));
				Button[] array = componentsInChildren;
				for (int num4 = 0; num4 < array.Length; num4++)
				{
					array[num4].onClick = new ButtonClickedEvent();
				}
				val21.AddComponent<LobbyAiDifficultyBinding>().Initialize(componentsInChildren[0], componentsInChildren[^1], val23);
				val14.transform.SetAsFirstSibling();
				val15.transform.SetSiblingIndex(1);
				val16.transform.SetAsLastSibling();
				val21.transform.SetAsLastSibling();
				val13.transform.SetAsLastSibling();
				val13.SetActive(true);
				Plugin.log.LogInfo((object)($"[ai-toggle] added Worm AI panel at {component.anchoredPosition} " + "using '" + ((Object)val10).name + "'"));
			}
			catch
			{
				if ((Object)(object)val13 != (Object)null)
				{
					Object.Destroy((Object)(object)val13);
				}
				throw;
			}
		}

		private static Transform FindMapGroup(MatchSettingsManager manager)
		{
			GameObject val = RefGameObject(manager, "cactusFruits_CustomSettingsGroup");
			Transform val2 = (((Object)(object)val != (Object)null) ? val.transform.parent : null);
			if (!((Object)(object)val2 != (Object)null))
			{
				return null;
			}
			return val2.parent;
		}

		private static Transform FindDirectChildAncestor(Transform child, Transform parent)
		{
			Transform val = child;
			while ((Object)(object)val != (Object)null && (Object)(object)val.parent != (Object)(object)parent)
			{
				val = val.parent;
			}
			if (!((Object)(object)val != (Object)null) || !((Object)(object)val.parent == (Object)(object)parent))
			{
				return null;
			}
			return val;
		}

		private static string RelativePath(Transform root, Transform child)
		{
			List<string> list = new List<string>();
			Transform val = child;
			while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root)
			{
				list.Add(((Object)val).name);
				val = val.parent;
			}
			if ((Object)(object)val != (Object)(object)root)
			{
				return null;
			}
			list.Reverse();
			return string.Join("/", list.ToArray());
		}

		private static void PlaceChild(GameObject child, Vector2 position, Vector2? size)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			child.SetActive(true);
			RectTransform component = child.GetComponent<RectTransform>();
			if (!((Object)(object)component == (Object)null))
			{
				component.anchorMin = new Vector2(0.5f, 0.5f);
				component.anchorMax = new Vector2(0.5f, 0.5f);
				component.pivot = new Vector2(0.5f, 0.5f);
				if (size.HasValue)
				{
					component.sizeDelta = size.Value;
				}
				component.anchoredPosition = position;
				((Transform)component).localScale = Vector3.one;
			}
		}

		private static void RemoveChild(Transform parent, string child_name)
		{
			Transform val = parent.Find(child_name);
			if ((Object)(object)val != (Object)null)
			{
				((Component)val).gameObject.SetActive(false);
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
		}

		private static void StripLocalizers(GameObject root)
		{
			Component[] componentsInChildren = root.GetComponentsInChildren<Component>(true);
			foreach (Component val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string name = ((object)val).GetType().Name;
					if (name.Contains("Localize") || name.Contains("Localizer"))
					{
						Object.Destroy((Object)(object)val);
					}
				}
			}
		}

		private static GameObject RefGameObject(object instance, string field_name)
		{
			FieldInfo field = instance.GetType().GetField(field_name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field == null)
			{
				return null;
			}
			object value = field.GetValue(instance);
			object obj = ((value is GameObject) ? value : null);
			if (obj == null)
			{
				object obj2 = ((value is Component) ? value : null);
				if (obj2 == null)
				{
					return null;
				}
				obj = ((Component)obj2).gameObject;
			}
			return (GameObject)obj;
		}

		private static Component RefComponent(object instance, string field_name)
		{
			if (instance == null)
			{
				return null;
			}
			FieldInfo field = instance.GetType().GetField(field_name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (!(field != null))
			{
				return null;
			}
			object? value = field.GetValue(instance);
			return (Component)((value is Component) ? value : null);
		}

		private static void SetFirstLabel(GameObject root, string text)
		{
			Component[] componentsInChildren = root.GetComponentsInChildren<Component>(false);
			foreach (Component val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				string name = ((object)val).GetType().Name;
				if (!(name != "TextMeshProUGUI") || !(name != "TMP_Text"))
				{
					PropertyInfo property = ((object)val).GetType().GetProperty("text");
					if (property != null)
					{
						property.SetValue(val, text, null);
					}
					break;
				}
			}
		}

		private static void SetFirstLabelExcept(GameObject root, Component excluded, string text)
		{
			Component[] componentsInChildren = root.GetComponentsInChildren<Component>(false);
			foreach (Component val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)excluded) && !((Object)(object)val.GetComponentInParent<Button>() != (Object)null))
				{
					string name = ((object)val).GetType().Name;
					if (!(name != "TextMeshProUGUI") || !(name != "TMP_Text"))
					{
						SetText(val, text);
						break;
					}
				}
			}
		}

		public static void SetText(Component label, string text)
		{
			if (!((Object)(object)label == (Object)null))
			{
				PropertyInfo property = ((object)label).GetType().GetProperty("text");
				if (property != null)
				{
					property.SetValue(label, text, null);
				}
			}
		}
	}
	public class LobbyAiToggleBinding : MonoBehaviour
	{
		private Button button;

		private GameObject mark;

		public void Initialize(Button toggle_button, GameObject checkmark)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			button = toggle_button;
			mark = checkmark;
			((UnityEvent)button.onClick).AddListener(new UnityAction(OnClicked));
			Refresh();
		}

		private void Update()
		{
			Refresh();
		}

		private void OnClicked()
		{
			LobbyAiState.SetLocalEnabled(!Settings.ai_enabled);
			Refresh();
		}

		private void Refresh()
		{
			if ((Object)(object)button != (Object)null)
			{
				((Selectable)button).interactable = true;
			}
			if ((Object)(object)mark != (Object)null && mark.activeSelf != Settings.ai_enabled)
			{
				mark.SetActive(Settings.ai_enabled);
			}
		}
	}
	public class LobbyAiDifficultyBinding : MonoBehaviour
	{
		private Button previous_button;

		private Button next_button;

		private Component value_label;

		public void Initialize(Button previous, Button next, Component label)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			previous_button = previous;
			next_button = next;
			value_label = label;
			((UnityEvent)previous_button.onClick).AddListener(new UnityAction(Previous));
			((UnityEvent)next_button.onClick).AddListener(new UnityAction(Next));
			Refresh();
		}

		private void Update()
		{
			Refresh();
		}

		private void Previous()
		{
			LobbyAiState.SetLocalDifficulty(AiWormDifficultyRules.Clamp((int)(Settings.ai_difficulty - 1)));
			Refresh();
		}

		private void Next()
		{
			LobbyAiState.SetLocalDifficulty(AiWormDifficultyRules.Clamp((int)(Settings.ai_difficulty + 1)));
			Refresh();
		}

		private void Refresh()
		{
			if ((Object)(object)previous_button != (Object)null)
			{
				((Selectable)previous_button).interactable = (int)Settings.ai_difficulty > 0;
			}
			if ((Object)(object)next_button != (Object)null)
			{
				((Selectable)next_button).interactable = (int)Settings.ai_difficulty < 2;
			}
			LobbySettingsUI.SetText(value_label, AiWormDifficultyRules.DisplayName(Settings.ai_difficulty));
		}
	}
	public static class ObservationBuilder
	{
		public const int SCHEMA_VERSION = 1;

		public const float WORLD_CLAMP = 255f;

		private const int N_PARDNERS = 4;

		private const int N_OBJECTIVES = 4;

		private const int N_ABILITIES = 4;

		private const int ROCK_K = 4;

		public const int OBS_SIZE = 93;

		public static float[] Build(WormMovement worm)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			List<float> list = new List<float>(93);
			Transform transform = ((Component)worm).transform;
			Vector3 val = Vector3.zero;
			Rigidbody component = ((Component)worm).GetComponent<Rigidbody>();
			if ((Object)(object)component != (Object)null)
			{
				val = component.velocity;
			}
			Vector3 forward = transform.forward;
			float num = Mathf.Atan2(forward.z, forward.x);
			list.Add(0f);
			AddOneHot(list, 0, 5);
			list.Add(val.x / 100f);
			list.Add(val.z / 100f);
			list.Add(Mathf.Sin(num));
			list.Add(Mathf.Cos(num));
			list.Add(1f);
			list.Add(1f);
			list.Add(1f);
			list.Add(0f);
			list.Add(0f);
			list.Add(0f);
			for (int i = 0; i < 4; i++)
			{
				list.Add(1f);
				list.Add(1f);
			}
			List<Transform> list2 = NearestPardners(transform.position, 4);
			for (int j = 0; j < 4; j++)
			{
				if (j < list2.Count)
				{
					Vector3 val2 = (list2[j].position - transform.position) / 255f;
					list.Add(val2.x);
					list.Add(val2.z);
					list.Add(0f);
					list.Add(0f);
					list.Add(1f);
					list.Add(0f);
					list.Add(val2.x);
					list.Add(val2.z);
					list.Add(1f);
				}
				else
				{
					list.Add(0f);
					list.Add(0f);
					list.Add(0f);
					list.Add(0f);
					list.Add(0f);
					list.Add(1f);
					list.Add(0f);
					list.Add(0f);
					list.Add(0f);
				}
			}
			for (int k = 0; k < 4; k++)
			{
				list.Add(0f);
				list.Add(0f);
				list.Add(0f);
				list.Add(0f);
				list.Add(0f);
			}
			list.Add(0f);
			list.Add(0f);
			list.Add(0f);
			list.Add(0f);
			list.Add(1f);
			for (int l = 0; l < 4; l++)
			{
				list.Add(0f);
				list.Add(0f);
			}
			if (list.Count != 93)
			{
				Plugin.log.LogError((object)$"obs size {list.Count} != {93} - schema mismatch!");
			}
			return list.ToArray();
		}

		private static List<Transform> NearestPardners(Vector3 from, int k)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			List<(float, Transform)> list = new List<(float, Transform)>();
			Player[] array = Object.FindObjectsOfType<Player>();
			foreach (Player val in array)
			{
				bool flag;
				try
				{
					flag = Traverse.Create((object)val).Field("isAlive").GetValue<bool>();
				}
				catch
				{
					flag = true;
				}
				if (flag)
				{
					Vector3 val2 = ((Component)val).transform.position - from;
					list.Add((((Vector3)(ref val2)).sqrMagnitude, ((Component)val).transform));
				}
			}
			list.Sort(((float d, Transform t) a, (float d, Transform t) b) => a.d.CompareTo(b.d));
			List<Transform> list2 = new List<Transform>();
			for (int num = 0; num < k && num < list.Count; num++)
			{
				list2.Add(list[num].Item2);
			}
			return list2;
		}

		private static void AddOneHot(List<float> o, int idx, int n)
		{
			for (int i = 0; i < n; i++)
			{
				o.Add((i == idx) ? 1f : 0f);
			}
		}
	}
	public struct WormAction
	{
		public float move_x;

		public float move_y;

		public bool dive;

		public bool burrow;

		public bool brakes;

		public bool[] abilities;
	}
	public class OnnxWormPolicy
	{
		public bool ready;

		private InferenceSession session;

		private readonly int obs_dim;

		private readonly int n_buttons;

		public OnnxWormPolicy(string model_path, int obs_dim = 93, int n_buttons = 7)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			this.obs_dim = obs_dim;
			this.n_buttons = n_buttons;
			try
			{
				session = new InferenceSession(model_path);
				ready = true;
			}
			catch (Exception ex)
			{
				Plugin.log.LogWarning((object)("onnx load failed: " + ex.Message));
				ready = false;
			}
		}

		public WormAction Act(float[] obs)
		{
			DenseTensor<float> val = new DenseTensor<float>((Memory<float>)obs, (ReadOnlySpan<int>)new int[2] { 1, obs_dim }, false);
			List<NamedOnnxValue> list = new List<NamedOnnxValue> { NamedOnnxValue.CreateFromTensor<float>("obs", (Tensor<float>)(object)val) };
			IDisposableReadOnlyCollection<DisposableNamedOnnxValue> val2 = session.Run((IReadOnlyCollection<NamedOnnxValue>)list);
			try
			{
				float[] array = null;
				float[] array2 = null;
				foreach (DisposableNamedOnnxValue item in (IEnumerable<DisposableNamedOnnxValue>)val2)
				{
					if (((NamedOnnxValue)item).Name == "move")
					{
						array = ((IEnumerable<float>)((NamedOnnxValue)item).AsTensor<float>()).ToArray();
					}
					else if (((NamedOnnxValue)item).Name == "button_probs")
					{
						array2 = ((IEnumerable<float>)((NamedOnnxValue)item).AsTensor<float>()).ToArray();
					}
				}
				bool[] array3 = new bool[n_buttons - 3];
				for (int i = 0; i < array3.Length; i++)
				{
					array3[i] = array2[3 + i] > 0.5f;
				}
				return new WormAction
				{
					move_x = array[0],
					move_y = array[1],
					dive = (array2[0] > 0.5f),
					burrow = (array2[1] > 0.5f),
					brakes = (array2[2] > 0.5f),
					abilities = array3
				};
			}
			finally
			{
				((IDisposable)val2)?.Dispose();
			}
		}
	}
	[BepInPlugin("com.wormtown.ai", "WormtownAI", "0.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string GUID = "com.wormtown.ai";

		public const string NAME = "WormtownAI";

		public const string VERSION = "0.1.0";

		public static Plugin instance;

		public static ManualLogSource log;

		public static OnnxWormPolicy policy;

		private static string plugin_directory;

		private static bool policy_load_attempted;

		private ConfigEntry<bool> ai_enabled_config;

		private ConfigEntry<AiWormDifficulty> ai_difficulty_config;

		[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
		private static extern bool SetDllDirectory(string path);

		private void Awake()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			instance = this;
			log = ((BaseUnityPlugin)this).Logger;
			plugin_directory = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			BindConfig();
			Harmony val =