Decompiled source of Map Loader v1.0.5

mapMaker/MapMaker.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.IO.Pipes;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Logging;
using BoplFixedMath;
using Entwined;
using HarmonyLib;
using MapMaker;
using MapMaker.Lua_stuff;
using Microsoft.CodeAnalysis;
using MiniJSON;
using Mono.Cecil.Cil;
using MoonSharp.Interpreter;
using MoonSharp.Interpreter.CoreLib;
using MoonSharp.Interpreter.DataStructs;
using MoonSharp.Interpreter.Debugging;
using MoonSharp.Interpreter.Execution.VM;
using MoonSharp.Interpreter.Tree.Expressions;
using MoonSharp.VsCodeDebugger;
using PlatformApi;
using Steamworks;
using Steamworks.Data;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("UnityEngine")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("MapMaker")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("My first plugin")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+eea93333dcd1d1a70b564c69651e624aab46f667")]
[assembly: AssemblyProduct("MapMaker")]
[assembly: AssemblyTitle("MapMaker")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public class IMG2Sprite : MonoBehaviour
{
	private static IMG2Sprite _instance;

	public static IMG2Sprite instance
	{
		get
		{
			if ((Object)(object)_instance == (Object)null)
			{
				_instance = Object.FindObjectOfType<IMG2Sprite>();
			}
			return _instance;
		}
	}

	public static Sprite LoadNewSprite(byte[] FileData, float PixelsPerUnit = 100f)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		//IL_007e: 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_0092: Unknown result type (might be due to invalid IL or missing references)
		Sprite val = new Sprite();
		Texture2D val2 = LoadTexture(FileData);
		Rect val3 = default(Rect);
		((Rect)(ref val3))..ctor(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height);
		float num = (float)((Texture)val2).width / 2f / (float)((Texture)val2).width;
		float num2 = (float)((Texture)val2).height / 2f / (float)((Texture)val2).height;
		Vector2 val4 = default(Vector2);
		((Vector2)(ref val4))..ctor(num, num2);
		float num3 = Mathf.Max((float)((Texture)val2).width, (float)((Texture)val2).height);
		Debug.Log((object)$"vector is {val4}");
		return Sprite.Create(val2, val3, val4, PixelsPerUnit);
	}

	public static Texture2D LoadTexture(byte[] FileData)
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: Expected O, but got Unknown
		Texture2D val = new Texture2D(2, 2);
		if (ImageConversion.LoadImage(val, FileData))
		{
			return val;
		}
		return null;
	}
}
public class Graph
{
	private int V;

	private Dictionary<int, List<GraphNode>> adj;

	private Dictionary<int, List<GraphNode>> backwordsConnectsons;

	private Dictionary<int, bool> visited = new Dictionary<int, bool>();

	private List<LogicGate> gates = new List<LogicGate>();

	private List<GraphNode> triggers = new List<GraphNode>();

	private List<GraphNode> AllNodes = new List<GraphNode>();

	public Graph(int V)
	{
		this.V = V;
		adj = new Dictionary<int, List<GraphNode>>();
		backwordsConnectsons = new Dictionary<int, List<GraphNode>>();
		for (int i = 0; i < V; i++)
		{
			adj.Add(i, new List<GraphNode>());
		}
		for (int j = 0; j < V; j++)
		{
			backwordsConnectsons.Add(j, new List<GraphNode>());
		}
	}

	private bool isCyclicUtil(int i, bool[] visited, bool[] recStack)
	{
		if (recStack[i])
		{
			return true;
		}
		if (visited[i])
		{
			return false;
		}
		visited[i] = true;
		recStack[i] = true;
		List<GraphNode> list = adj[i];
		foreach (GraphNode item in list)
		{
			if (isCyclicUtil(item.id, visited, recStack))
			{
				return true;
			}
		}
		recStack[i] = false;
		return false;
	}

	public int NumberOfInputsToNode(int node)
	{
		return adj[node].Count;
	}

	public void addEdge(int sou, int dest, GameObject destOwner, LogicGate destGate, GameObject souOwner, LogicGate souGate)
	{
		GraphNode item = new GraphNode
		{
			id = dest,
			Owner = destOwner,
			Gate = destGate
		};
		adj[sou].Add(item);
		AllNodes.Add(item);
		GraphNode item2 = new GraphNode
		{
			id = sou,
			Owner = souOwner,
			Gate = souGate
		};
		backwordsConnectsons[dest].Add(item2);
		if ((Object)(object)souGate == (Object)null)
		{
			triggers.Add(item2);
		}
		AllNodes.Add(item2);
	}

	public bool isCyclic()
	{
		bool[] array = new bool[V];
		bool[] recStack = new bool[V];
		for (int i = 0; i < V; i++)
		{
			if (isCyclicUtil(i, array, recStack))
			{
				return true;
			}
		}
		return false;
	}

	private void ForwordProbagate(GraphNode node)
	{
		foreach (GraphNode item in adj[node.id])
		{
			if (visited.ContainsKey(item.id) && visited[item.id])
			{
				break;
			}
			foreach (GraphNode item2 in backwordsConnectsons[item.id])
			{
				if (!visited.ContainsKey(item2.id) || !visited[item2.id])
				{
					BackPropagate(item2);
				}
			}
			if ((Object)(object)item.Gate != (Object)null)
			{
				gates.Add(item.Gate);
			}
			visited.Add(item.id, value: true);
			ForwordProbagate(item);
		}
	}

	private void BackPropagate(GraphNode node)
	{
		foreach (GraphNode item in backwordsConnectsons[node.id])
		{
			if (!visited.ContainsKey(item.id) || !visited[item.id])
			{
				BackPropagate(item);
				continue;
			}
			throw new Exception("WE FOUND A GATE THAT WAS ALREADY VISITED IN BACKPROPAGATE WHEN IT SHOULDNT HAVE BEEN!!! IUAOGAGUBFHJAUEF PLS SEND YOUR MAP FILE SO I CAN FIX THIS!");
		}
		if ((Object)(object)node.Gate != (Object)null)
		{
			gates.Add(node.Gate);
		}
		visited.Add(node.id, value: true);
	}

	public List<LogicGate> BuildListOfGates()
	{
		visited = new Dictionary<int, bool>();
		gates = new List<LogicGate>();
		foreach (GraphNode trigger in triggers)
		{
			ForwordProbagate(trigger);
		}
		foreach (GraphNode allNode in AllNodes)
		{
			if (!visited.ContainsKey(allNode.id) || !visited[allNode.id])
			{
				ForwordProbagate(allNode);
			}
		}
		return gates;
	}
}
public class GraphNode
{
	public int id;

	public GameObject Owner;

	public LogicGate Gate;
}
public class ShootBlink : MonoBehaviour
{
	private Fix maxDistance = (Fix)100L;

	public static LayerMask collisionMask;

	public static float raycastEffectSpacing;

	public static GameObject WaterExplosion;

	public static GameObject WaterRing;

	public static GameObject RayCastEffect;

	public static QuantumTunnel QuantumTunnelPrefab;

	public static ParticleSystem RaycastParticlePrefab;

	public static ParticleSystem RaycastParticleHitPrefab;

	public Fix minPlayerDuration = (Fix)0.5;

	public Fix WallDuration = (Fix)3L;

	public Fix WallDelay = (Fix)1f;

	public Fix WallShake = (Fix)1f;

	public static Material onHitWallMaterail;

	public static Material onHitResizableWallMaterail;

	public static Material onDissapearResizableWallMaterail;

	public static Material onHitBlackHoleMaterial;

	private ParticleSystem rayParticle;

	private ParticleSystem hitParticle;

	private ParticleSystem rayParticle2;

	private float rayDensity;

	private void Awake()
	{
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: 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_0064: Unknown result type (might be due to invalid IL or missing references)
		rayParticle = Object.Instantiate<ParticleSystem>(RaycastParticlePrefab);
		hitParticle = Object.Instantiate<ParticleSystem>(RaycastParticleHitPrefab);
		rayParticle2 = Object.Instantiate<ParticleSystem>(RaycastParticlePrefab);
		EmissionModule emission = rayParticle.emission;
		Burst burst = ((EmissionModule)(ref emission)).GetBurst(0);
		MinMaxCurve count = ((Burst)(ref burst)).count;
		float constant = ((MinMaxCurve)(ref count)).constant;
		ShapeModule shape = rayParticle.shape;
		rayDensity = constant / ((ShapeModule)(ref shape)).scale.x;
	}

	public void Shoot(Vec2 firepointFIX, Vec2 directionFIX, ref bool hasFired, bool alreadyHitWater = false)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: 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_0065: 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_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: 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_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0174: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0164: Unknown result type (might be due to invalid IL or missing references)
		//IL_0698: Unknown result type (might be due to invalid IL or missing references)
		//IL_0699: Unknown result type (might be due to invalid IL or missing references)
		//IL_069e: Unknown result type (might be due to invalid IL or missing references)
		//IL_069f: Unknown result type (might be due to invalid IL or missing references)
		//IL_06a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_06b1: 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_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0190: Unknown result type (might be due to invalid IL or missing references)
		//IL_0195: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: 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_01a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0200: Unknown result type (might be due to invalid IL or missing references)
		//IL_0201: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_020c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0211: Unknown result type (might be due to invalid IL or missing references)
		//IL_0216: Unknown result type (might be due to invalid IL or missing references)
		//IL_0221: Unknown result type (might be due to invalid IL or missing references)
		//IL_0222: Unknown result type (might be due to invalid IL or missing references)
		//IL_0227: Unknown result type (might be due to invalid IL or missing references)
		//IL_0230: Unknown result type (might be due to invalid IL or missing references)
		//IL_0231: Unknown result type (might be due to invalid IL or missing references)
		//IL_0236: Unknown result type (might be due to invalid IL or missing references)
		//IL_023b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0240: Unknown result type (might be due to invalid IL or missing references)
		//IL_0242: Unknown result type (might be due to invalid IL or missing references)
		//IL_0247: Unknown result type (might be due to invalid IL or missing references)
		//IL_024c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0251: Unknown result type (might be due to invalid IL or missing references)
		//IL_0256: Unknown result type (might be due to invalid IL or missing references)
		//IL_028e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0298: Unknown result type (might be due to invalid IL or missing references)
		//IL_0299: Unknown result type (might be due to invalid IL or missing references)
		//IL_029e: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_037c: Unknown result type (might be due to invalid IL or missing references)
		//IL_037d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0310: Unknown result type (might be due to invalid IL or missing references)
		//IL_0311: Unknown result type (might be due to invalid IL or missing references)
		//IL_0327: Unknown result type (might be due to invalid IL or missing references)
		//IL_0328: Unknown result type (might be due to invalid IL or missing references)
		//IL_0332: Unknown result type (might be due to invalid IL or missing references)
		//IL_033e: Unknown result type (might be due to invalid IL or missing references)
		//IL_033f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0367: Unknown result type (might be due to invalid IL or missing references)
		//IL_0671: Unknown result type (might be due to invalid IL or missing references)
		//IL_0672: Unknown result type (might be due to invalid IL or missing references)
		//IL_0677: Unknown result type (might be due to invalid IL or missing references)
		//IL_0678: Unknown result type (might be due to invalid IL or missing references)
		//IL_067d: Unknown result type (might be due to invalid IL or missing references)
		//IL_067e: Unknown result type (might be due to invalid IL or missing references)
		//IL_068a: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0406: Unknown result type (might be due to invalid IL or missing references)
		//IL_0524: Unknown result type (might be due to invalid IL or missing references)
		//IL_052a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0542: Unknown result type (might be due to invalid IL or missing references)
		//IL_0548: Unknown result type (might be due to invalid IL or missing references)
		//IL_0482: Unknown result type (might be due to invalid IL or missing references)
		//IL_049b: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_04b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_04bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_04be: Unknown result type (might be due to invalid IL or missing references)
		//IL_04d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_04d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0507: Unknown result type (might be due to invalid IL or missing references)
		//IL_050d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0661: Unknown result type (might be due to invalid IL or missing references)
		//IL_05a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_058e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0625: Unknown result type (might be due to invalid IL or missing references)
		//IL_0633: Unknown result type (might be due to invalid IL or missing references)
		//IL_0639: Unknown result type (might be due to invalid IL or missing references)
		//IL_063e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0643: Unknown result type (might be due to invalid IL or missing references)
		//IL_0648: Unknown result type (might be due to invalid IL or missing references)
		//IL_064e: Unknown result type (might be due to invalid IL or missing references)
		Plugin.CurrentlyBlinking = true;
		Vec2 val = directionFIX;
		AudioManager.Get().Play("laserShoot");
		Debug.DrawRay(Vector2.op_Implicit((Vector2)firepointFIX), Vector2.op_Implicit((float)maxDistance * (Vector2)val), new Color(255f, 255f, 0f));
		RaycastInformation val2 = DetPhysics.Get().PointCheckAllRoundedRects(firepointFIX);
		if (!RaycastInformation.op_Implicit(val2))
		{
			val2 = DetPhysics.Get().RaycastToClosest(firepointFIX, val, maxDistance, collisionMask);
		}
		if (!RaycastInformation.op_Implicit(val2) && firepointFIX.y <= SceneBounds.WaterHeight && !alreadyHitWater)
		{
			spawnRayCastEffect(Vector2.op_Implicit((Vector3)firepointFIX), Vector2.op_Implicit((Vector3)val), (float)val2.nearDist, didHit: false, Vec2.up, reflected: true);
			rayParticle.Stop();
			GameObject val3 = Object.Instantiate<GameObject>(WaterRing);
			AudioManager.Get().Play("waterExplosion");
			val3.transform.position = new Vector3(WaterRing.transform.position.x + (float)val2.nearPos.x, WaterRing.transform.position.y, WaterRing.transform.position.z);
			return;
		}
		if (RaycastInformation.op_Implicit(val2))
		{
			Vec2 normal = Vec2.NormalizedSafe(PhysTools.NormalAtPoint(val2.pp.monobehaviourCollider, val2.nearPos));
			if (val2.layer == LayerMask.NameToLayer("Water") && !alreadyHitWater)
			{
				spawnRayCastEffect(Vector2.op_Implicit((Vector3)firepointFIX), Vector2.op_Implicit((Vector3)val), (float)val2.nearDist, didHit: false, normal, reflected: true);
				rayParticle.Stop();
				((Vec2)(ref val))..ctor(val.x, val.y * -Fix.One);
				Shoot(val2.nearPos, val, ref hasFired, alreadyHitWater: true);
				Debug.DrawRay(Vector2.op_Implicit((Vector2)val2.nearPos), Vector2.op_Implicit((Vector2)(val * maxDistance)), Color.magenta);
				GameObject val4 = Object.Instantiate<GameObject>(WaterRing);
				AudioManager.Get().Play("waterExplosion");
				val4.transform.position = new Vector3(WaterRing.transform.position.x + (float)val2.nearPos.x, WaterRing.transform.position.y, WaterRing.transform.position.z);
				return;
			}
			if (val2.layer == LayerMask.NameToLayer("EffectorZone") || val2.layer == LayerMask.NameToLayer("weapon"))
			{
				GameObject gameObject = ((Component)val2.pp.fixTrans).gameObject;
				QuantumTunnel val5 = FixTransform.InstantiateFixed<QuantumTunnel>(QuantumTunnelPrefab, val2.pp.fixTrans.position);
				if (!((Component)val2.pp.fixTrans).gameObject.CompareTag("InvincibilityZone"))
				{
					val5.Init(gameObject, WallDuration, (Material)null, false);
				}
			}
			else
			{
				GameObject gameObject2 = ((Component)val2.pp.fixTrans).gameObject;
				QuantumTunnel val6 = null;
				for (int i = 0; i < ShootQuantum.spawnedQuantumTunnels.Count; i++)
				{
					if (((Object)ShootQuantum.spawnedQuantumTunnels[i].Victim).GetInstanceID() == ((Object)gameObject2).GetInstanceID())
					{
						val6 = ShootQuantum.spawnedQuantumTunnels[i];
					}
				}
				if ((Object)(object)val6 == (Object)null)
				{
					val6 = FixTransform.InstantiateFixed<QuantumTunnel>(QuantumTunnelPrefab, val2.pp.fixTrans.position);
					ShootQuantum.spawnedQuantumTunnels.Add(val6);
				}
				if (gameObject2.layer == LayerMask.NameToLayer("wall"))
				{
					ShakablePlatform component = gameObject2.GetComponent<ShakablePlatform>();
					if (gameObject2.CompareTag("ResizablePlatform"))
					{
						Material val7 = onHitResizableWallMaterail;
						gameObject2.GetComponent<SpriteRenderer>();
						DPhysicsRoundedRect component2 = gameObject2.GetComponent<DPhysicsRoundedRect>();
						val7.SetFloat("_Scale", gameObject2.transform.localScale.x);
						val7.SetFloat("_BevelRadius", (float)component2.radius);
						Vec2 val8 = component2.CalcExtents();
						val7.SetFloat("_RHeight", (float)val8.y);
						val7.SetFloat("_RWidth", (float)val8.x);
						component.AddShake(WallDelay, WallShake, 10, val7, (AnimationCurveFixed)null);
						val6.DelayedInit(gameObject2, WallDuration, WallDelay, onDissapearResizableWallMaterail);
					}
					else
					{
						component.AddShake(WallDelay, WallShake, 10, onHitWallMaterail, (AnimationCurveFixed)null);
						val6.DelayedInit(gameObject2, WallDuration, WallDelay, (Material)null);
					}
				}
				else if (gameObject2.layer == LayerMask.NameToLayer("RigidBodyAffector"))
				{
					if ((Object)(object)gameObject2.GetComponent<BlackHole>() != (Object)null)
					{
						val6.Init(gameObject2, WallDuration, onHitBlackHoleMaterial, false);
					}
					else
					{
						val6.Init(gameObject2, WallDuration, (Material)null, false);
					}
				}
				else if (gameObject2.layer == LayerMask.NameToLayer("Player"))
				{
					IPlayerIdHolder component3 = gameObject2.GetComponent<IPlayerIdHolder>();
					Player player = PlayerHandler.Get().GetPlayer(component3.GetPlayerId());
					if (player != null)
					{
						int timesHitByBlinkgunThisRound = player.timesHitByBlinkgunThisRound;
						Player val9 = player;
						int timesHitByBlinkgunThisRound2 = val9.timesHitByBlinkgunThisRound;
						val9.timesHitByBlinkgunThisRound = timesHitByBlinkgunThisRound2 + 1;
					}
					Fix val10 = Fix.Max(minPlayerDuration, (Fix)0.3 * WallDuration);
					val6.Init(gameObject2, val10, (Material)null, true);
				}
				else
				{
					val6.Init(gameObject2, WallDuration, (Material)null, false);
				}
			}
			spawnRayCastEffect((Vector2)firepointFIX, (Vector2)val, (float)val2.nearDist, didHit: true, normal);
		}
		else
		{
			spawnRayCastEffect((Vector2)firepointFIX, (Vector2)val, (float)maxDistance, didHit: false, Vec2.up);
		}
		hasFired = true;
		Plugin.CurrentlyBlinking = false;
	}

	private void spawnRayCastEffect(Vector2 start, Vector2 dir, float dist, bool didHit, Vec2 normal, bool reflected = false)
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		ParticleSystem val = (reflected ? rayParticle2 : rayParticle);
		ShapeModule shape = val.shape;
		EmissionModule emission = val.emission;
		Burst burst = ((EmissionModule)(ref emission)).GetBurst(0);
		((ShapeModule)(ref shape)).scale = new Vector3(dist, ((ShapeModule)(ref shape)).scale.y, ((ShapeModule)(ref shape)).scale.z);
		((Component)val).transform.right = Vector2.op_Implicit(dir);
		((Component)val).transform.position = Vector2.op_Implicit(start + dir * dist * 0.5f);
		((Burst)(ref burst)).count = MinMaxCurve.op_Implicit(dist * rayDensity);
		((EmissionModule)(ref emission)).SetBurst(0, burst);
		val.Play();
		if (reflected)
		{
			((Component)hitParticle).transform.position = Vector2.op_Implicit(start + dir * dist);
			((Component)hitParticle).transform.up = (Vector3)normal;
			hitParticle.Simulate(0.16f);
			hitParticle.Play();
		}
		if (didHit)
		{
			hitParticle.Stop();
			((Component)hitParticle).transform.position = Vector2.op_Implicit(start + dir * dist);
			((Component)hitParticle).transform.up = (Vector3)normal;
			hitParticle.Play();
		}
	}
}
namespace MiniJSON
{
	public static class Json
	{
		private sealed class Parser : IDisposable
		{
			private enum TOKEN
			{
				NONE,
				CURLY_OPEN,
				CURLY_CLOSE,
				SQUARED_OPEN,
				SQUARED_CLOSE,
				COLON,
				COMMA,
				STRING,
				NUMBER,
				TRUE,
				FALSE,
				NULL
			}

			private const string WORD_BREAK = "{}[],:\"";

			private const string HEX_DIGIT = "0123456789ABCDEFabcdef";

			private StringReader json;

			private char PeekChar => Convert.ToChar(json.Peek());

			private char NextChar => Convert.ToChar(json.Read());

			private string NextWord
			{
				get
				{
					StringBuilder stringBuilder = new StringBuilder();
					while (!IsWordBreak(PeekChar))
					{
						stringBuilder.Append(NextChar);
						if (json.Peek() == -1)
						{
							break;
						}
					}
					return stringBuilder.ToString();
				}
			}

			private TOKEN NextToken
			{
				get
				{
					EatWhitespace();
					if (json.Peek() == -1)
					{
						return TOKEN.NONE;
					}
					switch (PeekChar)
					{
					case '{':
						return TOKEN.CURLY_OPEN;
					case '}':
						json.Read();
						return TOKEN.CURLY_CLOSE;
					case '[':
						return TOKEN.SQUARED_OPEN;
					case ']':
						json.Read();
						return TOKEN.SQUARED_CLOSE;
					case ',':
						json.Read();
						return TOKEN.COMMA;
					case '"':
						return TOKEN.STRING;
					case ':':
						return TOKEN.COLON;
					case '-':
					case '0':
					case '1':
					case '2':
					case '3':
					case '4':
					case '5':
					case '6':
					case '7':
					case '8':
					case '9':
						return TOKEN.NUMBER;
					default:
						return NextWord switch
						{
							"false" => TOKEN.FALSE, 
							"true" => TOKEN.TRUE, 
							"null" => TOKEN.NULL, 
							_ => TOKEN.NONE, 
						};
					}
				}
			}

			public static bool IsWordBreak(char c)
			{
				return char.IsWhiteSpace(c) || "{}[],:\"".IndexOf(c) != -1;
			}

			public static bool IsHexDigit(char c)
			{
				return "0123456789ABCDEFabcdef".IndexOf(c) != -1;
			}

			private Parser(string jsonString)
			{
				json = new StringReader(jsonString);
			}

			public static object Parse(string jsonString)
			{
				using Parser parser = new Parser(jsonString);
				return parser.ParseValue();
			}

			public void Dispose()
			{
				json.Dispose();
				json = null;
			}

			private Dictionary<string, object> ParseObject()
			{
				Dictionary<string, object> dictionary = new Dictionary<string, object>();
				json.Read();
				while (true)
				{
					string text;
					object obj;
					switch (NextToken)
					{
					case TOKEN.NONE:
						return null;
					case TOKEN.CURLY_CLOSE:
						return dictionary;
					case TOKEN.STRING:
					{
						text = ParseString();
						if (text == null)
						{
							return null;
						}
						if (NextToken != TOKEN.COLON)
						{
							return null;
						}
						json.Read();
						TOKEN nextToken = NextToken;
						obj = ParseByToken(nextToken);
						if (obj == null && nextToken != TOKEN.NULL)
						{
							return null;
						}
						goto IL_00ba;
					}
					default:
						return null;
					case TOKEN.COMMA:
						break;
					}
					continue;
					IL_00ba:
					dictionary[text] = obj;
				}
			}

			private List<object> ParseArray()
			{
				List<object> list = new List<object>();
				json.Read();
				bool flag = true;
				while (flag)
				{
					TOKEN nextToken = NextToken;
					switch (nextToken)
					{
					case TOKEN.NONE:
						return null;
					case TOKEN.SQUARED_CLOSE:
						flag = false;
						continue;
					case TOKEN.COMMA:
						continue;
					}
					object obj = ParseByToken(nextToken);
					if (obj == null && nextToken != TOKEN.NULL)
					{
						return null;
					}
					list.Add(obj);
				}
				return list;
			}

			private object ParseValue()
			{
				TOKEN nextToken = NextToken;
				return ParseByToken(nextToken);
			}

			private object ParseByToken(TOKEN token)
			{
				return token switch
				{
					TOKEN.STRING => ParseString(), 
					TOKEN.NUMBER => ParseNumber(), 
					TOKEN.CURLY_OPEN => ParseObject(), 
					TOKEN.SQUARED_OPEN => ParseArray(), 
					TOKEN.TRUE => true, 
					TOKEN.FALSE => false, 
					TOKEN.NULL => null, 
					_ => null, 
				};
			}

			private string ParseString()
			{
				StringBuilder stringBuilder = new StringBuilder();
				json.Read();
				bool flag = true;
				while (flag)
				{
					if (json.Peek() == -1)
					{
						flag = false;
						break;
					}
					char nextChar = NextChar;
					switch (nextChar)
					{
					case '"':
						flag = false;
						break;
					case '\\':
						if (json.Peek() == -1)
						{
							flag = false;
							break;
						}
						nextChar = NextChar;
						switch (nextChar)
						{
						case '"':
						case '/':
						case '\\':
							stringBuilder.Append(nextChar);
							break;
						case 'b':
							stringBuilder.Append('\b');
							break;
						case 'f':
							stringBuilder.Append('\f');
							break;
						case 'n':
							stringBuilder.Append('\n');
							break;
						case 'r':
							stringBuilder.Append('\r');
							break;
						case 't':
							stringBuilder.Append('\t');
							break;
						case 'u':
						{
							char[] array = new char[4];
							for (int i = 0; i < 4; i++)
							{
								array[i] = NextChar;
								if (!IsHexDigit(array[i]))
								{
									return null;
								}
							}
							stringBuilder.Append((char)Convert.ToInt32(new string(array), 16));
							break;
						}
						}
						break;
					default:
						stringBuilder.Append(nextChar);
						break;
					}
				}
				return stringBuilder.ToString();
			}

			private object ParseNumber()
			{
				string nextWord = NextWord;
				if (nextWord.IndexOf('.') == -1 && nextWord.IndexOf('E') == -1 && nextWord.IndexOf('e') == -1)
				{
					long.TryParse(nextWord, NumberStyles.Any, CultureInfo.InvariantCulture, out var result);
					return result;
				}
				double.TryParse(nextWord, NumberStyles.Any, CultureInfo.InvariantCulture, out var result2);
				return result2;
			}

			private void EatWhitespace()
			{
				while (char.IsWhiteSpace(PeekChar))
				{
					json.Read();
					if (json.Peek() == -1)
					{
						break;
					}
				}
			}
		}

		private sealed class Serializer
		{
			private StringBuilder builder;

			private Serializer()
			{
				builder = new StringBuilder();
			}

			public static string Serialize(object obj)
			{
				Serializer serializer = new Serializer();
				serializer.SerializeValue(obj);
				return serializer.builder.ToString();
			}

			private void SerializeValue(object value)
			{
				if (value == null)
				{
					builder.Append("null");
				}
				else if (value is string str)
				{
					SerializeString(str);
				}
				else if (value is bool)
				{
					builder.Append(((bool)value) ? "true" : "false");
				}
				else if (value is IList anArray)
				{
					SerializeArray(anArray);
				}
				else if (value is IDictionary obj)
				{
					SerializeObject(obj);
				}
				else if (value is char)
				{
					SerializeString(new string((char)value, 1));
				}
				else
				{
					SerializeOther(value);
				}
			}

			private void SerializeObject(IDictionary obj)
			{
				bool flag = true;
				builder.Append('{');
				foreach (object key in obj.Keys)
				{
					if (!flag)
					{
						builder.Append(',');
					}
					SerializeString(key.ToString());
					builder.Append(':');
					SerializeValue(obj[key]);
					flag = false;
				}
				builder.Append('}');
			}

			private void SerializeArray(IList anArray)
			{
				builder.Append('[');
				bool flag = true;
				for (int i = 0; i < anArray.Count; i++)
				{
					object value = anArray[i];
					if (!flag)
					{
						builder.Append(',');
					}
					SerializeValue(value);
					flag = false;
				}
				builder.Append(']');
			}

			private void SerializeString(string str)
			{
				builder.Append('"');
				char[] array = str.ToCharArray();
				foreach (char c in array)
				{
					switch (c)
					{
					case '"':
						builder.Append("\\\"");
						continue;
					case '\\':
						builder.Append("\\\\");
						continue;
					case '\b':
						builder.Append("\\b");
						continue;
					case '\f':
						builder.Append("\\f");
						continue;
					case '\n':
						builder.Append("\\n");
						continue;
					case '\r':
						builder.Append("\\r");
						continue;
					case '\t':
						builder.Append("\\t");
						continue;
					}
					int num = Convert.ToInt32(c);
					if (num >= 32 && num <= 126)
					{
						builder.Append(c);
						continue;
					}
					builder.Append("\\u");
					builder.Append(num.ToString("x4"));
				}
				builder.Append('"');
			}

			private void SerializeOther(object value)
			{
				if (value is float)
				{
					builder.Append(((float)value).ToString("R", CultureInfo.InvariantCulture));
				}
				else if (value is int || value is uint || value is long || value is sbyte || value is byte || value is short || value is ushort || value is ulong)
				{
					builder.Append(value);
				}
				else if (value is double || value is decimal)
				{
					builder.Append(Convert.ToDouble(value).ToString("R", CultureInfo.InvariantCulture));
				}
				else
				{
					SerializeString(value.ToString());
				}
			}
		}

		public static object Deserialize(string json)
		{
			if (json == null)
			{
				return null;
			}
			return Parser.Parse(json);
		}

		public static string Serialize(object obj)
		{
			return Serializer.Serialize(obj);
		}
	}
}
namespace MapMaker
{
	public class Debugging
	{
		public static void Awake()
		{
			//IL_0385: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Expected O, but got Unknown
			Type[] types = typeof(Beam).Assembly.GetTypes();
			List<Type> list = new List<Type>();
			list.AddRange(types);
			list.Remove(typeof(FixTransform));
			types = list.ToArray();
			types = Array.FindAll(types, IsAllowed);
			list = types.ToList();
			list.Remove(typeof(Circle));
			list.Remove(typeof(Box));
			list.Remove(typeof(RoundedRect));
			Type[] array = new Type[35]
			{
				typeof(Beam),
				typeof(BeamObject),
				typeof(BlackHoleClap),
				typeof(BoplBody),
				typeof(BowTransform),
				typeof(CastSpell),
				typeof(ControlPlatform),
				typeof(Dash),
				typeof(DestroyIfOutsideSceneBounds),
				typeof(DetPhysics),
				typeof(DPhysicsBox),
				typeof(DPhysicsCircle),
				typeof(DPhysicsRoundedRect),
				typeof(Drill),
				typeof(DuplicatePlatformEffect),
				typeof(GameSessionHandler),
				typeof(Gravity),
				typeof(GunTransform),
				typeof(HookshotInstant),
				typeof(InstantAbility),
				typeof(MeteorSmash),
				typeof(PlaceRocketEngine),
				typeof(PlaceSparkNode),
				typeof(PlatformTransform),
				typeof(PlayerBody),
				typeof(QuantumTunnel),
				typeof(ReviveParticle),
				typeof(Rope),
				typeof(RopeAttachment),
				typeof(Shake),
				typeof(SimpleSparkNode),
				typeof(TeleportedObjectEffect),
				typeof(TeleportIndicator),
				typeof(Updater),
				typeof(vibrate)
			};
			foreach (Type item in list)
			{
				if (item.FullName.Contains("<PrivateImplementationDetails>") || item.FullName.Contains("+"))
				{
					continue;
				}
				Plugin.logger.LogInfo((object)("Patching " + item.FullName));
				MethodInfo[] methods = item.GetMethods();
				MethodInfo[] array2 = methods;
				foreach (MethodInfo methodInfo in array2)
				{
					if (!(methodInfo.DeclaringType != item) && MethodBaseExtensions.HasMethodBody((MethodBase)methodInfo) && !methodInfo.IsDefined(typeof(AsyncStateMachineAttribute), inherit: false) && !methodInfo.IsDefined(typeof(IteratorStateMachineAttribute), inherit: false))
					{
						try
						{
							Plugin.harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(DebbugingTranspiler), "FieldTranspiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
						}
						catch (Exception ex)
						{
							Plugin.logger.LogWarning((object)("Failed to patch " + item.FullName + "::" + methodInfo.Name + ": " + ex));
						}
					}
				}
			}
		}

		public static bool IsAllowed(Type type)
		{
			return !type.IsGenericType && !type.IsDefined(typeof(CompilerGeneratedAttribute), inherit: false) && !type.FullName.Contains("<PrivateImplementationDetails>") && !type.FullName.Contains("+");
		}

		public static void LogDif(List<Type> list, List<Type> list2)
		{
			foreach (Type item in list)
			{
				if (!list2.Contains(item))
				{
					Debug.Log((object)$"type is difrent: {item}");
				}
			}
		}
	}
	public static class DebbugingTranspiler
	{
		private static FieldInfo f_Pos_Field = AccessTools.Field(typeof(FixTransform), "position");

		private static FieldInfo f_ExternalVel_Field = AccessTools.Field(typeof(PlayerBody), "externalVelocity");

		private static FieldInfo f_selfImposedVel_Field = AccessTools.Field(typeof(PlayerBody), "selfImposedVelocity");

		private static MethodInfo m_LoggingPosFunc = AccessTools.Method(typeof(DebbugingTranspiler), "LoggingPos", (Type[])null, (Type[])null);

		private static MethodInfo m_LoggingExternalVelFunc = AccessTools.Method(typeof(DebbugingTranspiler), "LoggingExternalVel", (Type[])null, (Type[])null);

		private static MethodInfo m_LoggingselfImposedVelocityFunc = AccessTools.Method(typeof(DebbugingTranspiler), "LoggingselfImposedVelocity", (Type[])null, (Type[])null);

		public static IEnumerable<CodeInstruction> FieldTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			new List<CodeInstruction>(instructions);
			foreach (CodeInstruction instruction in instructions)
			{
				if (CodeInstructionExtensions.StoresField(instruction, f_Pos_Field))
				{
					yield return new CodeInstruction(OpCodes.Dup, (object)null);
					yield return new CodeInstruction(OpCodes.Ldarg_0, (object)null);
					yield return new CodeInstruction(OpCodes.Call, (object)m_LoggingPosFunc);
				}
				yield return instruction;
			}
		}

		public static void LoggingPos(Vec2 newPos, Component component)
		{
			//IL_0027: 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)
			GameObject gameObject = component.gameObject;
			if (((Object)gameObject).name == "Player(Clone)")
			{
				Debug.Log((object)$"{StackTraceUtility.ExtractStackTrace()} is changing player pos, new value: {newPos}, at time: {Updater.SimTimeSinceLevelLoaded}");
			}
		}

		public static void LoggingExternalVel(Vec2 newExternalVel, Component component)
		{
			//IL_0027: 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)
			GameObject gameObject = component.gameObject;
			if (((Object)gameObject).name == "Player(Clone)")
			{
				Debug.Log((object)$"{StackTraceUtility.ExtractStackTrace()} is changing player externalVelocity, new value: {newExternalVel}, at time: {Updater.SimTimeSinceLevelLoaded}");
			}
		}

		public static void LoggingselfImposedVelocity(Vec2 newselfImposedVelocity, Component component)
		{
			//IL_0027: 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)
			GameObject gameObject = component.gameObject;
			if (((Object)gameObject).name == "Player(Clone)")
			{
				Debug.Log((object)$"{StackTraceUtility.ExtractStackTrace()} is changing player selfImposedVelocity, new value: {newselfImposedVelocity}, at time: {Updater.SimTimeSinceLevelLoaded}");
			}
		}
	}
	public class AndGate : LogicGate
	{
		public void Register()
		{
			SignalSystem.RegisterLogicGate(this);
			UUID = Plugin.NextUUID;
			Plugin.NextUUID++;
		}

		public override void Logic(Fix SimDeltaTime)
		{
			LogicOutput logicOutput = OutputSignals[0];
			if (InputSignals.Count == 1)
			{
				logicOutput.WasOnLastTick = logicOutput.IsOn;
				logicOutput.IsOn = InputSignals[0].IsOn;
				return;
			}
			bool flag = true;
			for (int i = 0; i < InputSignals.Count; i++)
			{
				flag = InputSignals[i].IsOn && flag;
			}
			logicOutput.WasOnLastTick = logicOutput.IsOn;
			logicOutput.IsOn = flag;
		}
	}
	public class DisappearPlatformsOnSignal : LogicGate
	{
		public static List<DisappearPlatformsOnSignal> DisappearPlatformsOnSignals = new List<DisappearPlatformsOnSignal>();

		public GameObject platform = null;

		public bool SignalIsInverse = false;

		public Fix SecondsToReapper = Fix.One;

		public Fix delay = Fix.One;

		public static Material onHitResizableWallMaterail;

		public static Material onHitWallMaterail;

		public static QuantumTunnel QuantumTunnelPrefab;

		public QuantumTunnel currentTunnel = null;

		public Fix TimeDelayed;

		private Fix age;

		private bool delaying = false;

		private Material originalMaterial;

		private bool update1 = true;

		private bool ShouldBeActive = true;

		public void Register()
		{
			UUID = Plugin.NextUUID;
			Plugin.NextUUID++;
			DisappearPlatformsOnSignals.Add(this);
			SignalSystem.RegisterLogicGate(this);
			SignalSystem.RegisterGateThatAlwaysRuns(this);
			SignalSystem.RegisterInputThatUpdatesConnectson(InputSignals[0]);
		}

		public bool IsOn()
		{
			return InputSignals[0].IsOn;
		}

		public override void Logic(Fix SimDeltaTime)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: 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_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).GetComponent<FixTransform>().position = platform.GetComponent<FixTransform>().position;
			if (((Object)((Component)this).gameObject).name == "DisappearPlatformsObject" || !((Object)(object)platform != (Object)null))
			{
				return;
			}
			if (update1)
			{
				originalMaterial = ((Renderer)platform.GetComponent<SpriteRenderer>()).material;
				update1 = false;
			}
			QuantumTunnel val = null;
			for (int i = 0; i < ShootQuantum.spawnedQuantumTunnels.Count; i++)
			{
				if (((Object)ShootQuantum.spawnedQuantumTunnels[i].Victim).GetInstanceID() == ((Object)platform).GetInstanceID())
				{
					val = ShootQuantum.spawnedQuantumTunnels[i];
				}
			}
			bool flag = (IsOn() && !SignalIsInverse) || (!IsOn() && SignalIsInverse);
			if (flag && !delaying && ShouldBeActive)
			{
				delaying = true;
			}
			if (age - delay > SecondsToReapper && !Object.op_Implicit((Object)(object)val))
			{
				ShouldBeActive = true;
				platform.SetActive(true);
				TimeDelayed = Fix.Zero;
				age = Fix.Zero;
				((Renderer)platform.GetComponent<SpriteRenderer>()).material = originalMaterial;
			}
			if (age > SecondsToReapper && !Object.op_Implicit((Object)(object)val))
			{
				ShouldBeActive = true;
				platform.SetActive(true);
				TimeDelayed = Fix.Zero;
				age = Fix.Zero;
				((Renderer)platform.GetComponent<SpriteRenderer>()).material = originalMaterial;
			}
			if (!flag)
			{
				age += GameTime.PlayerTimeScale * SimDeltaTime;
			}
			if (delaying)
			{
				TimeDelayed += GameTime.PlayerTimeScale * SimDeltaTime;
				age = Fix.Zero;
				if (platform.CompareTag("ResizablePlatform"))
				{
					Material val2 = onHitResizableWallMaterail;
					platform.GetComponent<SpriteRenderer>();
					DPhysicsRoundedRect component = platform.GetComponent<DPhysicsRoundedRect>();
					val2.SetFloat("_Scale", platform.transform.localScale.x);
					val2.SetFloat("_BevelRadius", (float)component.radius);
					Vec2 val3 = component.CalcExtents();
					val2.SetFloat("_RHeight", (float)val3.y);
					val2.SetFloat("_RWidth", (float)val3.x);
					((Renderer)platform.GetComponent<SpriteRenderer>()).material = val2;
				}
				else
				{
					((Renderer)platform.GetComponent<SpriteRenderer>()).material = onHitWallMaterail;
				}
			}
			if (TimeDelayed > delay && !Object.op_Implicit((Object)(object)val))
			{
				if (!Object.op_Implicit((Object)(object)platform))
				{
					Debug.Log((object)"GAME OBJECT IS NULL!");
				}
				delaying = false;
				ShouldBeActive = false;
				platform.SetActive(false);
			}
		}
	}
	public class DropPlayers : LogicGate
	{
		public bool OnlyActivateOnRise = false;

		public StickyRoundedRectangle stickyRoundedRectangle;

		public Fix DropForce = Fix.One;

		private bool WasOnLastFrame = false;

		public void Register()
		{
			UUID = Plugin.NextUUID;
			Plugin.NextUUID++;
			SignalSystem.RegisterLogicGate(this);
			SignalSystem.RegisterInputThatUpdatesConnectson(InputSignals[0]);
			SignalSystem.RegisterGateThatAlwaysRuns(this);
		}

		public bool IsOn()
		{
			if (InputSignals.Count > 0)
			{
				return InputSignals[0].IsOn;
			}
			Debug.Log((object)"error: DropPlayers has no inputs");
			return false;
		}

		public override void Logic(Fix SimDeltaTime)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			if ((OnlyActivateOnRise && !WasOnLastFrame && IsOn()) || (!OnlyActivateOnRise && IsOn() && (Object)(object)stickyRoundedRectangle != (Object)null))
			{
				stickyRoundedRectangle.DropAllAttachedPlayers(255, DropForce);
			}
			WasOnLastFrame = IsOn();
			((Component)this).GetComponent<FixTransform>().position = ((Component)stickyRoundedRectangle).GetComponent<FixTransform>().position;
		}
	}
	public abstract class LogicGate : MonoBehaviour
	{
		public readonly List<LogicInput> InputSignals = new List<LogicInput>();

		public readonly List<LogicOutput> OutputSignals = new List<LogicOutput>();

		public Fix LastTimeUpdated = Fix.Zero;

		public int UUID = 0;

		public abstract void Logic(Fix SimDeltaTime);
	}
	public class LogicInput
	{
		public int UUid;

		public LogicGate gate;

		public GameObject Owner;

		public bool IsOn;

		public List<LogicOutput> inputs;

		public LogicInput()
		{
			inputs = new List<LogicOutput>();
		}
	}
	public class LogicOutput
	{
		public int UUid;

		public LogicGate gate;

		public GameObject Owner;

		public bool IsOn;

		public bool WasOnLastTick;

		public List<LogicInput> outputs;

		public LogicOutput()
		{
			outputs = new List<LogicInput>();
		}
	}
	public class MovingPlatformSignalStuff : LogicGate
	{
		public bool SignalIsInverted = false;

		public void Register()
		{
			UUID = Plugin.NextUUID;
			Plugin.NextUUID++;
			SignalSystem.RegisterLogicGate(this);
			SignalSystem.RegisterInputThatUpdatesConnectson(InputSignals[0]);
		}

		public bool IsOn()
		{
			if (InputSignals.Count > 0)
			{
				return InputSignals[0].IsOn;
			}
			Debug.Log((object)"error: MovingPlatformSignalStuff has no inputs");
			return false;
		}

		public override void Logic(Fix SimDeltaTime)
		{
		}
	}
	public class NotGate : LogicGate
	{
		public void Register()
		{
			UUID = Plugin.NextUUID;
			Plugin.NextUUID++;
			SignalSystem.RegisterLogicGate(this);
		}

		public override void Logic(Fix SimDeltaTime)
		{
			OutputSignals[0].WasOnLastTick = OutputSignals[0].IsOn;
			OutputSignals[0].IsOn = !InputSignals[0].IsOn;
		}
	}
	public class OrGate : LogicGate
	{
		public void Register()
		{
			UUID = Plugin.NextUUID;
			Plugin.NextUUID++;
			SignalSystem.RegisterLogicGate(this);
		}

		public override void Logic(Fix SimDeltaTime)
		{
			LogicOutput logicOutput = OutputSignals[0];
			if (InputSignals.Count == 1)
			{
				logicOutput.WasOnLastTick = logicOutput.IsOn;
				logicOutput.IsOn = InputSignals[0].IsOn;
				return;
			}
			bool flag = false;
			for (int i = 0; i < InputSignals.Count; i++)
			{
				flag = InputSignals[i].IsOn || flag;
			}
			logicOutput.WasOnLastTick = logicOutput.IsOn;
			logicOutput.IsOn = flag;
		}
	}
	public class ShakePlatform : LogicGate
	{
		public bool OnlyActivateOnRise = false;

		public ShakablePlatform shakablePlatform;

		public Fix duration = Fix.One;

		public Fix shakeAmount = Fix.One;

		private bool WasOnLastFrame = false;

		public void Register()
		{
			UUID = Plugin.NextUUID;
			Plugin.NextUUID++;
			SignalSystem.RegisterLogicGate(this);
			SignalSystem.RegisterInputThatUpdatesConnectson(InputSignals[0]);
			SignalSystem.RegisterGateThatAlwaysRuns(this);
		}

		public bool IsOn()
		{
			if (InputSignals.Count > 0)
			{
				return InputSignals[0].IsOn;
			}
			Debug.Log((object)"error: ShakePlatform has no inputs");
			return false;
		}

		public override void Logic(Fix SimDeltaTime)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			if ((OnlyActivateOnRise && !WasOnLastFrame && IsOn()) || (!OnlyActivateOnRise && IsOn()))
			{
				shakablePlatform.AddShake(duration, shakeAmount, 11, (Material)null, (AnimationCurveFixed)null);
			}
			WasOnLastFrame = IsOn();
			((Component)this).GetComponent<FixTransform>().position = ((Component)shakablePlatform).GetComponent<FixTransform>().position;
		}
	}
	public class ShootRay : LogicGate
	{
		public enum RayType
		{
			Blink,
			Grow,
			Shrink
		}

		public static GameObject GrowGameObjectPrefab;

		public static GameObject StrinkGameObjectPrefab;

		public RayType rayType;

		public Fix VarenceInDegrees = Fix.Zero;

		public Fix BlinkMinPlayerDuration = (Fix)0.5;

		public Fix BlinkWallDuration = (Fix)3L;

		public Fix BlinkWallDelay = (Fix)1L;

		public Fix BlinkWallShake = (Fix)1L;

		public Fix blackHoleGrowth = (Fix)50L;

		public Fix ScaleMultiplyer = (Fix)0.8;

		public Fix PlayerMultiplyer = (Fix)0.8;

		public Fix smallNonPlayersMultiplier = (Fix)0.8;

		private bool WasOnLastTick = false;

		private FixTransform fixTransform;

		private ShootScaleChange shootScaleChange = null;

		public void Awake()
		{
			//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)
			Debug.Log((object)$"gameObject is {((Component)this).gameObject}");
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			string name = ((Object)((Component)this).gameObject).name;
			Scene activeScene = SceneManager.GetActiveScene();
			Debug.Log((object)(name + " Awake in " + ((Scene)(ref activeScene)).name));
		}

		private void OnDestroy()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			string name = ((Object)((Component)this).gameObject).name;
			Scene activeScene = SceneManager.GetActiveScene();
			Debug.Log((object)(name + " Destroyed in " + ((Scene)(ref activeScene)).name));
		}

		public void Register()
		{
			UUID = Plugin.NextUUID;
			Plugin.NextUUID++;
			fixTransform = ((Component)this).gameObject.GetComponent<FixTransform>();
			SignalSystem.RegisterLogicGate(this);
		}

		public bool IsOn()
		{
			bool wasOnLastTick = WasOnLastTick;
			WasOnLastTick = InputSignals[0].IsOn;
			return InputSignals[0].IsOn && !wasOnLastTick;
		}

		public override void Logic(Fix SimDeltaTime)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			if (IsOn())
			{
				Vec2 position = fixTransform.position;
				Fix val = VarenceInDegrees * (Fix)((float)Math.PI / 180f);
				Fix val2 = Updater.RandomFix(Fix.Zero, val * (Fix)2L) - val;
				Fix val3 = fixTransform.rotation + val2;
				Vec2 directionFIX = default(Vec2);
				((Vec2)(ref directionFIX))..ctor(val3);
				switch (rayType)
				{
				case RayType.Blink:
				{
					bool hasFired = false;
					((Component)this).GetComponent<ShootBlink>().minPlayerDuration = BlinkMinPlayerDuration;
					((Component)this).GetComponent<ShootBlink>().WallDuration = BlinkWallDuration;
					((Component)this).GetComponent<ShootBlink>().WallDelay = BlinkWallDelay;
					((Component)this).GetComponent<ShootBlink>().WallShake = BlinkWallShake;
					((Component)this).GetComponent<ShootBlink>().Shoot(position, directionFIX, ref hasFired);
					break;
				}
				case RayType.Grow:
					ShootGrow();
					break;
				case RayType.Shrink:
					ShootStrink();
					break;
				}
			}
		}

		public void ShootGrow()
		{
			//IL_007e: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)shootScaleChange == (Object)null)
			{
				ShootScaleChange component = GrowGameObjectPrefab.GetComponent<ShootScaleChange>();
				shootScaleChange = ShootRay.CopyComponent<ShootScaleChange>(component, ((Component)this).gameObject);
				shootScaleChange.Awake();
				ScaleChanger scaleChangerPrefab = component.ScaleChangerPrefab;
				scaleChangerPrefab.multiplier = ScaleMultiplyer;
				scaleChangerPrefab.PlayerMultiplier = PlayerMultiplyer;
				scaleChangerPrefab.smallNonPlayersMultiplier = smallNonPlayersMultiplier;
				shootScaleChange.ScaleChangerPrefab = scaleChangerPrefab;
			}
			Fix val = VarenceInDegrees * (Fix)((float)Math.PI / 180f);
			Fix val2 = Updater.RandomFix(Fix.Zero, val * (Fix)2L) - val;
			Fix val3 = fixTransform.rotation + val2;
			Vec2 val4 = default(Vec2);
			((Vec2)(ref val4))..ctor(val3);
			shootScaleChange.blackHoleGrowthInverse01 = Fix.One / blackHoleGrowth;
			bool flag = false;
			shootScaleChange.Shoot(fixTransform.position, val4, ref flag, 255, false);
		}

		public void ShootStrink()
		{
			//IL_007e: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)shootScaleChange == (Object)null)
			{
				ShootScaleChange component = StrinkGameObjectPrefab.GetComponent<ShootScaleChange>();
				shootScaleChange = ShootRay.CopyComponent<ShootScaleChange>(component, ((Component)this).gameObject);
				shootScaleChange.Awake();
				ScaleChanger scaleChangerPrefab = component.ScaleChangerPrefab;
				scaleChangerPrefab.multiplier = ScaleMultiplyer;
				scaleChangerPrefab.PlayerMultiplier = PlayerMultiplyer;
				scaleChangerPrefab.smallNonPlayersMultiplier = smallNonPlayersMultiplier;
				shootScaleChange.ScaleChangerPrefab = scaleChangerPrefab;
			}
			Fix val = VarenceInDegrees * (Fix)((float)Math.PI / 180f);
			Fix val2 = Updater.RandomFix(Fix.Zero, val * (Fix)2L) - val;
			Fix val3 = fixTransform.rotation + val2;
			Vec2 val4 = default(Vec2);
			((Vec2)(ref val4))..ctor(val3);
			shootScaleChange.blackHoleGrowthInverse01 = Fix.One / blackHoleGrowth;
			bool flag = false;
			shootScaleChange.Shoot(fixTransform.position, val4, ref flag, 255, false);
		}

		public static T CopyComponent<T>(T original, GameObject destination) where T : Component
		{
			Type type = ((object)original).GetType();
			Component val = destination.AddComponent(type);
			FieldInfo[] fields = type.GetFields();
			FieldInfo[] array = fields;
			foreach (FieldInfo fieldInfo in array)
			{
				fieldInfo.SetValue(val, fieldInfo.GetValue(original));
			}
			return (T)(object)((val is T) ? val : null);
		}
	}
	public class SignalDelay : LogicGate
	{
		public Fix delay = Fix.One;

		private List<bool> SignalBuffer = new List<bool>();

		private List<Fix> SignalTimeBuffer = new List<Fix>();

		private Fix lastSimTime;

		public void Register()
		{
			UUID = Plugin.NextUUID;
			Plugin.NextUUID++;
			SignalSystem.AllLogicGates.Add(this);
			SignalSystem.RegisterInput(InputSignals[0]);
			SignalSystem.RegisterTrigger(OutputSignals[0]);
			SignalSystem.RegisterGateThatAlwaysRuns(this);
		}

		public bool IsOn()
		{
			return InputSignals[0].IsOn;
		}

		public override void Logic(Fix SimDeltaTime)
		{
			//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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			lastSimTime = Updater.SimTimeSinceLevelLoaded;
			SignalBuffer.Add(IsOn());
			SignalTimeBuffer.Add(Updater.SimTimeSinceLevelLoaded);
			if (SignalTimeBuffer[0] + delay < Updater.SimTimeSinceLevelLoaded)
			{
				bool isOn = SignalBuffer[0];
				OutputSignals[0].WasOnLastTick = OutputSignals[0].IsOn;
				OutputSignals[0].IsOn = isOn;
				SignalBuffer.RemoveAt(0);
				SignalTimeBuffer.RemoveAt(0);
			}
		}
	}
	public class SignalSystem : MonoUpdatable
	{
		public static List<LogicOutput> LogicOutputs = new List<LogicOutput>();

		public static List<LogicInput> LogicInputs = new List<LogicInput>();

		public static List<LogicOutput> LogicStartingOutputs = new List<LogicOutput>();

		public static List<LogicGate> LogicGatesToAlwaysUpdate = new List<LogicGate>();

		public static List<LogicGate> AllLogicGates = new List<LogicGate>();

		public static List<LogicGate> LogicGatesInOrder = new List<LogicGate>();

		public static bool LogicDebugMode = false;

		public static Dictionary<LogicInput, LineRenderer> LineRenderers = new Dictionary<LogicInput, LineRenderer>();

		public static List<LogicInput> LogicInputsThatAlwaysUpdateThereLineConnectsons = new List<LogicInput>();

		public static bool FirstUpdateOfTheRound = true;

		private List<string> references = new List<string>();

		public static void RegisterLogicGate(LogicGate LogicGate)
		{
			AllLogicGates.Add(LogicGate);
			for (int i = 0; i < LogicGate.OutputSignals.Count; i++)
			{
				if (LogicOutputs.Count == 0)
				{
					LogicOutputs.Insert(0, LogicGate.OutputSignals[i]);
					break;
				}
				int index = BinarySearchLogicOutputSignalId(LogicGate.OutputSignals[i].UUid);
				LogicOutputs.Insert(index, LogicGate.OutputSignals[i]);
			}
			for (int j = 0; j < LogicGate.InputSignals.Count; j++)
			{
				RegisterInput(LogicGate.InputSignals[j]);
			}
		}

		public static void RegisterTrigger(LogicOutput logicOutput)
		{
			if (LogicStartingOutputs.Count == 0)
			{
				LogicStartingOutputs.Insert(0, logicOutput);
				return;
			}
			int index = BinarySearchLogicTriggerOutputSignalId(logicOutput.UUid);
			LogicStartingOutputs.Insert(index, logicOutput);
		}

		public static void RegisterInput(LogicInput input)
		{
			if (LogicInputs.Count == 0)
			{
				LogicInputs.Insert(0, input);
				return;
			}
			int index = BinarySearchLogicInputSignalId(input.UUid);
			LogicInputs.Insert(index, input);
		}

		public static void RegisterGateThatAlwaysRuns(LogicGate gate)
		{
			LogicGatesToAlwaysUpdate.Add(gate);
		}

		public static void RegisterInputThatUpdatesConnectson(LogicInput input)
		{
			LogicInputsThatAlwaysUpdateThereLineConnectsons.Add(input);
		}

		public static int BinarySearchLogicOutputSignalId(int UUid)
		{
			int num = 0;
			int num2 = LogicOutputs.Count - 1;
			int num3 = 0;
			while (num <= num2)
			{
				num3 = (num + num2) / 2;
				int uUid = LogicOutputs[num3].UUid;
				if (UUid < uUid)
				{
					num2 = num3 - 1;
					continue;
				}
				if (UUid > uUid)
				{
					num = num3 + 1;
					continue;
				}
				break;
			}
			if (LogicOutputs.Count != 0)
			{
				while (num3 >= 0 && LogicOutputs[num3].UUid >= UUid)
				{
					num3--;
				}
				return num3 + 1;
			}
			return 0;
		}

		public static int BinarySearchLogicInputSignalId(int UUid)
		{
			int num = 0;
			int num2 = LogicInputs.Count - 1;
			int num3 = 0;
			while (num <= num2)
			{
				num3 = Mathf.CeilToInt((float)((num + num2) / 2));
				int uUid = LogicInputs[num3].UUid;
				if (UUid < uUid)
				{
					num2 = num3 - 1;
					continue;
				}
				if (UUid > uUid)
				{
					num = num3 + 1;
					continue;
				}
				break;
			}
			if (LogicInputs.Count != 0)
			{
				while (num3 >= 0 && LogicInputs[num3].UUid >= UUid)
				{
					num3--;
				}
				return num3 + 1;
			}
			return 0;
		}

		public static int BinarySearchLogicTriggerOutputSignalId(int UUid)
		{
			int num = 0;
			int num2 = LogicStartingOutputs.Count - 1;
			int num3 = 0;
			while (num <= num2)
			{
				num3 = (num + num2) / 2;
				int uUid = LogicStartingOutputs[num3].UUid;
				if (UUid < uUid)
				{
					num2 = num3 - 1;
					continue;
				}
				if (UUid > uUid)
				{
					num = num3 + 1;
					continue;
				}
				break;
			}
			if (LogicStartingOutputs.Count != 0)
			{
				while (num3 >= 0 && LogicStartingOutputs[num3].UUid >= UUid)
				{
					num3--;
				}
				return num3 + 1;
			}
			return 0;
		}

		public static List<LogicInput> GetLogicInputs(int UUid)
		{
			if (LogicInputs.Count == 0)
			{
				Debug.Log((object)"no LogicInputs");
				return new List<LogicInput>();
			}
			int num = BinarySearchLogicInputSignalId(UUid);
			if (LogicInputs[num].UUid != UUid)
			{
				Debug.Log((object)$"no LogicInputs with UUid {UUid}");
				return new List<LogicInput>();
			}
			int i = num;
			List<LogicInput> list = new List<LogicInput>();
			for (; i < LogicInputs.Count && LogicInputs[i].UUid == UUid; i++)
			{
				list.Add(LogicInputs[i]);
			}
			return list;
		}

		public static List<LogicOutput> GetLogicOutputs(int UUid)
		{
			List<LogicOutput> list = new List<LogicOutput>();
			list.AddRange(LogicOutputs);
			list.AddRange(LogicStartingOutputs);
			if (list.Count == 0)
			{
				return new List<LogicOutput>();
			}
			int num = BinarySearchLogicOutputSignalId(UUid);
			if (list[num].UUid != UUid)
			{
				return new List<LogicOutput>();
			}
			int i = num;
			List<LogicOutput> list2 = new List<LogicOutput>();
			for (; i < list.Count && list[i].UUid == UUid; i++)
			{
				list2.Add(list[i]);
			}
			return list2;
		}

		public void SetUpDicts()
		{
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Expected O, but got Unknown
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Expected O, but got Unknown
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			List<LogicOutput> list = new List<LogicOutput>();
			list.AddRange(LogicOutputs);
			list.AddRange(LogicStartingOutputs);
			List<int> list2 = new List<int>();
			foreach (LogicOutput item in list)
			{
				if (list2.Contains(item.UUid))
				{
					throw new InvalidOperationException("Logic Output UUids must be unique! not generating the logic connectsons!");
				}
				list2.Add(item.UUid);
			}
			Graph graph = new Graph(Plugin.NextUUID);
			foreach (LogicOutput item2 in list)
			{
				List<LogicInput> logicInputs = GetLogicInputs(item2.UUid);
				foreach (LogicInput item3 in logicInputs)
				{
					if (item3.inputs == null)
					{
						Debug.Log((object)"input.inputs IS NULL!");
					}
					item3.inputs.Add(item2);
					item2.outputs.Add(item3);
					if (LogicDebugMode)
					{
						GameObject val = new GameObject("LineRenderer");
						LineRenderer val2 = val.AddComponent<LineRenderer>();
						((Renderer)val2).material = new Material(Shader.Find("Hidden/Internal-Colored"));
						Color endColor = (val2.startColor = Color.red);
						val2.endColor = endColor;
						float endWidth = (val2.startWidth = 0.2f);
						val2.endWidth = endWidth;
						val2.positionCount = 2;
						SetLinePosForLine(val2, item3, item2);
						LineRenderers.Add(item3, val2);
					}
					if ((Object)(object)item3.gate != (Object)null && (Object)(object)item2.Owner.GetComponent<SignalDelay>() == (Object)null)
					{
						if ((Object)(object)item2.gate != (Object)null)
						{
							graph.addEdge(item2.gate.UUID, item3.gate.UUID, item3.Owner, item3.gate, item2.Owner, item2.gate);
							continue;
						}
						Trigger component = item2.Owner.GetComponent<Trigger>();
						graph.addEdge(component.UUID, item3.gate.UUID, item3.Owner, item3.gate, item2.Owner, item2.gate);
					}
				}
			}
			if (!LogicDebugMode)
			{
				foreach (LogicGate allLogicGate in AllLogicGates)
				{
					if (Object.op_Implicit((Object)(object)((Component)allLogicGate).gameObject) && (Object)(object)((Component)allLogicGate).gameObject.GetComponent<SpriteRenderer>() != (Object)null && (Object)(object)((Component)allLogicGate).gameObject.GetComponent<StickyRoundedRectangle>() == (Object)null)
					{
						Object.Destroy((Object)(object)((Component)allLogicGate).gameObject.GetComponent<SpriteRenderer>());
					}
				}
			}
			if (graph.isCyclic())
			{
				throw new InvalidOperationException("Logic Gate Loops Must Have a Delay In Them!");
			}
			LogicGatesInOrder = graph.BuildListOfGates();
			Updater.RegisterUpdatable((MonoUpdatable)(object)this);
		}

		public static void SetLinePosForLine(LineRenderer lineRenderer, LogicInput input, LogicOutput output)
		{
			//IL_00b7: 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_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0367: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_037f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_0395: Unknown result type (might be due to invalid IL or missing references)
			//IL_0397: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Unknown result type (might be due to invalid IL or missing references)
			//IL_039e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0400: Unknown result type (might be due to invalid IL or missing references)
			//IL_0452: Unknown result type (might be due to invalid IL or missing references)
			//IL_0457: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04db: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0501: Unknown result type (might be due to invalid IL or missing references)
			//IL_0503: Unknown result type (might be due to invalid IL or missing references)
			//IL_0505: Unknown result type (might be due to invalid IL or missing references)
			//IL_050a: Unknown result type (might be due to invalid IL or missing references)
			//IL_050e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0533: Unknown result type (might be due to invalid IL or missing references)
			//IL_0538: Unknown result type (might be due to invalid IL or missing references)
			//IL_053d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0571: Unknown result type (might be due to invalid IL or missing references)
			//IL_057e: Unknown result type (might be due to invalid IL or missing references)
			//IL_05aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_05cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0600: Unknown result type (might be due to invalid IL or missing references)
			//IL_0616: Unknown result type (might be due to invalid IL or missing references)
			//IL_0623: Unknown result type (might be due to invalid IL or missing references)
			//IL_0635: Unknown result type (might be due to invalid IL or missing references)
			//IL_063a: Unknown result type (might be due to invalid IL or missing references)
			//IL_063c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0643: Unknown result type (might be due to invalid IL or missing references)
			//IL_0648: Unknown result type (might be due to invalid IL or missing references)
			//IL_064d: Unknown result type (might be due to invalid IL or missing references)
			//IL_064f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0651: Unknown result type (might be due to invalid IL or missing references)
			//IL_0653: Unknown result type (might be due to invalid IL or missing references)
			//IL_0655: Unknown result type (might be due to invalid IL or missing references)
			//IL_065a: Unknown result type (might be due to invalid IL or missing references)
			//IL_065e: Unknown result type (might be due to invalid IL or missing references)
			GameObject owner = input.Owner;
			GameObject owner2 = output.Owner;
			if ((Object)(object)owner == (Object)null && (Object)(object)lineRenderer != (Object)null)
			{
				Object.Destroy((Object)(object)lineRenderer);
			}
			else
			{
				if (!((Object)(object)lineRenderer != (Object)null))
				{
					return;
				}
				if ((Object)(object)owner.GetComponent<Trigger>() != (Object)null || (Object)(object)owner.GetComponent<Spawner>() != (Object)null || (Object)(object)owner.GetComponent<DisappearPlatformsOnSignal>() != (Object)null || (Object)(object)owner.GetComponent<MovingPlatformSignalStuff>() != (Object)null || (Object)(object)owner.GetComponent<ShootRay>() != (Object)null || (Object)(object)owner.GetComponent<ShakePlatform>() != (Object)null || (Object)(object)owner.GetComponent<DropPlayers>() != (Object)null)
				{
					lineRenderer.SetPosition(0, (Vector3)owner.GetComponent<FixTransform>().position);
					DisappearPlatformsOnSignal component = owner.GetComponent<DisappearPlatformsOnSignal>();
					if ((Object)(object)component != (Object)null)
					{
						if ((Object)(object)component.platform != (Object)null)
						{
							lineRenderer.SetPosition(0, (Vector3)component.platform.GetComponent<FixTransform>().position);
						}
						else
						{
							Object.Destroy((Object)(object)lineRenderer);
						}
					}
					DropPlayers component2 = owner.GetComponent<DropPlayers>();
					if ((Object)(object)component2 != (Object)null)
					{
						if ((Object)(object)component2.stickyRoundedRectangle != (Object)null && (Object)(object)((Component)component2.stickyRoundedRectangle).gameObject != (Object)null)
						{
							lineRenderer.SetPosition(0, (Vector3)((Component)component2.stickyRoundedRectangle).gameObject.GetComponent<FixTransform>().position);
						}
						else
						{
							Object.Destroy((Object)(object)lineRenderer);
						}
					}
					ShakePlatform component3 = owner.GetComponent<ShakePlatform>();
					if ((Object)(object)component3 != (Object)null)
					{
						if ((Object)(object)component3.shakablePlatform != (Object)null && (Object)(object)((Component)component3.shakablePlatform).gameObject != (Object)null)
						{
							lineRenderer.SetPosition(0, (Vector3)((Component)component3.shakablePlatform).gameObject.GetComponent<FixTransform>().position);
						}
						else
						{
							Object.Destroy((Object)(object)lineRenderer);
						}
					}
				}
				if ((Object)(object)owner.GetComponent<NotGate>() != (Object)null || (Object)(object)owner.GetComponent<SignalDelay>() != (Object)null)
				{
					Vector3 val = (Vector3)owner.GetComponent<FixTransform>().position;
					Fix rotationInner = owner.GetComponent<FixTransform>().rotationInner;
					Fix angle = rotationInner * (Fix)(180f / (float)Math.PI);
					float x = owner.transform.localScale.x;
					Vector3 point = val + new Vector3(-2f, 0f);
					Vector3 val2 = RotatePointAroundPivot(point, val, angle);
					lineRenderer.SetPosition(0, val2);
				}
				if ((Object)(object)owner.GetComponent<AndGate>() != (Object)null || (Object)(object)owner.GetComponent<OrGate>() != (Object)null || (Object)(object)owner.GetComponent<LuaMain>() != (Object)null)
				{
					Vector3 val3 = (Vector3)owner.GetComponent<FixTransform>().position;
					int count = input.gate.InputSignals.Count;
					int num = input.gate.InputSignals.IndexOf(input) + 1;
					double num2 = 0.6;
					double num3 = (double)val3.y - num2;
					float y = val3.y;
					double num4 = (double)(num - 1) * (2.0 * ((double)y - num3) / (double)(count - 1)) + num3;
					Vector3 point2 = default(Vector3);
					((Vector3)(ref point2))..ctor(val3.x - 1.7f, (float)num4);
					Fix rotationInner2 = owner.GetComponent<FixTransform>().rotationInner;
					Fix angle2 = rotationInner2 * (Fix)(180f / (float)Math.PI);
					float x2 = owner.transform.localScale.x;
					Vector3 val4 = RotatePointAroundPivot(point2, val3, angle2);
					lineRenderer.SetPosition(0, val4);
					if (count == 1)
					{
						((Vector3)(ref point2))..ctor(val3.x - 1.7f, val3.y);
						Fix rotationInner3 = owner.GetComponent<FixTransform>().rotationInner;
						Fix angle3 = rotationInner3 * (Fix)(180f / (float)Math.PI);
						Vector3 val5 = RotatePointAroundPivot(point2, val3, angle3);
						lineRenderer.SetPosition(0, val5);
					}
				}
				if ((Object)(object)owner2.GetComponent<Trigger>() != (Object)null || (Object)(object)owner2.GetComponent<Spawner>() != (Object)null || (Object)(object)owner2.GetComponent<DisappearPlatformsOnSignal>() != (Object)null || (Object)(object)owner2.GetComponent<MovingPlatformSignalStuff>() != (Object)null)
				{
					lineRenderer.SetPosition(1, (Vector3)owner2.GetComponent<FixTransform>().position);
				}
				if ((Object)(object)owner2.GetComponent<NotGate>() != (Object)null || (Object)(object)owner2.GetComponent<SignalDelay>() != (Object)null || (Object)(object)owner2.GetComponent<AndGate>() != (Object)null || (Object)(object)owner2.GetComponent<OrGate>() != (Object)null)
				{
					Vector3 val6 = (Vector3)owner2.GetComponent<FixTransform>().position;
					Fix rotationInner4 = owner2.GetComponent<FixTransform>().rotationInner;
					Fix angle4 = rotationInner4 * (Fix)(180f / (float)Math.PI);
					float x3 = owner.transform.localScale.x;
					Vector3 point3 = val6 + new Vector3(2f, 0f);
					Vector3 val7 = RotatePointAroundPivot(point3, val6, angle4);
					lineRenderer.SetPosition(1, val7);
				}
				if ((Object)(object)owner2.GetComponent<LuaMain>() != (Object)null)
				{
					Vector3 val8 = (Vector3)owner2.GetComponent<FixTransform>().position;
					int count2 = output.gate.OutputSignals.Count;
					int num5 = output.gate.OutputSignals.IndexOf(output) + 1;
					double num6 = 0.6;
					double num7 = (double)val8.y - num6;
					float y2 = val8.y;
					double num8 = (double)(num5 - 1) * (2.0 * ((double)y2 - num7) / (double)(count2 - 1)) + num7;
					Vector3 point4 = default(Vector3);
					((Vector3)(ref point4))..ctor(val8.x + 1.7f, (float)num8);
					Fix rotationInner5 = owner2.GetComponent<FixTransform>().rotationInner;
					Fix angle5 = rotationInner5 * (Fix)(180f / (float)Math.PI);
					float x4 = owner2.transform.localScale.x;
					Vector3 val9 = RotatePointAroundPivot(point4, val8, angle5);
					lineRenderer.SetPosition(1, val9);
					if (count2 == 1)
					{
						((Vector3)(ref point4))..ctor(val8.x + 1.7f, val8.y);
						Fix rotationInner6 = owner2.GetComponent<FixTransform>().rotationInner;
						Fix angle6 = rotationInner6 * (Fix)(180f / (float)Math.PI);
						Vector3 val10 = RotatePointAroundPivot(point4, val8, angle6);
						lineRenderer.SetPosition(1, val10);
					}
				}
			}
		}

		public override void Init()
		{
		}

		public override void UpdateSim(Fix SimDeltaTime)
		{
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: 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_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: 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_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			List<MonoUpdatable> updatables = Updater.updatables;
			int num = updatables.IndexOf((MonoUpdatable)(object)this);
			if (num != updatables.Count - 1)
			{
				updatables.RemoveAt(num);
				updatables.Add((MonoUpdatable)(object)this);
				return;
			}
			foreach (LogicOutput logicOutput2 in LogicOutputs)
			{
				logicOutput2.WasOnLastTick = logicOutput2.IsOn;
			}
			if (!GameTime.IsTimeStopped() && PlatformApi.gameInProgress)
			{
				foreach (LogicGate item in LogicGatesInOrder)
				{
					foreach (LogicInput inputSignal in item.InputSignals)
					{
						LogicOutput logicOutput = inputSignal.inputs[0];
						inputSignal.IsOn = logicOutput.IsOn;
						if (LogicDebugMode)
						{
							LineRenderer val = LineRenderers[inputSignal];
							if (Object.op_Implicit((Object)(object)val))
							{
								if (inputSignal.IsOn)
								{
									Color endColor = (val.startColor = Color.green);
									val.endColor = endColor;
								}
								else
								{
									Color endColor = (val.startColor = Color.red);
									val.endColor = endColor;
								}
							}
						}
						if (item.LastTimeUpdated != Updater.SimTimeSinceLevelLoaded)
						{
							item.Logic(SimDeltaTime);
							item.LastTimeUpdated = Updater.SimTimeSinceLevelLoaded;
						}
					}
				}
				if (FirstUpdateOfTheRound)
				{
					FirstUpdateOfTheRound = false;
				}
				if (LogicDebugMode)
				{
					foreach (LogicInput logicInputsThatAlwaysUpdateThereLineConnectson in LogicInputsThatAlwaysUpdateThereLineConnectsons)
					{
						LineRenderer lineRenderer = LineRenderers[logicInputsThatAlwaysUpdateThereLineConnectson];
				

mapMaker/MoonSharp.Interpreter.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using MoonSharp.Interpreter.Compatibility;
using MoonSharp.Interpreter.Compatibility.Frameworks;
using MoonSharp.Interpreter.CoreLib;
using MoonSharp.Interpreter.CoreLib.IO;
using MoonSharp.Interpreter.CoreLib.StringLib;
using MoonSharp.Interpreter.DataStructs;
using MoonSharp.Interpreter.Debugging;
using MoonSharp.Interpreter.Diagnostics;
using MoonSharp.Interpreter.Diagnostics.PerformanceCounters;
using MoonSharp.Interpreter.Execution;
using MoonSharp.Interpreter.Execution.Scopes;
using MoonSharp.Interpreter.Execution.VM;
using MoonSharp.Interpreter.IO;
using MoonSharp.Interpreter.Interop;
using MoonSharp.Interpreter.Interop.BasicDescriptors;
using MoonSharp.Interpreter.Interop.Converters;
using MoonSharp.Interpreter.Interop.LuaStateInterop;
using MoonSharp.Interpreter.Interop.RegistrationPolicies;
using MoonSharp.Interpreter.Interop.StandardDescriptors;
using MoonSharp.Interpreter.Interop.UserDataRegistries;
using MoonSharp.Interpreter.Loaders;
using MoonSharp.Interpreter.Platforms;
using MoonSharp.Interpreter.REPL;
using MoonSharp.Interpreter.Serialization.Json;
using MoonSharp.Interpreter.Tree;
using MoonSharp.Interpreter.Tree.Expressions;
using MoonSharp.Interpreter.Tree.Fast_Interface;
using MoonSharp.Interpreter.Tree.Statements;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("MoonSharp.Interpreter")]
[assembly: AssemblyDescription("An interpreter for the Lua language")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("http://www.moonsharp.org")]
[assembly: AssemblyProduct("MoonSharp.Interpreter")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("c971e5a8-dbec-4408-8046-86e4fdd1b2e3")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: InternalsVisibleTo("MoonSharp.Interpreter.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100F704C50BBDC3F2F011CC26A8C6C4797A40E0B4BC94CFB1335E9BA208326340696B686DC13099F10D3054544532F5E3E66C26A13FF260AEA2343E0410511FE56EDCC2AFB898AAA1BC21DA33C0D0AE60824EB441D02A0E6B7AE251CDE0946BFC748209C12B062573ECDB008A3D10CC40534B314847591CE5342A3BC6AA83CE23B8")]
[assembly: InternalsVisibleTo("MoonSharp.Interpreter.Tests.net40-client, PublicKey=0024000004800000940000000602000000240000525341310004000001000100F704C50BBDC3F2F011CC26A8C6C4797A40E0B4BC94CFB1335E9BA208326340696B686DC13099F10D3054544532F5E3E66C26A13FF260AEA2343E0410511FE56EDCC2AFB898AAA1BC21DA33C0D0AE60824EB441D02A0E6B7AE251CDE0946BFC748209C12B062573ECDB008A3D10CC40534B314847591CE5342A3BC6AA83CE23B8")]
[assembly: InternalsVisibleTo("MoonSharp.Interpreter.Tests.portable40, PublicKey=0024000004800000940000000602000000240000525341310004000001000100F704C50BBDC3F2F011CC26A8C6C4797A40E0B4BC94CFB1335E9BA208326340696B686DC13099F10D3054544532F5E3E66C26A13FF260AEA2343E0410511FE56EDCC2AFB898AAA1BC21DA33C0D0AE60824EB441D02A0E6B7AE251CDE0946BFC748209C12B062573ECDB008A3D10CC40534B314847591CE5342A3BC6AA83CE23B8")]
[assembly: AssemblyCopyright("Copyright © 2014-2015, Marco Mastropaolo")]
[assembly: InternalsVisibleTo("MoonSharp.Interpreter.Tests.net35-client, PublicKey=0024000004800000940000000602000000240000525341310004000001000100F704C50BBDC3F2F011CC26A8C6C4797A40E0B4BC94CFB1335E9BA208326340696B686DC13099F10D3054544532F5E3E66C26A13FF260AEA2343E0410511FE56EDCC2AFB898AAA1BC21DA33C0D0AE60824EB441D02A0E6B7AE251CDE0946BFC748209C12B062573ECDB008A3D10CC40534B314847591CE5342A3BC6AA83CE23B8")]
[assembly: TargetFramework(".NETFramework,Version=v4.0,Profile=Client", FrameworkDisplayName = ".NET Framework 4 Client Profile")]
[assembly: AssemblyVersion("2.0.0.0")]
namespace MoonSharp.Interpreter
{
	public static class AsyncExtensions
	{
		public static Task<T> ExecAsync<T>(Func<T> func)
		{
			return Task.Factory.StartNew(func);
		}

		public static Task ExecAsyncVoid(Action func)
		{
			return Task.Factory.StartNew(func);
		}

		public static Task<DynValue> CallAsync(this Closure function)
		{
			return ExecAsync(() => function.Call());
		}

		public static Task<DynValue> CallAsync(this Closure function, params object[] args)
		{
			return ExecAsync(() => function.Call(args));
		}

		public static Task<DynValue> CallAsync(this Closure function, params DynValue[] args)
		{
			return ExecAsync(() => function.Call(args));
		}

		public static Task<DynValue> DoStringAsync(this Script script, string code, Table globalContext = null, string codeFriendlyName = null)
		{
			return ExecAsync(() => script.DoString(code, globalContext, codeFriendlyName));
		}

		public static Task<DynValue> DoStreamAsync(this Script script, Stream stream, Table globalContext = null, string codeFriendlyName = null)
		{
			return ExecAsync(() => script.DoStream(stream, globalContext, codeFriendlyName));
		}

		public static Task<DynValue> DoFileAsync(this Script script, string filename, Table globalContext = null, string codeFriendlyName = null)
		{
			return ExecAsync(() => script.DoFile(filename, globalContext, codeFriendlyName));
		}

		public static Task<DynValue> LoadFunctionAsync(this Script script, string code, Table globalTable = null, string funcFriendlyName = null)
		{
			return ExecAsync(() => script.LoadFunction(code, globalTable, funcFriendlyName));
		}

		public static Task<DynValue> LoadStringAsync(this Script script, string code, Table globalTable = null, string codeFriendlyName = null)
		{
			return ExecAsync(() => script.LoadString(code, globalTable, codeFriendlyName));
		}

		public static Task<DynValue> LoadStreamAsync(this Script script, Stream stream, Table globalTable = null, string codeFriendlyName = null)
		{
			return ExecAsync(() => script.LoadStream(stream, globalTable, codeFriendlyName));
		}

		public static Task DumpAsync(this Script script, DynValue function, Stream stream)
		{
			return ExecAsyncVoid(delegate
			{
				script.Dump(function, stream);
			});
		}

		public static Task<DynValue> LoadFileAsync(this Script script, string filename, Table globalContext = null, string friendlyFilename = null)
		{
			return ExecAsync(() => script.LoadFile(filename, globalContext, friendlyFilename));
		}

		public static Task<DynValue> CallAsync(this Script script, DynValue function)
		{
			return ExecAsync(() => script.Call(function));
		}

		public static Task<DynValue> CallAsync(this Script script, DynValue function, params DynValue[] args)
		{
			return ExecAsync(() => script.Call(function, args));
		}

		public static Task<DynValue> CallAsync(this Script script, DynValue function, params object[] args)
		{
			return ExecAsync(() => script.Call(function, args));
		}

		public static Task<DynValue> CallAsync(this Script script, object function)
		{
			return ExecAsync(() => script.Call(function));
		}

		public static Task<DynValue> CallAsync(this Script script, object function, params object[] args)
		{
			return ExecAsync(() => script.Call(function, args));
		}

		public static Task<DynamicExpression> CreateDynamicExpressionAsync(this Script script, string code)
		{
			return ExecAsync(() => script.CreateDynamicExpression(code));
		}

		public static Task<DynValue> EvaluateAsync(this ReplInterpreter interpreter, string input)
		{
			return ExecAsync(() => interpreter.Evaluate(input));
		}

		public static Task<DynValue> ResumeAsync(this Coroutine cor, params DynValue[] args)
		{
			return ExecAsync(() => cor.Resume(args));
		}

		public static Task<DynValue> ResumeAsync(this Coroutine cor, ScriptExecutionContext context, params DynValue[] args)
		{
			return ExecAsync(() => cor.Resume(context, args));
		}

		public static Task<DynValue> ResumeAsync(this Coroutine cor)
		{
			return ExecAsync(() => cor.Resume());
		}

		public static Task<DynValue> ResumeAsync(this Coroutine cor, ScriptExecutionContext context)
		{
			return ExecAsync(() => cor.Resume(context));
		}

		public static Task<DynValue> ResumeAsync(this Coroutine cor, params object[] args)
		{
			return ExecAsync(() => cor.Resume(args));
		}

		public static Task<DynValue> ResumeAsync(this Coroutine cor, ScriptExecutionContext context, params object[] args)
		{
			return ExecAsync(() => cor.Resume(context, args));
		}
	}
	[AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = true)]
	public sealed class MoonSharpPropertyAttribute : Attribute
	{
		public string Name { get; set; }

		public MoonSharpPropertyAttribute()
		{
		}

		public MoonSharpPropertyAttribute(string name)
		{
			Name = name;
		}
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
	public sealed class MoonSharpUserDataMetamethodAttribute : Attribute
	{
		public string Name { get; set; }

		public MoonSharpUserDataMetamethodAttribute(string name)
		{
			Name = name;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = true, AllowMultiple = true)]
	public sealed class MoonSharpHideMemberAttribute : Attribute
	{
		public string MemberName { get; set; }

		public MoonSharpHideMemberAttribute(string memberName)
		{
			MemberName = memberName;
		}
	}
	[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event, Inherited = true, AllowMultiple = false)]
	public sealed class MoonSharpHiddenAttribute : Attribute
	{
	}
	public delegate object ScriptFunctionDelegate(params object[] args);
	public delegate T ScriptFunctionDelegate<T>(params object[] args);
	[Flags]
	public enum TypeValidationFlags
	{
		None = 0,
		AllowNil = 1,
		AutoConvert = 2,
		Default = 2
	}
	[Serializable]
	public class DynamicExpressionException : ScriptRuntimeException
	{
		public DynamicExpressionException(string format, params object[] args)
			: base("<dynamic>: " + format, args)
		{
		}

		public DynamicExpressionException(string message)
			: base("<dynamic>: " + message)
		{
		}
	}
	public class DynamicExpression : IScriptPrivateResource
	{
		public DynamicExprExpression m_Exp;

		public DynValue m_Constant;

		public readonly string ExpressionCode;

		public Script OwnerScript { get; set; }

		public DynamicExpression(Script S, string strExpr, DynamicExprExpression expr)
		{
			ExpressionCode = strExpr;
			OwnerScript = S;
			m_Exp = expr;
		}

		public DynamicExpression(Script S, string strExpr, DynValue constant)
		{
			ExpressionCode = strExpr;
			OwnerScript = S;
			m_Constant = constant;
		}

		public DynValue Evaluate(ScriptExecutionContext context = null)
		{
			context = context ?? OwnerScript.CreateDynamicExecutionContext();
			this.CheckScriptOwnership(context.GetScript());
			if (m_Constant != null)
			{
				return m_Constant;
			}
			return m_Exp.Eval(context);
		}

		public SymbolRef FindSymbol(ScriptExecutionContext context)
		{
			this.CheckScriptOwnership(context.GetScript());
			if (m_Exp != null)
			{
				return m_Exp.FindDynamic(context);
			}
			return null;
		}

		public bool IsConstant()
		{
			return m_Constant != null;
		}

		public override int GetHashCode()
		{
			return ExpressionCode.GetHashCode();
		}

		public override bool Equals(object obj)
		{
			if (!(obj is DynamicExpression dynamicExpression))
			{
				return false;
			}
			return dynamicExpression.ExpressionCode == ExpressionCode;
		}
	}
	public static class Extension_Methods
	{
		public static TValue GetOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key)
		{
			if (dictionary.TryGetValue(key, out var value))
			{
				return value;
			}
			return default(TValue);
		}

		public static TValue GetOrCreate<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key, Func<TValue> creator)
		{
			if (!dictionary.TryGetValue(key, out var value))
			{
				value = creator();
				dictionary.Add(key, value);
			}
			return value;
		}
	}
	public class Coroutine : RefIdObject, IScriptPrivateResource
	{
		public enum CoroutineType
		{
			Coroutine,
			ClrCallback,
			ClrCallbackDead
		}

		public CallbackFunction m_ClrCallback;

		public Processor m_Processor;

		public CoroutineType Type { get; set; }

		public CoroutineState State
		{
			get
			{
				if (Type == CoroutineType.ClrCallback)
				{
					return CoroutineState.NotStarted;
				}
				if (Type == CoroutineType.ClrCallbackDead)
				{
					return CoroutineState.Dead;
				}
				return m_Processor.State;
			}
		}

		public Script OwnerScript { get; set; }

		public long AutoYieldCounter
		{
			get
			{
				return m_Processor.AutoYieldCounter;
			}
			set
			{
				m_Processor.AutoYieldCounter = value;
			}
		}

		public Coroutine(CallbackFunction function)
		{
			Type = CoroutineType.ClrCallback;
			m_ClrCallback = function;
			OwnerScript = null;
		}

		public Coroutine(Processor proc)
		{
			Type = CoroutineType.Coroutine;
			m_Processor = proc;
			m_Processor.AssociatedCoroutine = this;
			OwnerScript = proc.GetScript();
		}

		public void MarkClrCallbackAsDead()
		{
			if (Type != CoroutineType.ClrCallback)
			{
				throw new InvalidOperationException("State must be CoroutineType.ClrCallback");
			}
			Type = CoroutineType.ClrCallbackDead;
		}

		public IEnumerable<DynValue> AsTypedEnumerable()
		{
			if (Type != 0)
			{
				throw new InvalidOperationException("Only non-CLR coroutines can be resumed with this overload of the Resume method. Use the overload accepting a ScriptExecutionContext instead");
			}
			while (State == CoroutineState.NotStarted || State == CoroutineState.Suspended || State == CoroutineState.ForceSuspended)
			{
				yield return Resume();
			}
		}

		public IEnumerable<object> AsEnumerable()
		{
			foreach (DynValue item in AsTypedEnumerable())
			{
				yield return item.ToScalar().ToObject();
			}
		}

		public IEnumerable<T> AsEnumerable<T>()
		{
			foreach (DynValue item in AsTypedEnumerable())
			{
				yield return item.ToScalar().ToObject<T>();
			}
		}

		public IEnumerator AsUnityCoroutine()
		{
			foreach (DynValue item in AsTypedEnumerable())
			{
				_ = item;
				yield return null;
			}
		}

		public DynValue Resume(params DynValue[] args)
		{
			this.CheckScriptOwnership(args);
			if (Type == CoroutineType.Coroutine)
			{
				return m_Processor.Coroutine_Resume(args);
			}
			throw new InvalidOperationException("Only non-CLR coroutines can be resumed with this overload of the Resume method. Use the overload accepting a ScriptExecutionContext instead");
		}

		public DynValue Resume(ScriptExecutionContext context, params DynValue[] args)
		{
			this.CheckScriptOwnership(context);
			this.CheckScriptOwnership(args);
			if (Type == CoroutineType.Coroutine)
			{
				return m_Processor.Coroutine_Resume(args);
			}
			if (Type == CoroutineType.ClrCallback)
			{
				DynValue result = m_ClrCallback.Invoke(context, args);
				MarkClrCallbackAsDead();
				return result;
			}
			throw ScriptRuntimeException.CannotResumeNotSuspended(CoroutineState.Dead);
		}

		public DynValue Resume()
		{
			return Resume(new DynValue[0]);
		}

		public DynValue Resume(ScriptExecutionContext context)
		{
			return Resume(context, new DynValue[0]);
		}

		public DynValue Resume(params object[] args)
		{
			if (Type != 0)
			{
				throw new InvalidOperationException("Only non-CLR coroutines can be resumed with this overload of the Resume method. Use the overload accepting a ScriptExecutionContext instead");
			}
			DynValue[] array = new DynValue[args.Length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = DynValue.FromObject(OwnerScript, args[i]);
			}
			return Resume(array);
		}

		public DynValue Resume(ScriptExecutionContext context, params object[] args)
		{
			DynValue[] array = new DynValue[args.Length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = DynValue.FromObject(context.GetScript(), args[i]);
			}
			return Resume(context, array);
		}

		public WatchItem[] GetStackTrace(int skip, SourceRef entrySourceRef = null)
		{
			if (State != CoroutineState.Running)
			{
				entrySourceRef = m_Processor.GetCoroutineSuspendedLocation();
			}
			return m_Processor.Debugger_GetCallStack(entrySourceRef).Skip(skip).ToArray();
		}
	}
	public interface IScriptPrivateResource
	{
		Script OwnerScript { get; }
	}
	public static class ScriptPrivateResource_Extension
	{
		public static void CheckScriptOwnership(this IScriptPrivateResource containingResource, DynValue[] values)
		{
			foreach (DynValue value in values)
			{
				containingResource.CheckScriptOwnership(value);
			}
		}

		public static void CheckScriptOwnership(this IScriptPrivateResource containingResource, DynValue value)
		{
			if (value != null)
			{
				IScriptPrivateResource asPrivateResource = value.GetAsPrivateResource();
				if (asPrivateResource != null)
				{
					containingResource.CheckScriptOwnership(asPrivateResource);
				}
			}
		}

		public static void CheckScriptOwnership(this IScriptPrivateResource resource, Script script)
		{
			if (resource.OwnerScript != null && resource.OwnerScript != script && script != null)
			{
				throw new ScriptRuntimeException("Attempt to access a resource owned by a script, from another script");
			}
		}

		public static void CheckScriptOwnership(this IScriptPrivateResource containingResource, IScriptPrivateResource itemResource)
		{
			if (itemResource != null)
			{
				if (containingResource.OwnerScript != null && containingResource.OwnerScript != itemResource.OwnerScript && itemResource.OwnerScript != null)
				{
					throw new ScriptRuntimeException("Attempt to perform operations with resources owned by different scripts.");
				}
				if (containingResource.OwnerScript == null && itemResource.OwnerScript != null)
				{
					throw new ScriptRuntimeException("Attempt to perform operations with a script private resource on a shared resource.");
				}
			}
		}
	}
	public class RefIdObject
	{
		public static int s_RefIDCounter;

		public int m_RefID = ++s_RefIDCounter;

		public int ReferenceID => m_RefID;

		public string FormatTypeString(string typeString)
		{
			return $"{typeString}: {m_RefID:X8}";
		}
	}
	public class TailCallData
	{
		public DynValue Function { get; set; }

		public DynValue[] Args { get; set; }

		public CallbackFunction Continuation { get; set; }

		public CallbackFunction ErrorHandler { get; set; }

		public DynValue ErrorHandlerBeforeUnwind { get; set; }
	}
	public class UserData : RefIdObject
	{
		public DynValue UserValue { get; set; }

		public object Object { get; set; }

		public IUserDataDescriptor Descriptor { get; set; }

		public static IRegistrationPolicy RegistrationPolicy
		{
			get
			{
				return TypeDescriptorRegistry.RegistrationPolicy;
			}
			set
			{
				TypeDescriptorRegistry.RegistrationPolicy = value;
			}
		}

		public static InteropAccessMode DefaultAccessMode
		{
			get
			{
				return TypeDescriptorRegistry.DefaultAccessMode;
			}
			set
			{
				TypeDescriptorRegistry.DefaultAccessMode = value;
			}
		}

		static UserData()
		{
			RegistrationPolicy = InteropRegistrationPolicy.Default;
			RegisterType<EventFacade>(InteropAccessMode.NoReflectionAllowed);
			RegisterType<AnonWrapper>(InteropAccessMode.HideMembers);
			RegisterType<EnumerableWrapper>(InteropAccessMode.NoReflectionAllowed);
			RegisterType<JsonNull>(InteropAccessMode.Reflection);
			DefaultAccessMode = InteropAccessMode.LazyOptimized;
		}

		public static IUserDataDescriptor RegisterType<T>(InteropAccessMode accessMode = InteropAccessMode.Default, string friendlyName = null)
		{
			return TypeDescriptorRegistry.RegisterType_Impl(typeof(T), accessMode, friendlyName, null);
		}

		public static IUserDataDescriptor RegisterType(Type type, InteropAccessMode accessMode = InteropAccessMode.Default, string friendlyName = null)
		{
			return TypeDescriptorRegistry.RegisterType_Impl(type, accessMode, friendlyName, null);
		}

		public static IUserDataDescriptor RegisterProxyType(IProxyFactory proxyFactory, InteropAccessMode accessMode = InteropAccessMode.Default, string friendlyName = null)
		{
			return TypeDescriptorRegistry.RegisterProxyType_Impl(proxyFactory, accessMode, friendlyName);
		}

		public static IUserDataDescriptor RegisterProxyType<TProxy, TTarget>(Func<TTarget, TProxy> wrapDelegate, InteropAccessMode accessMode = InteropAccessMode.Default, string friendlyName = null) where TProxy : class where TTarget : class
		{
			return RegisterProxyType(new DelegateProxyFactory<TProxy, TTarget>(wrapDelegate), accessMode, friendlyName);
		}

		public static IUserDataDescriptor RegisterType<T>(IUserDataDescriptor customDescriptor)
		{
			return TypeDescriptorRegistry.RegisterType_Impl(typeof(T), InteropAccessMode.Default, null, customDescriptor);
		}

		public static IUserDataDescriptor RegisterType(Type type, IUserDataDescriptor customDescriptor)
		{
			return TypeDescriptorRegistry.RegisterType_Impl(type, InteropAccessMode.Default, null, customDescriptor);
		}

		public static IUserDataDescriptor RegisterType(IUserDataDescriptor customDescriptor)
		{
			return TypeDescriptorRegistry.RegisterType_Impl(customDescriptor.Type, InteropAccessMode.Default, null, customDescriptor);
		}

		public static void RegisterAssembly(Assembly asm = null, bool includeExtensionTypes = false)
		{
			if (asm == null)
			{
				asm = Assembly.GetCallingAssembly();
			}
			TypeDescriptorRegistry.RegisterAssembly(asm, includeExtensionTypes);
		}

		public static bool IsTypeRegistered(Type t)
		{
			return TypeDescriptorRegistry.IsTypeRegistered(t);
		}

		public static bool IsTypeRegistered<T>()
		{
			return TypeDescriptorRegistry.IsTypeRegistered(typeof(T));
		}

		public static void UnregisterType<T>()
		{
			TypeDescriptorRegistry.UnregisterType(typeof(T));
		}

		public static void UnregisterType(Type t)
		{
			TypeDescriptorRegistry.UnregisterType(t);
		}

		public static DynValue Create(object o, IUserDataDescriptor descr)
		{
			return DynValue.NewUserData(new UserData
			{
				Descriptor = descr,
				Object = o
			});
		}

		public static DynValue Create(object o)
		{
			IUserDataDescriptor descriptorForObject = GetDescriptorForObject(o);
			if (descriptorForObject == null)
			{
				if (o is Type)
				{
					return CreateStatic((Type)o);
				}
				return null;
			}
			return Create(o, descriptorForObject);
		}

		public static DynValue CreateStatic(IUserDataDescriptor descr)
		{
			if (descr == null)
			{
				return null;
			}
			return DynValue.NewUserData(new UserData
			{
				Descriptor = descr,
				Object = null
			});
		}

		public static DynValue CreateStatic(Type t)
		{
			return CreateStatic(GetDescriptorForType(t, searchInterfaces: false));
		}

		public static DynValue CreateStatic<T>()
		{
			return CreateStatic(GetDescriptorForType(typeof(T), searchInterfaces: false));
		}

		public static void RegisterExtensionType(Type type, InteropAccessMode mode = InteropAccessMode.Default)
		{
			ExtensionMethodsRegistry.RegisterExtensionType(type, mode);
		}

		public static List<IOverloadableMemberDescriptor> GetExtensionMethodsByNameAndType(string name, Type extendedType)
		{
			return ExtensionMethodsRegistry.GetExtensionMethodsByNameAndType(name, extendedType);
		}

		public static int GetExtensionMethodsChangeVersion()
		{
			return ExtensionMethodsRegistry.GetExtensionMethodsChangeVersion();
		}

		public static IUserDataDescriptor GetDescriptorForType<T>(bool searchInterfaces)
		{
			return TypeDescriptorRegistry.GetDescriptorForType(typeof(T), searchInterfaces);
		}

		public static IUserDataDescriptor GetDescriptorForType(Type type, bool searchInterfaces)
		{
			return TypeDescriptorRegistry.GetDescriptorForType(type, searchInterfaces);
		}

		public static IUserDataDescriptor GetDescriptorForObject(object o)
		{
			return TypeDescriptorRegistry.GetDescriptorForType(o.GetType(), searchInterfaces: true);
		}

		public static Table GetDescriptionOfRegisteredTypes(bool useHistoricalData = false)
		{
			DynValue dynValue = DynValue.NewPrimeTable();
			foreach (KeyValuePair<Type, IUserDataDescriptor> item in useHistoricalData ? TypeDescriptorRegistry.RegisteredTypesHistory : TypeDescriptorRegistry.RegisteredTypes)
			{
				if (item.Value is IWireableDescriptor wireableDescriptor)
				{
					DynValue dynValue2 = DynValue.NewPrimeTable();
					dynValue.Table.Set(item.Key.FullName, dynValue2);
					wireableDescriptor.PrepareForWiring(dynValue2.Table);
				}
			}
			return dynValue.Table;
		}

		public static IEnumerable<Type> GetRegisteredTypes(bool useHistoricalData = false)
		{
			return (useHistoricalData ? TypeDescriptorRegistry.RegisteredTypesHistory : TypeDescriptorRegistry.RegisteredTypes).Select((KeyValuePair<Type, IUserDataDescriptor> p) => p.Value.Type);
		}
	}
	public static class WellKnownSymbols
	{
		public const string VARARGS = "...";

		public const string ENV = "_ENV";
	}
	public class YieldRequest
	{
		public DynValue[] ReturnValues;

		public bool Forced { get; set; }
	}
	[Serializable]
	public class ScriptRuntimeException : InterpreterException
	{
		public ScriptRuntimeException(Exception ex)
			: base(ex)
		{
		}

		public ScriptRuntimeException(ScriptRuntimeException ex)
			: base(ex, ex.DecoratedMessage)
		{
			base.DecoratedMessage = Message;
			base.DoNotDecorateMessage = true;
		}

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

		public ScriptRuntimeException(string format, params object[] args)
			: base(format, args)
		{
		}

		public static ScriptRuntimeException ArithmeticOnNonNumber(DynValue l, DynValue r = null)
		{
			if (l.Type != DataType.Number && l.Type != DataType.String)
			{
				return new ScriptRuntimeException("attempt to perform arithmetic on a {0} value", l.Type.ToLuaTypeString());
			}
			if (r != null && r.Type != DataType.Number && r.Type != DataType.String)
			{
				return new ScriptRuntimeException("attempt to perform arithmetic on a {0} value", r.Type.ToLuaTypeString());
			}
			if (l.Type == DataType.String || (r != null && r.Type == DataType.String))
			{
				return new ScriptRuntimeException("attempt to perform arithmetic on a string value");
			}
			throw new InternalErrorException("ArithmeticOnNonNumber - both are numbers");
		}

		public static ScriptRuntimeException ConcatOnNonString(DynValue l, DynValue r)
		{
			if (l.Type != DataType.Number && l.Type != DataType.String)
			{
				return new ScriptRuntimeException("attempt to concatenate a {0} value", l.Type.ToLuaTypeString());
			}
			if (r != null && r.Type != DataType.Number && r.Type != DataType.String)
			{
				return new ScriptRuntimeException("attempt to concatenate a {0} value", r.Type.ToLuaTypeString());
			}
			throw new InternalErrorException("ConcatOnNonString - both are numbers/strings");
		}

		public static ScriptRuntimeException LenOnInvalidType(DynValue r)
		{
			return new ScriptRuntimeException("attempt to get length of a {0} value", r.Type.ToLuaTypeString());
		}

		public static ScriptRuntimeException CompareInvalidType(DynValue l, DynValue r)
		{
			if (l.Type.ToLuaTypeString() == r.Type.ToLuaTypeString())
			{
				return new ScriptRuntimeException("attempt to compare two {0} values", l.Type.ToLuaTypeString());
			}
			return new ScriptRuntimeException("attempt to compare {0} with {1}", l.Type.ToLuaTypeString(), r.Type.ToLuaTypeString());
		}

		public static ScriptRuntimeException BadArgument(int argNum, string funcName, string message)
		{
			return new ScriptRuntimeException("bad argument #{0} to '{1}' ({2})", argNum + 1, funcName, message);
		}

		public static ScriptRuntimeException BadArgumentUserData(int argNum, string funcName, Type expected, object got, bool allowNil)
		{
			return new ScriptRuntimeException("bad argument #{0} to '{1}' (userdata<{2}>{3} expected, got {4})", argNum + 1, funcName, expected.Name, allowNil ? "nil or " : "", (got != null) ? ("userdata<" + got.GetType().Name + ">") : "null");
		}

		public static ScriptRuntimeException BadArgument(int argNum, string funcName, DataType expected, DataType got, bool allowNil)
		{
			return BadArgument(argNum, funcName, expected.ToErrorTypeString(), got.ToErrorTypeString(), allowNil);
		}

		public static ScriptRuntimeException BadArgument(int argNum, string funcName, string expected, string got, bool allowNil)
		{
			return new ScriptRuntimeException("bad argument #{0} to '{1}' ({2}{3} expected, got {4})", argNum + 1, funcName, allowNil ? "nil or " : "", expected, got);
		}

		public static ScriptRuntimeException BadArgumentNoValue(int argNum, string funcName, DataType expected)
		{
			return new ScriptRuntimeException("bad argument #{0} to '{1}' ({2} expected, got no value)", argNum + 1, funcName, expected.ToErrorTypeString());
		}

		public static ScriptRuntimeException BadArgumentIndexOutOfRange(string funcName, int argNum)
		{
			return new ScriptRuntimeException("bad argument #{0} to '{1}' (index out of range)", argNum + 1, funcName);
		}

		public static ScriptRuntimeException BadArgumentNoNegativeNumbers(int argNum, string funcName)
		{
			return new ScriptRuntimeException("bad argument #{0} to '{1}' (not a non-negative number in proper range)", argNum + 1, funcName);
		}

		public static ScriptRuntimeException BadArgumentValueExpected(int argNum, string funcName)
		{
			return new ScriptRuntimeException("bad argument #{0} to '{1}' (value expected)", argNum + 1, funcName);
		}

		public static ScriptRuntimeException IndexType(DynValue obj)
		{
			return new ScriptRuntimeException("attempt to index a {0} value", obj.Type.ToLuaTypeString());
		}

		public static ScriptRuntimeException LoopInIndex()
		{
			return new ScriptRuntimeException("loop in gettable");
		}

		public static ScriptRuntimeException LoopInNewIndex()
		{
			return new ScriptRuntimeException("loop in settable");
		}

		public static ScriptRuntimeException LoopInCall()
		{
			return new ScriptRuntimeException("loop in call");
		}

		public static ScriptRuntimeException TableIndexIsNil()
		{
			return new ScriptRuntimeException("table index is nil");
		}

		public static ScriptRuntimeException TableIndexIsNaN()
		{
			return new ScriptRuntimeException("table index is NaN");
		}

		public static ScriptRuntimeException ConvertToNumberFailed(int stage)
		{
			return stage switch
			{
				1 => new ScriptRuntimeException("'for' initial value must be a number"), 
				2 => new ScriptRuntimeException("'for' step must be a number"), 
				3 => new ScriptRuntimeException("'for' limit must be a number"), 
				_ => new ScriptRuntimeException("value must be a number"), 
			};
		}

		public static ScriptRuntimeException ConvertObjectFailed(object obj)
		{
			return new ScriptRuntimeException("cannot convert clr type {0}", obj.GetType());
		}

		public static ScriptRuntimeException ConvertObjectFailed(DataType t)
		{
			return new ScriptRuntimeException("cannot convert a {0} to a clr type", t.ToString().ToLowerInvariant());
		}

		public static ScriptRuntimeException ConvertObjectFailed(DataType t, Type t2)
		{
			return new ScriptRuntimeException("cannot convert a {0} to a clr type {1}", t.ToString().ToLowerInvariant(), t2.FullName);
		}

		public static ScriptRuntimeException UserDataArgumentTypeMismatch(DataType t, Type clrType)
		{
			return new ScriptRuntimeException("cannot find a conversion from a MoonSharp {0} to a clr {1}", t.ToString().ToLowerInvariant(), clrType.FullName);
		}

		public static ScriptRuntimeException UserDataMissingField(string typename, string fieldname)
		{
			return new ScriptRuntimeException("cannot access field {0} of userdata<{1}>", fieldname, typename);
		}

		public static ScriptRuntimeException CannotResumeNotSuspended(CoroutineState state)
		{
			if (state == CoroutineState.Dead)
			{
				return new ScriptRuntimeException("cannot resume dead coroutine");
			}
			return new ScriptRuntimeException("cannot resume non-suspended coroutine");
		}

		public static ScriptRuntimeException CannotYield()
		{
			return new ScriptRuntimeException("attempt to yield across a CLR-call boundary");
		}

		public static ScriptRuntimeException CannotYieldMain()
		{
			return new ScriptRuntimeException("attempt to yield from outside a coroutine");
		}

		public static ScriptRuntimeException AttemptToCallNonFunc(DataType type, string debugText = null)
		{
			string text = type.ToErrorTypeString();
			if (debugText != null)
			{
				return new ScriptRuntimeException("attempt to call a {0} value near '{1}'", text, debugText);
			}
			return new ScriptRuntimeException("attempt to call a {0} value", text);
		}

		public static ScriptRuntimeException AccessInstanceMemberOnStatics(IMemberDescriptor desc)
		{
			return new ScriptRuntimeException("attempt to access instance member {0} from a static userdata", desc.Name);
		}

		public static ScriptRuntimeException AccessInstanceMemberOnStatics(IUserDataDescriptor typeDescr, IMemberDescriptor desc)
		{
			return new ScriptRuntimeException("attempt to access instance member {0}.{1} from a static userdata", typeDescr.Name, desc.Name);
		}

		public override void Rethrow()
		{
			if (Script.GlobalOptions.RethrowExceptionNested)
			{
				throw new ScriptRuntimeException(this);
			}
		}
	}
	[Serializable]
	public class InternalErrorException : InterpreterException
	{
		public InternalErrorException(string message)
			: base(message)
		{
		}

		public InternalErrorException(string format, params object[] args)
			: base(format, args)
		{
		}
	}
	[Serializable]
	public class InterpreterException : Exception
	{
		public int InstructionPtr { get; set; }

		public IList<WatchItem> CallStack { get; set; }

		public string DecoratedMessage { get; set; }

		public bool DoNotDecorateMessage { get; set; }

		public InterpreterException(Exception ex, string message)
			: base(message, ex)
		{
		}

		public InterpreterException(Exception ex)
			: base(ex.Message, ex)
		{
		}

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

		public InterpreterException(string format, params object[] args)
			: base(string.Format(format, args))
		{
		}

		public void DecorateMessage(Script script, SourceRef sref, int ip = -1)
		{
			if (string.IsNullOrEmpty(DecoratedMessage))
			{
				if (DoNotDecorateMessage)
				{
					DecoratedMessage = Message;
				}
				else if (sref != null)
				{
					DecoratedMessage = $"{sref.FormatLocation(script)}: {Message}";
				}
				else
				{
					DecoratedMessage = $"bytecode:{ip}: {Message}";
				}
			}
		}

		public virtual void Rethrow()
		{
		}
	}
	[Serializable]
	public class SyntaxErrorException : InterpreterException
	{
		public Token Token { get; set; }

		public bool IsPrematureStreamTermination { get; set; }

		public SyntaxErrorException(Token t, string format, params object[] args)
			: base(format, args)
		{
			Token = t;
		}

		public SyntaxErrorException(Token t, string message)
			: base(message)
		{
			Token = t;
		}

		public SyntaxErrorException(Script script, SourceRef sref, string format, params object[] args)
			: base(format, args)
		{
			DecorateMessage(script, sref);
		}

		public SyntaxErrorException(Script script, SourceRef sref, string message)
			: base(message)
		{
			DecorateMessage(script, sref);
		}

		public SyntaxErrorException(SyntaxErrorException syntaxErrorException)
			: base(syntaxErrorException, syntaxErrorException.DecoratedMessage)
		{
			Token = syntaxErrorException.Token;
			base.DecoratedMessage = Message;
		}

		public void DecorateMessage(Script script)
		{
			if (Token != null)
			{
				DecorateMessage(script, Token.GetSourceRef(isStepStop: false));
			}
		}

		public override void Rethrow()
		{
			if (Script.GlobalOptions.RethrowExceptionNested)
			{
				throw new SyntaxErrorException(this);
			}
		}
	}
	public class CallbackArguments
	{
		public IList<DynValue> m_Args;

		public int m_Count;

		public bool m_LastIsTuple;

		public int Count => m_Count;

		public bool IsMethodCall { get; set; }

		public DynValue this[int index] => RawGet(index, translateVoids: true) ?? DynValue.Void;

		public CallbackArguments(IList<DynValue> args, bool isMethodCall)
		{
			m_Args = args;
			if (m_Args.Count > 0)
			{
				DynValue dynValue = m_Args[m_Args.Count - 1];
				if (dynValue.Type == DataType.Tuple)
				{
					m_Count = dynValue.Tuple.Length - 1 + m_Args.Count;
					m_LastIsTuple = true;
				}
				else if (dynValue.Type == DataType.Void)
				{
					m_Count = m_Args.Count - 1;
				}
				else
				{
					m_Count = m_Args.Count;
				}
			}
			else
			{
				m_Count = 0;
			}
			IsMethodCall = isMethodCall;
		}

		public DynValue RawGet(int index, bool translateVoids)
		{
			if (index >= m_Count)
			{
				return null;
			}
			DynValue dynValue = ((m_LastIsTuple && index >= m_Args.Count - 1) ? m_Args[m_Args.Count - 1].Tuple[index - (m_Args.Count - 1)] : m_Args[index]);
			if (dynValue.Type == DataType.Tuple)
			{
				dynValue = ((dynValue.Tuple.Length == 0) ? DynValue.Nil : dynValue.Tuple[0]);
			}
			if (translateVoids && dynValue.Type == DataType.Void)
			{
				dynValue = DynValue.Nil;
			}
			return dynValue;
		}

		public DynValue[] GetArray(int skip = 0)
		{
			if (skip >= m_Count)
			{
				return new DynValue[0];
			}
			DynValue[] array = new DynValue[m_Count - skip];
			for (int i = skip; i < m_Count; i++)
			{
				array[i - skip] = this[i];
			}
			return array;
		}

		public DynValue AsType(int argNum, string funcName, DataType type, bool allowNil = false)
		{
			return this[argNum].CheckType(funcName, type, argNum, allowNil ? (TypeValidationFlags.AllowNil | TypeValidationFlags.AutoConvert) : TypeValidationFlags.AutoConvert);
		}

		public T AsUserData<T>(int argNum, string funcName, bool allowNil = false)
		{
			return this[argNum].CheckUserDataType<T>(funcName, argNum, allowNil ? TypeValidationFlags.AllowNil : TypeValidationFlags.None);
		}

		public int AsInt(int argNum, string funcName)
		{
			return (int)AsType(argNum, funcName, DataType.Number).Number;
		}

		public long AsLong(int argNum, string funcName)
		{
			return (long)AsType(argNum, funcName, DataType.Number).Number;
		}

		public string AsStringUsingMeta(ScriptExecutionContext executionContext, int argNum, string funcName)
		{
			if (this[argNum].Type == DataType.Table && this[argNum].Table.MetaTable != null && this[argNum].Table.MetaTable.RawGet("__tostring") != null)
			{
				DynValue dynValue = executionContext.GetScript().Call(this[argNum].Table.MetaTable.RawGet("__tostring"), this[argNum]);
				if (dynValue.Type != DataType.String)
				{
					throw new ScriptRuntimeException("'tostring' must return a string to '{0}'", funcName);
				}
				return dynValue.ToPrintString();
			}
			return this[argNum].ToPrintString();
		}

		public CallbackArguments SkipMethodCall()
		{
			if (IsMethodCall)
			{
				return new CallbackArguments(new Slice<DynValue>(m_Args, 1, m_Args.Count - 1, reversed: false), isMethodCall: false);
			}
			return this;
		}
	}
	public class Closure : RefIdObject, IScriptPrivateResource
	{
		public enum UpvaluesType
		{
			None,
			Environment,
			Closure
		}

		public static ClosureContext emptyClosure = new ClosureContext();

		public int EntryPointByteCodeLocation { get; set; }

		public Script OwnerScript { get; set; }

		public ClosureContext ClosureContext { get; set; }

		public Closure(Script script, int idx, SymbolRef[] symbols, IEnumerable<DynValue> resolvedLocals)
		{
			OwnerScript = script;
			EntryPointByteCodeLocation = idx;
			if (symbols.Length != 0)
			{
				ClosureContext = new ClosureContext(symbols, resolvedLocals);
			}
			else
			{
				ClosureContext = emptyClosure;
			}
		}

		public DynValue Call()
		{
			return OwnerScript.Call(this);
		}

		public DynValue Call(params object[] args)
		{
			return OwnerScript.Call(this, args);
		}

		public DynValue Call(params DynValue[] args)
		{
			return OwnerScript.Call(this, args);
		}

		public ScriptFunctionDelegate GetDelegate()
		{
			return (object[] args) => Call(args).ToObject();
		}

		public ScriptFunctionDelegate<T> GetDelegate<T>()
		{
			return (object[] args) => Call(args).ToObject<T>();
		}

		public int GetUpvaluesCount()
		{
			return ClosureContext.Count;
		}

		public string GetUpvalueName(int idx)
		{
			return ClosureContext.Symbols[idx];
		}

		public DynValue GetUpvalue(int idx)
		{
			return ClosureContext[idx];
		}

		public UpvaluesType GetUpvaluesType()
		{
			switch (GetUpvaluesCount())
			{
			case 0:
				return UpvaluesType.None;
			case 1:
				if (GetUpvalueName(0) == "_ENV")
				{
					return UpvaluesType.Environment;
				}
				break;
			}
			return UpvaluesType.Closure;
		}
	}
	public sealed class CallbackFunction : RefIdObject
	{
		public static InteropAccessMode m_DefaultAccessMode = InteropAccessMode.LazyOptimized;

		public string Name { get; set; }

		public Func<ScriptExecutionContext, CallbackArguments, DynValue> ClrCallback { get; set; }

		public static InteropAccessMode DefaultAccessMode
		{
			get
			{
				return m_DefaultAccessMode;
			}
			set
			{
				if (value == InteropAccessMode.Default || value == InteropAccessMode.HideMembers || value == InteropAccessMode.BackgroundOptimized)
				{
					throw new ArgumentException("DefaultAccessMode");
				}
				m_DefaultAccessMode = value;
			}
		}

		public object AdditionalData { get; set; }

		public CallbackFunction(Func<ScriptExecutionContext, CallbackArguments, DynValue> callBack, string name = null)
		{
			ClrCallback = callBack;
			Name = name;
		}

		public DynValue Invoke(ScriptExecutionContext executionContext, IList<DynValue> args, bool isMethodCall = false)
		{
			if (isMethodCall)
			{
				switch (executionContext.GetScript().Options.ColonOperatorClrCallbackBehaviour)
				{
				case ColonOperatorBehaviour.TreatAsColon:
					isMethodCall = false;
					break;
				case ColonOperatorBehaviour.TreatAsDotOnUserData:
					isMethodCall = args.Count > 0 && args[0].Type == DataType.UserData;
					break;
				}
			}
			return ClrCallback(executionContext, new CallbackArguments(args, isMethodCall));
		}

		public static CallbackFunction FromDelegate(Script script, Delegate del, InteropAccessMode accessMode = InteropAccessMode.Default)
		{
			if (accessMode == InteropAccessMode.Default)
			{
				accessMode = m_DefaultAccessMode;
			}
			return new MethodMemberDescriptor(del.Method, accessMode).GetCallbackFunction(script, del.Target);
		}

		public static CallbackFunction FromMethodInfo(Script script, MethodInfo mi, object obj = null, InteropAccessMode accessMode = InteropAccessMode.Default)
		{
			if (accessMode == InteropAccessMode.Default)
			{
				accessMode = m_DefaultAccessMode;
			}
			return new MethodMemberDescriptor(mi, accessMode).GetCallbackFunction(script, obj);
		}

		public static bool CheckCallbackSignature(MethodInfo mi, bool requirePublicVisibility)
		{
			ParameterInfo[] parameters = mi.GetParameters();
			if (parameters.Length == 2 && parameters[0].ParameterType == typeof(ScriptExecutionContext) && parameters[1].ParameterType == typeof(CallbackArguments) && mi.ReturnType == typeof(DynValue))
			{
				if (!requirePublicVisibility)
				{
					return mi.IsPublic;
				}
				return true;
			}
			return false;
		}
	}
	public sealed class DynValue
	{
		public static int s_RefIDCounter;

		public int m_RefID = ++s_RefIDCounter;

		public int m_HashCode = -1;

		public bool m_ReadOnly;

		public double m_Number;

		public object m_Object;

		public DataType m_Type;

		public int ReferenceID => m_RefID;

		public DataType Type => m_Type;

		public Closure Function => m_Object as Closure;

		public double Number => m_Number;

		public DynValue[] Tuple => m_Object as DynValue[];

		public Coroutine Coroutine => m_Object as Coroutine;

		public Table Table => m_Object as Table;

		public bool Boolean => Number != 0.0;

		public string String => m_Object as string;

		public CallbackFunction Callback => m_Object as CallbackFunction;

		public TailCallData TailCallData => m_Object as TailCallData;

		public YieldRequest YieldRequest => m_Object as YieldRequest;

		public UserData UserData => m_Object as UserData;

		public bool ReadOnly => m_ReadOnly;

		public static DynValue Void { get; set; }

		public static DynValue Nil { get; set; }

		public static DynValue True { get; set; }

		public static DynValue False { get; set; }

		public static DynValue NewNil()
		{
			return new DynValue();
		}

		public static DynValue NewBoolean(bool v)
		{
			return new DynValue
			{
				m_Number = (v ? 1 : 0),
				m_Type = DataType.Boolean
			};
		}

		public static DynValue NewNumber(double num)
		{
			return new DynValue
			{
				m_Number = num,
				m_Type = DataType.Number,
				m_HashCode = -1
			};
		}

		public static DynValue NewString(string str)
		{
			return new DynValue
			{
				m_Object = str,
				m_Type = DataType.String
			};
		}

		public static DynValue NewString(StringBuilder sb)
		{
			return new DynValue
			{
				m_Object = sb.ToString(),
				m_Type = DataType.String
			};
		}

		public static DynValue NewString(string format, params object[] args)
		{
			return new DynValue
			{
				m_Object = string.Format(format, args),
				m_Type = DataType.String
			};
		}

		public static DynValue NewCoroutine(Coroutine coroutine)
		{
			return new DynValue
			{
				m_Object = coroutine,
				m_Type = DataType.Thread
			};
		}

		public static DynValue NewClosure(Closure function)
		{
			return new DynValue
			{
				m_Object = function,
				m_Type = DataType.Function
			};
		}

		public static DynValue NewCallback(Func<ScriptExecutionContext, CallbackArguments, DynValue> callBack, string name = null)
		{
			return new DynValue
			{
				m_Object = new CallbackFunction(callBack, name),
				m_Type = DataType.ClrFunction
			};
		}

		public static DynValue NewCallback(CallbackFunction function)
		{
			return new DynValue
			{
				m_Object = function,
				m_Type = DataType.ClrFunction
			};
		}

		public static DynValue NewTable(Table table)
		{
			return new DynValue
			{
				m_Object = table,
				m_Type = DataType.Table
			};
		}

		public static DynValue NewPrimeTable()
		{
			return NewTable(new Table(null));
		}

		public static DynValue NewTable(Script script)
		{
			return NewTable(new Table(script));
		}

		public static DynValue NewTable(Script script, params DynValue[] arrayValues)
		{
			return NewTable(new Table(script, arrayValues));
		}

		public static DynValue NewTailCallReq(DynValue tailFn, params DynValue[] args)
		{
			return new DynValue
			{
				m_Object = new TailCallData
				{
					Args = args,
					Function = tailFn
				},
				m_Type = DataType.TailCallRequest
			};
		}

		public static DynValue NewTailCallReq(TailCallData tailCallData)
		{
			return new DynValue
			{
				m_Object = tailCallData,
				m_Type = DataType.TailCallRequest
			};
		}

		public static DynValue NewYieldReq(DynValue[] args)
		{
			return new DynValue
			{
				m_Object = new YieldRequest
				{
					ReturnValues = args
				},
				m_Type = DataType.YieldRequest
			};
		}

		public static DynValue NewForcedYieldReq()
		{
			return new DynValue
			{
				m_Object = new YieldRequest
				{
					Forced = true
				},
				m_Type = DataType.YieldRequest
			};
		}

		public static DynValue NewTuple(params DynValue[] values)
		{
			if (values.Length == 0)
			{
				return NewNil();
			}
			if (values.Length == 1)
			{
				return values[0];
			}
			return new DynValue
			{
				m_Object = values,
				m_Type = DataType.Tuple
			};
		}

		public static DynValue NewTupleNested(params DynValue[] values)
		{
			if (!values.Any((DynValue v) => v.Type == DataType.Tuple))
			{
				return NewTuple(values);
			}
			if (values.Length == 1)
			{
				return values[0];
			}
			List<DynValue> list = new List<DynValue>();
			foreach (DynValue dynValue in values)
			{
				if (dynValue.Type == DataType.Tuple)
				{
					list.AddRange(dynValue.Tuple);
				}
				else
				{
					list.Add(dynValue);
				}
			}
			return new DynValue
			{
				m_Object = list.ToArray(),
				m_Type = DataType.Tuple
			};
		}

		public static DynValue NewUserData(UserData userData)
		{
			return new DynValue
			{
				m_Object = userData,
				m_Type = DataType.UserData
			};
		}

		public DynValue AsReadOnly()
		{
			if (ReadOnly)
			{
				return this;
			}
			return Clone(readOnly: true);
		}

		public DynValue Clone()
		{
			return Clone(ReadOnly);
		}

		public DynValue Clone(bool readOnly)
		{
			return new DynValue
			{
				m_Object = m_Object,
				m_Number = m_Number,
				m_HashCode = m_HashCode,
				m_Type = m_Type,
				m_ReadOnly = readOnly
			};
		}

		public DynValue CloneAsWritable()
		{
			return Clone(readOnly: false);
		}

		static DynValue()
		{
			Nil = new DynValue
			{
				m_Type = DataType.Nil
			}.AsReadOnly();
			Void = new DynValue
			{
				m_Type = DataType.Void
			}.AsReadOnly();
			True = NewBoolean(v: true).AsReadOnly();
			False = NewBoolean(v: false).AsReadOnly();
		}

		public string ToPrintString()
		{
			if (m_Object != null && m_Object is RefIdObject)
			{
				RefIdObject refIdObject = (RefIdObject)m_Object;
				string typeString = Type.ToLuaTypeString();
				if (m_Object is UserData)
				{
					UserData userData = (UserData)m_Object;
					string text = userData.Descriptor.AsString(userData.Object);
					if (text != null)
					{
						return text;
					}
				}
				return refIdObject.FormatTypeString(typeString);
			}
			return Type switch
			{
				DataType.String => String, 
				DataType.Tuple => string.Join("\t", Tuple.Select((DynValue t) => t.ToPrintString()).ToArray()), 
				DataType.TailCallRequest => "(TailCallRequest -- INTERNAL!)", 
				DataType.YieldRequest => "(YieldRequest -- INTERNAL!)", 
				_ => ToString(), 
			};
		}

		public string ToDebugPrintString()
		{
			if (m_Object != null && m_Object is RefIdObject)
			{
				RefIdObject refIdObject = (RefIdObject)m_Object;
				string typeString = Type.ToLuaTypeString();
				if (m_Object is UserData)
				{
					UserData userData = (UserData)m_Object;
					string text = userData.Descriptor.AsString(userData.Object);
					if (text != null)
					{
						return text;
					}
				}
				return refIdObject.FormatTypeString(typeString);
			}
			return Type switch
			{
				DataType.Tuple => string.Join("\t", Tuple.Select((DynValue t) => t.ToPrintString()).ToArray()), 
				DataType.TailCallRequest => "(TailCallRequest)", 
				DataType.YieldRequest => "(YieldRequest)", 
				_ => ToString(), 
			};
		}

		public override string ToString()
		{
			return Type switch
			{
				DataType.Void => "void", 
				DataType.Nil => "nil", 
				DataType.Boolean => Boolean.ToString().ToLower(), 
				DataType.Number => Number.ToString(CultureInfo.InvariantCulture), 
				DataType.String => "\"" + String + "\"", 
				DataType.Function => $"(Function {Function.EntryPointByteCodeLocation:X8})", 
				DataType.ClrFunction => string.Format("(Function CLR)", Function), 
				DataType.Table => "(Table)", 
				DataType.Tuple => string.Join(", ", Tuple.Select((DynValue t) => t.ToString()).ToArray()), 
				DataType.TailCallRequest => "Tail:(" + string.Join(", ", Tuple.Select((DynValue t) => t.ToString()).ToArray()) + ")", 
				DataType.UserData => "(UserData)", 
				DataType.Thread => $"(Coroutine {Coroutine.ReferenceID:X8})", 
				_ => "(???)", 
			};
		}

		public override int GetHashCode()
		{
			if (m_HashCode != -1)
			{
				return m_HashCode;
			}
			int num = (int)Type << 27;
			switch (Type)
			{
			case DataType.Nil:
			case DataType.Void:
				m_HashCode = 0;
				break;
			case DataType.Boolean:
				m_HashCode = (Boolean ? 1 : 2);
				break;
			case DataType.Number:
				m_HashCode = num ^ Number.GetHashCode();
				break;
			case DataType.String:
				m_HashCode = num ^ String.GetHashCode();
				break;
			case DataType.Function:
				m_HashCode = num ^ Function.GetHashCode();
				break;
			case DataType.ClrFunction:
				m_HashCode = num ^ Callback.GetHashCode();
				break;
			case DataType.Table:
				m_HashCode = num ^ Table.GetHashCode();
				break;
			case DataType.Tuple:
			case DataType.TailCallRequest:
				m_HashCode = num ^ Tuple.GetHashCode();
				break;
			default:
				m_HashCode = 999;
				break;
			}
			return m_HashCode;
		}

		public override bool Equals(object obj)
		{
			if (!(obj is DynValue dynValue))
			{
				return false;
			}
			if ((dynValue.Type == DataType.Nil && Type == DataType.Void) || (dynValue.Type == DataType.Void && Type == DataType.Nil))
			{
				return true;
			}
			if (dynValue.Type != Type)
			{
				return false;
			}
			switch (Type)
			{
			case DataType.Nil:
			case DataType.Void:
				return true;
			case DataType.Boolean:
				return Boolean == dynValue.Boolean;
			case DataType.Number:
				return Number == dynValue.Number;
			case DataType.String:
				return String == dynValue.String;
			case DataType.Function:
				return Function == dynValue.Function;
			case DataType.ClrFunction:
				return Callback == dynValue.Callback;
			case DataType.Table:
				return Table == dynValue.Table;
			case DataType.Tuple:
			case DataType.TailCallRequest:
				return Tuple == dynValue.Tuple;
			case DataType.Thread:
				return Coroutine == dynValue.Coroutine;
			case DataType.UserData:
			{
				UserData userData = UserData;
				UserData userData2 = dynValue.UserData;
				if (userData == null || userData2 == null)
				{
					return false;
				}
				if (userData.Descriptor != userData2.Descriptor)
				{
					return false;
				}
				if (userData.Object == null && userData2.Object == null)
				{
					return true;
				}
				if (userData.Object != null && userData2.Object != null)
				{
					return userData.Object.Equals(userData2.Object);
				}
				return false;
			}
			default:
				return this == dynValue;
			}
		}

		public string CastToString()
		{
			DynValue dynValue = ToScalar();
			if (dynValue.Type == DataType.Number)
			{
				return dynValue.Number.ToString();
			}
			if (dynValue.Type == DataType.String)
			{
				return dynValue.String;
			}
			return null;
		}

		public double? CastToNumber()
		{
			DynValue dynValue = ToScalar();
			if (dynValue.Type == DataType.Number)
			{
				return dynValue.Number;
			}
			if (dynValue.Type == DataType.String && double.TryParse(dynValue.String, NumberStyles.Any, CultureInfo.InvariantCulture, out var result))
			{
				return result;
			}
			return null;
		}

		public bool CastToBool()
		{
			DynValue dynValue = ToScalar();
			if (dynValue.Type == DataType.Boolean)
			{
				return dynValue.Boolean;
			}
			if (dynValue.Type != 0)
			{
				return dynValue.Type != DataType.Void;
			}
			return false;
		}

		public IScriptPrivateResource GetAsPrivateResource()
		{
			return m_Object as IScriptPrivateResource;
		}

		public DynValue ToScalar()
		{
			if (Type != DataType.Tuple)
			{
				return this;
			}
			if (Tuple.Length == 0)
			{
				return Void;
			}
			return Tuple[0].ToScalar();
		}

		public void Assign(DynValue value)
		{
			if (ReadOnly)
			{
				throw new ScriptRuntimeException("Assigning on r-value");
			}
			m_Number = value.m_Number;
			m_Object = value.m_Object;
			m_Type = value.Type;
			m_HashCode = -1;
		}

		public DynValue GetLength()
		{
			if (Type == DataType.Table)
			{
				return NewNumber(Table.Length);
			}
			if (Type == DataType.String)
			{
				return NewNumber(String.Length);
			}
			throw new ScriptRuntimeException("Can't get length of type {0}", Type);
		}

		public bool IsNil()
		{
			if (Type != 0)
			{
				return Type == DataType.Void;
			}
			return true;
		}

		public bool IsNotNil()
		{
			if (Type != 0)
			{
				return Type != DataType.Void;
			}
			return false;
		}

		public bool IsVoid()
		{
			return Type == DataType.Void;
		}

		public bool IsNotVoid()
		{
			return Type != DataType.Void;
		}

		public bool IsNilOrNan()
		{
			if (Type != 0 && Type != DataType.Void)
			{
				if (Type == DataType.Number)
				{
					return double.IsNaN(Number);
				}
				return false;
			}
			return true;
		}

		public void AssignNumber(double num)
		{
			if (ReadOnly)
			{
				throw new InternalErrorException(null, "Writing on r-value");
			}
			if (Type != DataType.Number)
			{
				throw new InternalErrorException("Can't assign number to type {0}", Type);
			}
			m_Number = num;
		}

		public static DynValue FromObject(Script script, object obj)
		{
			return ClrToScriptConversions.ObjectToDynValue(script, obj);
		}

		public object ToObject()
		{
			return ScriptToClrConversions.DynValueToObject(this);
		}

		public object ToObject(Type desiredType)
		{
			return ScriptToClrConversions.DynValueToObjectOfType(this, desiredType, null, isOptional: false);
		}

		public T ToObject<T>()
		{
			return (T)ToObject(typeof(T));
		}

		public dynamic ToDynamic()
		{
			return ScriptToClrConversions.DynValueToObject(this);
		}

		public DynValue CheckType(string funcName, DataType desiredType, int argNum = -1, TypeValidationFlags flags = TypeValidationFlags.AutoConvert)
		{
			if (Type == desiredType)
			{
				return this;
			}
			bool flag = (flags & TypeValidationFlags.AllowNil) != 0;
			if (flag && IsNil())
			{
				return this;
			}
			if ((flags & TypeValidationFlags.AutoConvert) != 0)
			{
				switch (desiredType)
				{
				case DataType.Boolean:
					return NewBoolean(CastToBool());
				case DataType.Number:
				{
					double? num = CastToNumber();
					if (num.HasValue)
					{
						return NewNumber(num.Value);
					}
					break;
				}
				}
				if (desiredType == DataType.String)
				{
					string text = CastToString();
					if (text != null)
					{
						return NewString(text);
					}
				}
			}
			if (IsVoid())
			{
				throw ScriptRuntimeException.BadArgumentNoValue(argNum, funcName, desiredType);
			}
			throw ScriptRuntimeException.BadArgument(argNum, funcName, desiredType, Type, flag);
		}

		public T CheckUserDataType<T>(string funcName, int argNum = -1, TypeValidationFlags flags = TypeValidationFlags.AutoConvert)
		{
			DynValue dynValue = CheckType(funcName, DataType.UserData, argNum, flags);
			bool allowNil = (flags & TypeValidationFlags.AllowNil) != 0;
			if (dynValue.IsNil())
			{
				return default(T);
			}
			object @object = dynValue.UserData.Object;
			if (@object != null && @object is T)
			{
				return (T)@object;
			}
			throw ScriptRuntimeException.BadArgumentUserData(argNum, funcName, typeof(T), @object, allowNil);
		}
	}
	public struct TablePair
	{
		public static TablePair s_NilNode = new TablePair(DynValue.Nil, DynValue.Nil);

		public DynValue key;

		public DynValue value;

		public DynValue Key
		{
			get
			{
				return key;
			}
			set
			{
				Key = key;
			}
		}

		public DynValue Value
		{
			get
			{
				return value;
			}
			set
			{
				if (key.IsNotNil())
				{
					Value = value;
				}
			}
		}

		public static TablePair Nil => s_NilNode;

		public TablePair(DynValue key, DynValue val)
		{
			this.key = key;
			value = val;
		}
	}
	public class ScriptExecutionContext : IScriptPrivateResource
	{
		public Processor m_Processor;

		public CallbackFunction m_Callback;

		public bool IsDynamicExecution { get; set; }

		public SourceRef CallingLocation { get; set; }

		public object AdditionalData
		{
			get
			{
				if (m_Callback == null)
				{
					return null;
				}
				return m_Callback.AdditionalData;
			}
			set
			{
				if (m_Callback == null)
				{
					throw new InvalidOperationException("Cannot set additional data on a context which has no callback");
				}
				m_Callback.AdditionalData = value;
			}
		}

		public Table CurrentGlobalEnv
		{
			get
			{
				DynValue dynValue = EvaluateSymbolByName("_ENV");
				if (dynValue == null || dynValue.Type != DataType.Table)
				{
					return null;
				}
				return dynValue.Table;
			}
		}

		public Script OwnerScript => GetScript();

		public ScriptExecutionContext(Processor p, CallbackFunction callBackFunction, SourceRef sourceRef, bool isDynamic = false)
		{
			IsDynamicExecution = isDynamic;
			m_Processor = p;
			m_Callback = callBackFunction;
			CallingLocation = sourceRef;
		}

		public Table GetMetatable(DynValue value)
		{
			return m_Processor.GetMetatable(value);
		}

		public DynValue GetMetamethod(DynValue value, string metamethod)
		{
			return m_Processor.GetMetamethod(value, metamethod);
		}

		public DynValue GetMetamethodTailCall(DynValue value, string metamethod, params DynValue[] args)
		{
			DynValue metamethod2 = GetMetamethod(value, metamethod);
			if (metamethod2 == null)
			{
				return null;
			}
			return DynValue.NewTailCallReq(metamethod2, args);
		}

		public DynValue GetBinaryMetamethod(DynValue op1, DynValue op2, string eventName)
		{
			return m_Processor.GetBinaryMetamethod(op1, op2, eventName);
		}

		public Script GetScript()
		{
			return m_Processor.GetScript();
		}

		public Coroutine GetCallingCoroutine()
		{
			return m_Processor.AssociatedCoroutine;
		}

		public DynValue EmulateClassicCall(CallbackArguments args, string functionName, Func<LuaState, int> callback)
		{
			LuaState luaState = new LuaState(this, args, functionName);
			int retvals = callback(luaState);
			return luaState.GetReturnValue(retvals);
		}

		public DynValue Call(DynValue func, params DynValue[] args)
		{
			if (func.Type == DataType.Function)
			{
				return GetScript().Call(func, args);
			}
			if (func.Type == DataType.ClrFunction)
			{
				DynValue dynValue;
				while (true)
				{
					dynValue = func.Callback.Invoke(this, args);
					if (dynValue.Type == DataType.YieldRequest)
					{
						throw ScriptRuntimeException.CannotYield();
					}
					if (dynValue.Type != DataType.TailCallRequest)
					{
						break;
					}
					TailCallData tailCallData = dynValue.TailCallData;
					if (tailCallData.Continuation != null || tailCallData.ErrorHandler != null)
					{
						throw new ScriptRuntimeException("the function passed cannot be called directly. wrap in a script function instead.");
					}
					args = tailCallData.Args;
					func = tailCallData.Function;
				}
				return dynValue;
			}
			int num = 10;
			while (num > 0)
			{
				DynValue metamethod = GetMetamethod(func, "__call");
				if (metamethod == null && metamethod.IsNil())
				{
					throw ScriptRuntimeException.AttemptToCallNonFunc(func.Type);
				}
				func = metamethod;
				if (func.Type == DataType.Function || func.Type == DataType.ClrFunction)
				{
					return Call(func, args);
				}
			}
			throw ScriptRuntimeException.LoopInCall();
		}

		public DynValue EvaluateSymbol(SymbolRef symref)
		{
			if (symref == null)
			{
				return DynValue.Nil;
			}
			return m_Processor.GetGenericSymbol(symref);
		}

		public DynValue EvaluateSymbolByName(string symbol)
		{
			return EvaluateSymbol(FindSymbolByName(symbol));
		}

		public SymbolRef FindSymbolByName(string symbol)
		{
			return m_Processor.FindSymbolByName(symbol);
		}

		public void PerformMessageDecorationBeforeUnwind(DynValue messageHandler, ScriptRuntimeException exception)
		{
			if (messageHandler != null)
			{
				exception.DecoratedMessage = m_Processor.PerformMessageDecorationBeforeUnwind(messageHandler, exception.Message, CallingLocation);
			}
			else
			{
				exception.DecoratedMessage = exception.Message;
			}
		}
	}
	public enum CoroutineState
	{
		Main,
		NotStarted,
		Suspended,
		ForceSuspended,
		Running,
		Dead
	}
	public static class LinqHelpers
	{
		public static IEnumerable<T> Convert<T>(this IEnumerable<DynValue> enumerable, DataType type)
		{
			return from v in enumerable
				where v.Type == type
				select v.ToObject<T>();
		}

		public static IEnumerable<DynValue> OfDataType(this IEnumerable<DynValue> enumerable, DataType type)
		{
			return enumerable.Where((DynValue v) => v.Type == type);
		}

		public static IEnumerable<object> AsObjects(this IEnumerable<DynValue> enumerable)
		{
			return enumerable.Select((DynValue v) => v.ToObject());
		}

		public static IEnumerable<T> AsObjects<T>(this IEnumerable<DynValue> enumerable)
		{
			return enumerable.Select((DynValue v) => v.ToObject<T>());
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)]
	public sealed class MoonSharpUserDataAttribute : Attribute
	{
		public InteropAccessMode AccessMode { get; set; }

		public MoonSharpUserDataAttribute()
		{
			AccessMode = InteropAccessMode.Default;
		}
	}
	public class AutoDescribingUserDataDescriptor : IUserDataDescriptor
	{
		public string m_FriendlyName;

		public Type m_Type;

		public string Name => m_FriendlyName;

		public Type Type => m_Type;

		public AutoDescribingUserDataDescriptor(Type type, string friendlyName)
		{
			m_FriendlyName = friendlyName;
			m_Type = type;
		}

		public DynValue Index(Script script, object obj, DynValue index, bool isDirectIndexing)
		{
			if (obj is IUserDataType userDataType)
			{
				return userDataType.Index(script, index, isDirectIndexing);
			}
			return null;
		}

		public bool SetIndex(Script script, object obj, DynValue index, DynValue value, bool isDirectIndexing)
		{
			if (obj is IUserDataType userDataType)
			{
				return userDataType.SetIndex(script, index, value, isDirectIndexing);
			}
			return false;
		}

		public string AsString(object obj)
		{
			return obj?.ToString();
		}

		public DynValue MetaIndex(Script script, object obj, string metaname)
		{
			if (obj is IUserDataType userDataType)
			{
				return userDataType.MetaIndex(script, metaname);
			}
			return null;
		}

		public bool IsTypeCompatible(Type type, object obj)
		{
			return Framework.Do.IsInstanceOfType(type, obj);
		}
	}
	public enum InteropAccessMode
	{
		Reflection,
		LazyOptimized,
		Preoptimized,
		BackgroundOptimized,
		Hardwired,
		HideMembers,
		NoReflectionAllowed,
		Default
	}
	public enum SymbolRefType
	{
		Local,
		Upvalue,
		Global,
		DefaultEnv
	}
	public class SymbolRef
	{
		public static SymbolRef s_DefaultEnv = new SymbolRef
		{
			i_Type = SymbolRefType.DefaultEnv
		};

		public SymbolRefType i_Type;

		public SymbolRef i_Env;

		public int i_Index;

		public string i_Name;

		public SymbolRefType Type => i_Type;

		public int Index => i_Index;

		public string Name => i_Name;

		public SymbolRef Environment => i_Env;

		public static SymbolRef DefaultEnv => s_DefaultEnv;

		public static SymbolRef Global(string name, SymbolRef envSymbol)
		{
			return new SymbolRef
			{
				i_Index = -1,
				i_Type = SymbolRefType.Global,
				i_Env = envSymbol,
				i_Name = name
			};
		}

		public static SymbolRef Local(string name, int index)
		{
			return new SymbolRef
			{
				i_Index = index,
				i_Type = SymbolRefType.Local,
				i_Name = name
			};
		}

		public static SymbolRef Upvalue(string name, int index)
		{
			return new SymbolRef
			{
				i_Index = index,
				i_Type = SymbolRefType.Upvalue,
				i_Name = name
			};
		}

		public override string ToString()
		{
			if (i_Type == SymbolRefType.DefaultEnv)
			{
				return "(default _ENV)";
			}
			if (i_Type == SymbolRefType.Global)
			{
				return string.Format("{2} : {0} / {1}", i_Type, i_Env, i_Name);
			}
			return string.Format("{2} : {0}[{1}]", i_Type, i_Index, i_Name);
		}

		public void WriteBinary(BinaryWriter bw)
		{
			bw.Write((byte)i_Type);
			bw.Write(i_Index);
			bw.Write(i_Name);
		}

		public static SymbolRef ReadBinary(BinaryReader br)
		{
			return new SymbolRef
			{
				i_Type = (SymbolRefType)br.ReadByte(),
				i_Index = br.ReadInt32(),
				i_Name = br.ReadString()
			};
		}

		public void WriteBinaryEnv(BinaryWriter bw, Dictionary<SymbolRef, int> symbolMap)
		{
			if (i_Env != null)
			{
				bw.Write(symbolMap[i_Env]);
			}
			else
			{
				bw.Write(-1);
			}
		}

		public void ReadBinaryEnv(BinaryReader br, SymbolRef[] symbolRefs)
		{
			int num = br.ReadInt32();
			if (num >= 0)
			{
				i_Env = symbolRefs[num];
			}
		}
	}
	public enum DataType
	{
		Nil,
		Void,
		Boolean,
		Number,
		String,
		Function,
		Table,
		Tuple,
		UserData,
		Thread,
		ClrFunction,
		TailCallRequest,
		YieldRequest
	}
	public static class LuaTypeExtensions
	{
		public const DataType MaxMetaTypes = DataType.Table;

		public const DataType MaxConvertibleTypes = DataType.ClrFunction;

		public static bool CanHaveTypeMetatables(this DataType type)
		{
			return type < DataType.Table;
		}

		public static string ToErrorTypeString(this DataType type)
		{
			return type switch
			{
				DataType.Void => "no value", 
				DataType.Nil => "nil", 
				DataType.Boolean => "boolean", 
				DataType.Number => "number", 
				DataType.String => "string", 
				DataType.Function => "function", 
				DataType.ClrFunction => "function", 
				DataType.Table => "table", 
				DataType.UserData => "userdata", 
				DataType.Thread => "coroutine", 
				_ => $"internal<{type.ToLuaDebuggerString()}>", 
			};
		}

		public static string ToLuaDebuggerString(this DataType type)
		{
			return type.ToString().ToLowerInvariant();
		}

		public static string ToLuaTypeString(this DataType type)
		{
			switch (type)
			{
			case DataType.Nil:
			case DataType.Void:
				return "nil";
			case DataType.Boolean:
				return "boolean";
			case DataType.Number:
				return "number";
			case DataType.String:
				return "string";
			case DataType.Function:
				return "function";
			case DataType.ClrFunction:
				return "function";
			case DataType.Table:
				return "table";
			case DataType.UserData:
				return "userdata";
			case DataType.Thread:
				return "thread";
			default:
				throw new ScriptRuntimeException("Unexpected LuaType {0}", type);
			}
		}
	}
	public enum ColonOperatorBehaviour
	{
		TreatAsDot,
		TreatAsDotOnUserData,
		TreatAsColon
	}
	[AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
	public sealed class MoonSharpModuleConstantAttribute : Attribute
	{
		public string Name { get; set; }
	}
	public static class NamespaceDoc
	{
	}
	public class Script : IScriptPrivateResource
	{
		public const string VERSION = "2.0.0.0";

		public const string LUA_VERSION = "5.2";

		public Processor m_MainProcessor;

		public ByteCode m_ByteCode;

		public List<SourceCode> m_Sources = new List<SourceCode>();

		public Table m_GlobalTable;

		public IDebugger m_Debugger;

		public Table[] m_TypeMetatables = new Table[6];

		public static ScriptOptions DefaultOptions { get; set; }

		public ScriptOptions Options { get; set; }

		public static ScriptGlobalOptions GlobalOptions { get; set; }

		public PerformanceStatistics PerformanceStats { get; set; }

		public Table Globals => m_GlobalTable;

		public bool DebuggerEnabled
		{
			get
			{
				return m_MainProcessor.DebuggerEnabled;
			}
			set
			{
				m_MainProcessor.DebuggerEnabled = value;
			}
		}

		public int SourceCodeCount => m_Sources.Count;

		public Table Registry { get; set; }

		Script IScriptPrivateResource.OwnerScript => this;

		static Script()
		{
			GlobalOptions = new ScriptGlobalOptions();
			DefaultOptions = new ScriptOptions
			{
				DebugPrint = delegate(string s)
				{
					GlobalOptions.Platform.DefaultPrint(s);
				},
				DebugInput = (string s) => GlobalOptions.Platform.DefaultInput(s),
				CheckThreadAccess = true,
				ScriptLoader = PlatformAutoDetector.GetDefaultScriptLoader(),
				TailCallOptimizationThreshold = 65536
			};
		}

		public Script()
			: this(CoreModules.Preset_Default)
		{
		}

		public Script(CoreModules coreModules)
		{
			Options = new ScriptOptions(DefaultOptions);
			PerformanceStats = new PerformanceStatistics();
			Registry = new Table(this);
			m_ByteCode = new ByteCode(this);
			m_MainProcessor = new Processor(this, m_GlobalTable, m_ByteCode);
			m_GlobalTable = new Table(this).RegisterCoreModules(coreModules);
		}

		public DynValue LoadFunction(string code, Table globalTable = null, string funcFriendlyName = null)
		{
			this.CheckScriptOwnership(globalTable);
			SourceCode sourceCode = new SourceCode($"libfunc_{funcFriendlyName ?? m_Sources.Count.ToString()}", code, m_Sources.Count, this);
			m_Sources.Add(sourceCode);
			int address = Loader_Fast.LoadFunction(this, sourceCode, m_ByteCode, globalTable != null || m_GlobalTable != null);
			SignalSourceCodeChange(sourceCode);
			SignalByteCodeChange();
			return MakeClosure(address, globalTable ?? m_GlobalTable);
		}

		public void SignalByteCodeChange()
		{
			if (m_Debugger != null)
			{
				m_Debugger.SetByteCode(m_ByteCode.Code.Select((Instruction s) => s.ToString()).ToArray());
			}
		}

		public void SignalSourceCodeChange(SourceCode source)
		{
			if (m_Debugger != null)
			{
				m_Debugger.SetSourceCode(source);
			}
		}

		public DynValue LoadString(string code, Table globalTable = null, string codeFriendlyName = null)
		{
			this.CheckScriptOwnership(globalTable);
			if (code.StartsWith("MoonSharp_dump_b64::"))
			{
				code = code.Substring("MoonSharp_dump_b64::".Length);
				using MemoryStream stream = new MemoryStream(Convert.FromBase64String(code));
				return LoadStream(stream, globalTable, codeFriendlyName);
			}
			string text = string.Format("{0}", codeFriendlyName ?? ("chunk_" + m_Sources.Count));
			SourceCode sourceCode = new SourceCode(codeFriendlyName ?? text, code, m_Sources.Count, this);
			m_Sources.Add(sourceCode);
			int address = Loader_Fast.LoadChunk(this, sourceCode, m_ByteCode);
			SignalSourceCodeChange(sourceCode);
			SignalByteCodeChange();
			return MakeClosure(address, globalTable ?? m_GlobalTable);
		}

		public DynValue LoadStream(Stream stream, Table globalTable = null, string codeFriendlyName = null)
		{
			this.CheckScriptOwnership(globalTable);
			Stream stream2 = new UndisposableStream(stream);
			if (!Processor.IsDumpStream(stream2))
			{
				using (StreamReader streamReader = new StreamReader(stream2))
				{
					string code = streamReader.ReadToEnd();
					return LoadString(code, globalTable, codeFriendlyName);
				}
			}
			string text = string.Format("{0}", codeFriendlyName ?? ("dump_" + m_Sources.Count));
			SourceCode sourceCode = new SourceCode(codeFriendlyName ?? text, $"-- This script was decoded from a binary dump - dump_{m_Sources.Count}", m_Sources.Count, this);
			m_Sources.Add(sourceCode);
			bool hasUpvalues;
			int address = m_MainProcessor.Undump(stream2, m_Sources.Count - 1, globalTable ?? m_GlobalTable, out hasUpvalues);
			SignalSourceCodeChange(sourceCode);
			SignalByteCodeChange();
			if (hasUpvalues)
			{
				return MakeClosure(address, globalTable ?? m_GlobalTable);
			}
			return MakeClosure(address);
		}

		public void Dump(DynValue function, Stream stream)
		{
			this.CheckScriptOwnership(function);
			if (function.Type != DataType.Function)
			{
				throw new ArgumentException("function arg is not a function!");
			}
			if (!stream.CanWrite)
			{
				throw new ArgumentException("stream is readonly!");
			}
			Closure.UpvaluesType upvaluesType = function.Function.GetUpvaluesType();
			if (upvaluesType == Closure.UpvaluesType.Closure)
			{
				throw new ArgumentException("function arg has upvalues other than _ENV");
			}
			UndisposableStream stream2 = new UndisposableStream(stream);
			m_MainProcessor.Dump(stream2, function.Function.EntryPointByteCodeLocation, upvaluesType == Closure.UpvaluesType.Environment);
		}

		public DynValue LoadFile(string filename, Table globalContext = null, string friendlyFilename = null)
		{
			this.CheckScriptOwnership(globalContext);
			filename = Options.ScriptLoader.ResolveFileName(filename, globalContext ?? m_GlobalTable);
			object obj = Options.ScriptLoader.LoadFile(filename, globalContext ?? m_GlobalTable);
			if (obj is string)
			{
				return LoadString((string)obj, globalContext, friendlyFilename ?? filename);
			}
			if (obj is byte[])
			{
				using (MemoryStream stream = new MemoryStream((byte[])obj))
				{
					return LoadStream(stream, globalContext, friendlyFilename ?? filename);
				}
			}
			if (obj is Stream)
			{
				try
				{
					return LoadStream((Stream)obj, globalContext, friendlyFilename ?? filename);
				}
				finally
				{
					((Stream)obj).Dispose();
				}
			}
			if (obj == null)
			{
				throw new InvalidCastException("Unexpected null from IScriptLoader.LoadFile");
			}
			throw new InvalidCastException($"Unsupported return type from IScriptLoader.LoadFile : {obj.GetType()}");
		}

		public DynValue DoString(string code, Table globalContext = null, string codeFriendlyName = null)
		{
			DynValue function = LoadString(code, globalContext, codeFriendlyName);
			return Call(function);
		}

		public DynValue DoStream(Stream stream, Table globalContext = null, string codeFriendlyName = null)
		{
			DynValue function = LoadStream(stream, globalContext, codeFriendlyName);
			return Call(function);
		}

		public DynValue DoFile(string filename, Table globalContext = null, string codeFriendlyName = null)
		{
			DynValue function = LoadFile(filename, globalContext, codeFriendlyName);
			return Call(function);
		}

		public static DynValue RunFile(string filename)
		{
			return new Script().DoFile(filename);
		}

		public static DynValue RunString(string code)
		{
			return new Script().DoString(code);
		}

		public DynValue MakeClosure(int address, Table envTable = null)
		{
			this.CheckScriptOwnership(envTable);
			Closure function;
			if (envTable == null)
			{
				Instruction instruction = m_MainProcessor.FindMeta(ref address);
				function = ((instruction == null || instruction.NumVal2 != 0) ? new Closure(this, address, new SymbolRef[0], new DynValue[0]) : new Closure(this, address, new SymbolRef[1] { SymbolRef.Upvalue("_ENV", 0) }, new DynValue[1] { instruction.Value }));
			}
			else
			{
				SymbolRef[] symbols = new SymbolRef[1]
				{
					new SymbolRef
					{
						i_Env = null,
						i_Index = 0,
						i_Name = "_ENV",
						i_Type = SymbolRefType.DefaultEnv
					}
				};
				DynValue[] resolvedLocals = new DynValue[1] { DynValue.NewTable(envTable) };
				function = new Closure(this, address, symbols, resolvedLocals);
			}
			return DynValue.NewClosure(function);
		}

		public DynValue Call(DynValue function)
		{
			return Call(function, new DynValue[0]);
		}

		public DynValue Call(DynValue function, params DynValue[] args)
		{
			this.CheckScriptOwnership(function);
			this.CheckScriptOwnership(args);
			if (function.Type != DataType.Function && function.Type != DataType.ClrFunction)
			{
				DynValue metamethod = m_MainProcessor.GetMetamethod(function, "__call");
				if (metamethod == null)
				{
					throw new ArgumentException("function is not a function and has no __call metamethod.");
				}
				DynValue[] array = new DynValue[args.Length + 1];
				array[0] = function;
				for (int i = 0; i < args.Length; i++)
				{
					array[i + 1] = args[i];
				}
				function = metamethod;
				args = array;
			}
			else if (function.Type == DataType.ClrFunction)
			{
				return function.Callback.ClrCallback(CreateDynamicExecutionContext(function.Callback), new CallbackArguments(args, isMethodCall: false));
			}
			return m_MainProcessor.Call(function, args);
		}

		public DynValue Call(DynValue function, params object[] args)
		{
			DynValue[] array = new DynValue[args.Length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = DynValue.FromObject(this, args[i]);
			}
			return Call(function, array);
		}

		public DynValue Call(object function)
		{
			return Call(DynValue.FromObject(this, function));
		}

		public DynValue Call(object function, params object[] args)
		{
			return Call(DynValue.FromObject(this, function), args);
		}

		public DynValue CreateCoroutine(DynValue function)
		{
			this.CheckScriptOwnership(function);
			if (function.Type == DataType.Function)
			{
				return m_MainProcessor.Coroutine_Create(function.Function);
			}
			if (function.Type == DataType.ClrFunction)
			{
				return DynValue.NewCoroutine(new Coroutine(function.Callback));
			}
			throw new ArgumentException("function is not of DataType.Function or DataType.ClrFunction");
		}

		public DynValue CreateCoroutine(object function)
		{
			return CreateCoroutine(DynValue.FromObject(this, function));
		}

		public void AttachDebugger(IDebugger debugger)
		{
			DebuggerEnabled = true;
			m_Debugger = debugger;
			m_MainProcessor.AttachDebugger(debugger);
			foreach (SourceCode source in m_Sources)
			{
				SignalSourceCodeChange(source);
			}
			SignalByteCodeChange();
		}

		public SourceCode GetSourceCode(int sourceCodeID)
		{
			return m_Sources[sourceCodeID];
		}

		public DynValue RequireModule(string modname, Table globalContext = null)
		{
			this.CheckScriptOwnership(globalContext);
			Table globalContext2 = globalContext ?? m_GlobalTable;
			string text = Options.ScriptLoader.ResolveModuleName(modname, globalContext2);
			if (text == null)
			{
				throw new ScriptRuntimeException("module '{0}' not found", modname);
			}
			return LoadFile(text, globalContext, text);
		}

		public Table GetTypeMetatable(DataType type)
		{
			if (type >= DataType.Nil && (int)type < m_TypeMetatables.Length)
			{
				return m_TypeMetatables[(int)type];
			}
			return null;
		}

		public void SetTypeMetatable(DataType type, Table metatable)
		{
			this.CheckScriptOwnership(metatable);
			int num = (int)type;
			if (num >= 0 && num < m_TypeMetatables.Length)
			{
				m_TypeMetatables[num] = metatable;
				return;
			}
			throw new ArgumentException("Specified type not supported : " + type);
		}

		public static void WarmUp()
		{
			new Script(CoreModules.Basic).LoadString("return 1;");
		}

		public DynamicExpression CreateDynamicExpression(string code)
		{
			DynamicExprExpression expr = Loader_Fast.LoadDynamicExpr(this, new SourceCode("__dynamic", code, -1, this));
			return new DynamicExpression(this, code, expr);
		}

		public DynamicExpression CreateConstantDynamicExpression(string code, DynValue constant)
		{
			this.CheckScriptOwnership(constant);
			return new DynamicExpression(this, code, constant);
		}

		public ScriptExecutionContext CreateDynamicExecutionContext(CallbackFunction func = null)
		{
			return new ScriptExecutionContext(m_MainProcessor, func, null, isDynamic: true);
		}

		public static string GetBanner(string subproduct = null)
		{
			subproduct = ((subproduct != null) ? (subproduct + " ") : "");
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine(string.Format("MoonSharp {0}{1} [{2}]", subproduct, "2.0.0.0", GlobalOptions.Platform.GetPlatformName()));
			stringBuilder.AppendLine("Copyright (C) 2014-2016 Marco Mastropaolo");
			stringBuilder.AppendLine("http://www.moonsharp.org");
			return stringBuilder.ToString();
		}
	}
	public class Table : RefIdObject, IScriptPrivateResource
	{
		public readonly LinkedList<TablePair> m_Values;

		public readonly LinkedListIndex<DynValue, TablePair> m_ValueMap;

		public readonly LinkedListIndex<string, TablePair> m_StringMap;

		public readonly LinkedListIndex<int, TablePair> m_ArrayMap;

		public readonly Script m_Owner;

		public int m_InitArray;

		public int m_CachedLength = -1;

		public bool m_ContainsNilEntries;

		public Table m_MetaTable;

		public Script OwnerScript => m_Owner;

		public object this[params object[] keys]
		{
			get
			{
				return Get(keys).ToObject();
			}
			set
			{
				Set(keys, DynValue.FromObject(OwnerScript, value));
			}
		}

		public object this[object key]
		{
			get
			{
				return Get(key).ToObject();
			}
			set
			{
				Set(key, DynValue.FromObject(OwnerScript, value));
			}
		}

		public int Length
		{
			get
			{
				if (m_CachedLength < 0)
				{
					m_CachedLength = 0;
					for (int i = 1; m_ArrayMap.ContainsKey(i) && !m_ArrayMap.Find(i).Value.Value.IsNil(); i++)
					{
						m_CachedLength = i;
					}
				}
				return m_CachedLength;
			}
		}

		public Table MetaTable
		{
			get
			{
				return m_MetaTable;
			}
			set
			{
				this.CheckScriptOwnership(m_MetaTable);
				m_MetaTable = value;
			}
		}

		public IEnumerable<TablePair> Pairs => m_Values.Select((TablePair n) => new TablePair(n.Key, n.Value));

		public IEnumerable<DynValue> Keys => m_Values.Select((TablePair n) => n.Key);

		public IEnumerable<DynValue> Values => m_Values.Select((TablePair n) => n.Value);

		public Table(Script owner)
		{
			m_Values = new LinkedList<TablePair>();
			m_StringMap = new LinkedListIndex<string, TablePair>(m_Values);
			m_ArrayMap = new LinkedListIndex<int, TablePair>(m_Values);
			m_ValueMap = new LinkedListIndex<DynValue, TablePair>(m_Values);
			m_Owner = owner;
		}

		public Table(Script owner, params DynValue[] arrayValues)
			: this(owner)
		{
			for (int i = 0; i < arrayValues.Length; i++)
			{
				Set(DynValue.NewNumber(i + 1), arrayValues[i]);
			}
		}

		public void Clear()
		{
			m_Values.Clear();
			m_StringMap.Clear();
			m_ArrayMap.Clear();
			m_ValueMap.Clear();
			m_CachedLength = -1;
		}

		public int GetIntegralKey(double d)
		{
			int num = (int)d;
			if (d >= 1.0 && d == (double)num)
			{
				return num;
			}
			return -1;
		}

		public Table ResolveMultipleKeys(object[] keys, out object key)
		{
			Table table = this;
			key = ((keys.Length != 0) ? keys[0] : null);
			for (int i = 1; i < keys.Length; i++)
			{
				DynValue obj = table.RawGet(key) ?? throw new ScriptRuntimeException("Key '{0}' did not point to anything");
				if (obj.Type != DataType.Table)
				{
					throw new ScriptRuntimeException("Key '{0}' did not point to a table");
				}
				table = obj.Table;
				key = keys[i];
			}
			return table;
		}

		public void Append(DynValue value)
		{
			this.CheckScriptOwnership(value);
			PerformTableSet(m_ArrayMap, Length + 1, DynValue.NewNumber(Length + 1), value, isNumber: true, Length + 1);
		}

		public void PerformTableSet<T>(LinkedListIndex<T, TablePair> listIndex, T key, DynValue keyDynValue, DynValue value, bool isNumber, int appendKey)
		{
			TablePair tablePair = listIndex.Set(key, new TablePair(keyDynValue, value));
			if (m_ContainsNilEntries && value.IsNotNil() && (tablePair.Value == null || tablePair.Value.IsNil()))
			{
				CollectDeadKeys();
			}
			else if (value.IsNil())
			{
				m_ContainsNilEntries = true;
				if (isNumber)
				{
					m_CachedLength = -1;
				}
			}
			else
			{
				if (!isNumber || (tablePair.Value != null && !tablePair.Value.IsNilOrNan()))
				{
					return;
				}
				if (appendKey >= 0)
				{
					LinkedListNode<TablePair> linkedListNode = m_ArrayMap.Find(appendKey + 1);
					if (linkedListNode == null || linkedListNode.Value.Value == null || linkedListNode.Value.Value.IsNil())
					{
						m_CachedLength++;
					}
					else
					{
						m_CachedLength = -1;
					}
				}
				else
				{
					m_CachedLength = -1;
				}
			}
		}

		public void Set(string key, DynValue value)
		{
			if (key == null)
			{
				throw ScriptRuntimeException.TableIndexIsNil();
			}
			this.CheckScriptOwnership(value);
			PerformTableSet(m_StringMap, key, DynValue.NewString(key), value, isNumber: false, -1);
		}

		public void Set(int key, DynValue value)
		{
			this.CheckScriptOwnership(value);
			PerformTableSet(m_ArrayMap, key, DynValue.NewNumber(key), value, isNumber: true, -1);
		}

		public void Set(DynValue key, DynValue value)
		{
			if (key.IsNilOrNan())
			{
				if (key.IsNil())
				{
					throw ScriptRuntimeException.TableIndexIsNil();
				}
				throw ScriptRuntimeException.TableIndexIsNaN();
			}
			if (key.Type == DataType.String)
			{
				Set(key.String, value);
				return;
			}
			if (key.Type == DataType.Number)
			{
				int integralKey = GetIntegralKey(key.Number);
				if (integralKey > 0)
				{
					Set(integralKey, value);
					return;
				}
			}
			this.CheckScriptOwnership(key);
			this.CheckScriptOwnership(value);
			PerformTableSet(m_ValueMap, key, key, value, isNumber: false, -1);
		}

		public void Set(object key, DynValue value)
		{
			if (key == null)
			{
				throw ScriptRuntimeException.TableIndexIsNil();
			}
			if (key is string)
			{
				Set((string)key, value);
			}
			else if (key is int)
			{
				Set((int)key, value);
			}
			else
			{
				Set(DynValue.FromObject(OwnerScript, key), value);
			}
		}

		public void Set(object[] keys, DynValue value)
		{
			if (keys == null || keys.Length == 0)
			{
				throw ScriptRuntimeException.TableIndexIsNil();
			}
			ResolveMultipleKeys(keys, out var key).Set(key, value);
		}

		public DynValue Get(string key)
		{
			return RawGet(key) ?? DynValue.Nil;
		}

		public DynValue Get(int key)
		{
			return RawGet(key) ?? DynValue.Nil;
		}

		public DynValue Get(DynValue key)
		{
			return RawGet(key) ?? DynValue.Nil;
		}

		public DynValue Get(object key)
		{
			return RawGet(key) ?? DynValue.Nil;
		}

		public DynValue Get(params object[] keys)
		{
			return RawGet(keys) ?? DynValue.Nil;
		}

		public static DynValue RawGetValue(LinkedListNode<TablePair> linkedListNode)
		{
			return linkedListNode?.Value.Value;
		}

		public DynValue RawGet(string key)
		{
			return RawGetValue(m_StringMap.Find(key));
		}

		public DynValue RawGet(int key)
		{
			return RawGetValue(m_ArrayMap.Find(key));
		}

		public DynValue RawGet(DynValue key)
		{
			if (key.Type == DataType.String)
			{
				return RawGet(key.String);
			}
			if (key.Type == DataType.Number)
			{
				int integralKey = GetIntegralKey(key.Number);
				if (integralKey > 0)
				{
					return RawGet(integralKey);
				}
			}
			return RawGetValue(m_ValueMap.Find(key));
		}

		public DynValue RawGet(object key)
		{
			if (key == null)
			{
				return null;
			}
			if (key is string)
			{
				return RawGet((string)key);
			}
			if (key is int)
			{
				return RawGet((int)key);
			}
			return RawGet(DynValue.FromObject(OwnerScript, key));
		}

		public DynValue RawGet(params object[] keys)
		{
			if (keys == null || keys.Length == 0)
			{
				return null;
			}
			object key;
			return ResolveMultipleKeys(keys, out key).RawGet(key);
		}

		public bool PerformTableRemove<T>(LinkedListIndex<T, TablePair> listIndex, T key, bool isNumber)
		{
			bool num = listIndex.Remove(key);
			if (num && isNumber)
			{
				m_CachedLength = -1;
			}
			return num;
		}

		public bool Remove(string key)
		{
			return PerformTableRemove(m_StringMap, key, isNumber: false);
		}

		public bool Remove(int key)
		{
			return PerformTableRemove(m_ArrayMap, key, isNumber: true);
		}

		public bool Remove(DynValue key)
		{
			if (key.Type == DataType.String)
			{
				return Remove(key.String);
			}
			if (key.Type == DataType.Number)
			{
				int integralKey = GetIntegralKey(key.Number);
				if (integralKey > 0)
				{
					return Remove(integralKey);
				}
			}
			return PerformTableRemove(m_ValueMap, key, isNumber: false);
		}

		public bool Remove(object key)
		{
			if (key is string)
			{
				return Remove((string)key);
			}
			if (key is int)
			{
				return Remove((int)key);
			}
			return Remove(DynValue.FromObject(OwnerScript, key));
		}

		public bool Remove(params object[] keys)
		{
			if (keys == null || keys.Length == 0)
			{
				return false;
			}
			object key;
			return ResolveMultipleKeys(keys, out key).Remove(key);
		}

		public void CollectDeadKeys()
		{
			for (LinkedListNode<TablePair> linkedListNode = m_Values.First; linkedListNode != null; linkedListNode = linkedListNode.Next)
			{
				if (linkedListNode.Value.Value.IsNil())
				{
					Remove(linkedListNode.Value.Key);
				}
			}
			m_ContainsNilEntries = false;
			m_CachedLength = -1;
		}

		public TablePair? NextKey(DynValue v)
		{
			if (v.IsNil())
			{
				LinkedListNode<TablePair> first = m_Values.First;
				if (first == null)
				{
					return TablePair.Nil;
				}
				if (first.Value.Value.IsNil())
				{
					return NextKey(first.Value.Key);
				}
				return first.Value;
			}
			if (v.Type == DataType.String)
			{
				return GetNextOf(m_StringMap.Find(v.String));
			}
			if (v.Type == DataType.Number)
			{
				int integralKey = GetIntegralKey(v.Number);
				if (integralKey > 0)
				{
					return GetNextOf(m_ArrayMap.Find(integralKey));
				}
			}
			return GetNextOf(m_ValueMap.Find(v));
		}

		public TablePair? GetNextOf(LinkedListNode<TablePair> linkedListNode)
		{
			do
			{
				if (linkedListNode == null)
				{
					return null;
				}
				if (linkedListNode.Next == null)
				{
					return TablePair.Nil;
				}
				linkedListNode = linkedListNode.Next;
			}
			while (linkedListNode.Value.Value.IsNil());
			return linkedListNode.Value;
		}

		public void InitNextArrayKeys(DynValue val, bool lastpos)
		{
			if (val.Type == DataType.Tuple && lastpos)
			{
				DynValue[] tuple = val.Tuple;
				foreach (DynValue val2 in tuple)
				{
					InitNextArrayKeys(val2, lastpos: true);
				}
			}
			else
			{
				Set(++m_InitArray, val.ToScalar());
			}
		}
	}
	[Flags]
	public enum CoreModules
	{
		None = 0,
		Basic = 0x40,
		GlobalConsts = 1,
		TableIterators = 2,
		Metatables = 4,
		String = 8,
		LoadMethods = 0x10,
		Table = 0x20,
		ErrorHandling = 0x80,
		Math = 0x100,
		Coroutine = 0x200,
		Bit32 = 0x400,
		OS_Time = 0x800,
		OS_System = 0x1000,
		IO = 0x2000,
		Debug = 0x4000,
		Dynamic = 0x8000,
		Json = 0x10000,
		Preset_HardSandbox = 0x56B,
		Preset_SoftSandbox = 0x18FEF,
		Preset_Default = 0x1BFFF,
		Preset_Complete = 0x1FFFF
	}
	public static class CoreModules_ExtensionMethods
	{
		public static bool Has(this CoreModules val, CoreModules flag)
		{
			return (val & flag) == flag;
		}
	}
	public static class ModuleRegister
	{
		public static Table RegisterCoreModules(this Table table, CoreModules modules)
		{
			modules = Script.GlobalOptions.Platform.FilterSupportedCoreModules(modules);
			if (modules.Has(CoreModules.GlobalConsts))
			{
				table.RegisterConstants();
			}
			if (modules.Has(CoreModules.TableIterators))
			{
				table.RegisterModuleType<TableIteratorsModule>();
			}
			if (modules.Has(CoreModules.Basic))
			{
				table.RegisterModuleType<BasicModule>();
			}
			if (modules.Has(CoreModules.Metatables))
			{
				table.RegisterModuleType<MetaTableModule>();
			}
			if (modules.Has(CoreModules.String))
			{
				table.RegisterModuleType<StringModule>();
			}
			if (modules.Has(CoreModules.LoadMethods))
			{
				table.RegisterModuleType<LoadModule>();
			}
			if (modules.Has(CoreModules.Table))
			{
				table.RegisterModuleType<TableModule>();
			}
			if (modules.Has(CoreModules.Table))
			{
				table.RegisterModuleType<TableModule_Globals>();
			}
			if (modules.Has(CoreModules.ErrorHandling))
			{
				table.RegisterModuleType<ErrorHandlingModule>();
			}
			if (modules.Has(CoreModules.Math))
			{
				table.RegisterModuleType<MathModule>();
			}
			if (modules.Has(CoreModules.Coroutine))
			{
				table.RegisterModuleType<CoroutineModule>();
			}
			if (modules.Has(CoreModules.Bit32))
			{
				table.RegisterModuleType<Bit32Module>();
			}
			if (modules.Has(CoreModules.Dynamic))
			{
				table.RegisterModuleType<DynamicModule>();
			}
			if (modules.Has(CoreModules.OS_System))
			{
				table.RegisterModuleType<OsSystemModule>();
			}
			if (modules.Has(CoreModules.OS_Time))
			{
				table.RegisterModuleType<OsTimeModule>();
			}
			if (modules.Has(CoreModules.IO))
			{
				table.RegisterModuleType<IoModule>();
			}
			if (modules.Has(CoreModules.Debug))
			{
				table.RegisterModuleType<DebugModule>();
			}
			if (modules.Has(CoreModules.Json))
			{
				table.RegisterModuleType<JsonModule>();
			}
			return table;
		}

		public static Table RegisterConstants(this Table table)
		{
			DynValue dynValue = DynValue.NewTable(table.OwnerScript);
			Table table2 = dynValue.Table;
			table.Set("_G", DynValue.NewTable(table));
			table.Set("_VERSION", DynValue.NewString(string.Format("MoonSharp {0}", "2.0.0.0")));
			table.Set("_MOONSHARP", dynValue);
			table2.Set("version", DynValue.NewString("2.0.0.0"));
			table2.Set("luacompat", DynValue.NewString("5.2"));
			table2.Set("platform", DynValue.NewString(Script.GlobalOptions.Platform.GetPlatformName()));
			table2.Set("is_aot", DynValue.NewBoolean(Script.GlobalOptions.Platform.IsRunningOnAOT()));
			table2.Set("is_unity", DynValue.NewBoolean(PlatformAutoDetector.IsRunningOnUnity));
			table2.Set("is_mono", DynValue.NewBoolean(PlatformAutoDetector.IsRunningOnMono));
			table2.Set("is_clr4", DynValue.NewBoolean(PlatformAutoDetector.IsRunningOnClr4));
			table2.Set("is_pcl", DynValue.NewBoolean(PlatformAutoDetector.IsPortableFramework));
			table2.Set("banner", DynValue.NewString(Script.GetBanner()));
			return table;
		}

		public static Table RegisterModuleType(this Table gtable, Type t)
		{
			Table table = CreateModuleNamespace(gtable, t);
			foreach (MethodInfo item in from __mi in Framework.Do.GetMethods(t)
				where __mi.IsStatic
				select __mi)
			{
				if (item.GetCustomAttributes(typeof(MoonSharpModuleMethodAttribute), inherit: false).ToArray().Length != 0)
				{
					MoonSharpModuleMethodAttribute moonSharpModuleMethodAttribute = (MoonSharpModuleMethodAttribute)item.GetCustomAttributes(typeof(MoonSharpModuleMethodAttribute), inherit: false).First();
					if (!CallbackFunction.CheckCallbackSignature(item, requirePublicVisibility: true))
					{
						throw new ArgumentException($"Method {item.Name} does not have the right signature.");
					}
					Func<ScriptExecutionContext, CallbackArguments, DynValue> callBack = (Func<ScriptExecutionContext, CallbackArguments, DynValue>)Delegate.CreateDelegate(typeof(Func<ScriptExecutionContext, CallbackArguments, DynValue>), item);
					string text = ((!string.IsNullOrEmpty(moonSharpModuleMethodAttribute.Name)) ? moonSharpModuleMethodAttribute.Name : item.Name);
					table.Set(text, DynValue.NewCallback(callBack, text));
				}
				else if (item.Name == "MoonSharpInit")
				{
					object[] parameters = new object[2] { gtable, table };
					item.Invoke(null, parameters);
				}
			}
			foreach (FieldInfo item2 in from _mi in Framework.Do.GetFields(t)
				where _mi.IsStatic && _mi.GetCustomAttributes(typeof(MoonSharpModuleMethodAttribute), inherit: false).ToArray().Length != 0
				select _mi)
			{
				MoonSharpModuleMethodAttribute moonSharpModuleMethodAttribute2 = (MoonSharpModuleMethodAttribute)item2.GetCustomAttributes(typeof(MoonSharpModuleMethodAttribute), inherit: false).First();
				string name = ((!string.IsNullOrEmpty(moonSharpModuleMethodAttribute2.Name)) ? moonSharpModuleMethodAttribute2.Name : item2.Name);
				RegisterScriptField(item2, null, table, t, name);
			}
			foreach (FieldInfo item3 in from _mi in Framework.Do.GetFields(t)
				where _mi.IsStatic && _mi.GetCustomAttributes(typeof(MoonSharpModuleConstantAttribute), inherit: false).ToArray().Length != 0
				select _mi)
			{
				MoonSharpModuleConstantAttribute moonSharpModuleConstantAttribute = (MoonSharpModuleConstantAttribute)item3.GetCustomAttributes(typeof(MoonSharpModuleConstantAttribute), inherit: false).First();
				string name2 = ((!string.IsNullOrEmpty(moonSharpModuleConstantAttribute.Name)) ? moonSharpModuleConstantAttribute.Name : item3.Name);
				RegisterScriptFieldAsConst(item3, null, table, t, name2);
			}
			return gtable;
		}

		public static void RegisterScriptFieldAsConst(FieldInfo fi, object o, Table table, Type t, string name)
		{
			if (fi.FieldType == typeof(string))
			{
				string str = fi.GetValue(o) as string;
				table.Set(name, DynValue.NewString(str));
				return;
			}
			if (fi.FieldType == typeof(double))
			{
				double num = (double)fi.GetValue(o);
				table.Set(name, DynValue.NewNumber(num));
				return;
			}
			throw new ArgumentException($"Field {name} does not have the right type - it must be string or double.");
		}

		public static void RegisterScriptField(FieldInfo fi, object o, Table table, Type t, string name)
		{
			if (fi.FieldType != typeof(string))
			{
				throw new ArgumentException($"Field {name} does not have the right type - it must be string.");
			}
			string code = fi.GetValue(o) as string;
			DynValue value = table.OwnerScript.LoadFunction(code, table, name);
			table.Set(name, value);
		}

		public static Table CreateModuleNamespace(Table gtable, Type t)
		{
			MoonSharpModuleAttribute moonSharpModuleAttribute = (MoonSharpModuleAttribute)Framework.Do.GetCustomAttributes(t, typeof(MoonSharpModuleAttribute), inherit: false).First();
			if (string.IsNullOrEmpty(moonSharpModuleAttribute.Namespace))
			{
				return gtable;
			}
			Table table = null;
			DynValue dynValue = gtable.Get(moonSharpModuleAttribute.Namespace);
			if (dynValue.Type == DataType.Table)
			{
				table = dynValue.Table;
			}
			else
			{
				table = new Table(gtable.OwnerScript);
				gtable.Set(moonSharpModuleAttribute.Namespace, DynValue.NewTable(table));
			}
			DynValue dynValue2 = gtable.RawGet("package");
			if (dynValue2 == null || dynValue2.Type != DataType.Table)
			{
				gtable.Set("package", dynValue2 = DynValue.NewTable(gtable.OwnerScript));
			}
			DynValue dynValue3 = dynValue2.Table.RawGet("loaded");
			if (dynValue3 == null || dynValue3.Type != DataType.Table)
			{
				dynValue2.Table.Set("loaded", dynValue3 = DynValue.NewTable(gtable.OwnerScript));
			}
			dynValue3.Table.Set(moonSharpModuleAttribute.Namespace, DynValue.NewTable(table));
			return table;
		}

		public static Table RegisterModuleType<T>(this Table table)
		{
			return table.RegisterModuleType(typeof(T));
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
	public sealed class MoonSharpModuleMethodAttribute : Attribute
	{
		public string Name { get; set; }
	}
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	public sealed class MoonSharpModuleAttribute : Attribute
	{
		public string Namespace { get; set; }
	}
	public class ScriptGlobalOptions
	{
		public CustomConvertersCollection CustomConverters { get; set; }

		public IPlatformAccessor Platform { get; set; }

		public bool RethrowExceptionNested { get; set; }

		public ScriptGlobalOptions()
		{
			Platform = PlatformAutoDetector.GetDefaultPlatform();
			CustomConverters = new CustomConvertersCollection();
		}
	}
	public class ScriptOptions
	{
		public IScriptLoader ScriptLoader { get; set; }

		public Action<string> DebugPrint { get; set; }

		public Func<string, string> DebugInput { get; set; }

		public bool UseLuaErrorLocations { get; set; }

		public ColonOperatorBehaviour ColonOperatorClrCallbackBehaviour { get; set; }

		public Stream Stdin { get; set; }

		public Stream Stdout { get; set; }

		public Stream Stderr { get; set; }

		public int TailCallOptimizationThreshold { get; set; }

		public bool CheckThreadAccess { get; set; }

		public ScriptOptions()
		{
		}

		public ScriptOptions(ScriptOptions defaults)
		{
			DebugIn

mapMaker/MoonSharp.VsCodeDebugger.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using MoonSharp.Interpreter;
using MoonSharp.Interpreter.Compatibility;
using MoonSharp.Interpreter.Debugging;
using MoonSharp.Interpreter.Serialization.Json;
using MoonSharp.VsCodeDebugger.DebuggerLogic;
using MoonSharp.VsCodeDebugger.SDK;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("MoonSharp.VsCodeDebugger")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MoonSharp.VsCodeDebugger")]
[assembly: AssemblyCopyright("Copyright ©  2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.0,Profile=Client", FrameworkDisplayName = ".NET Framework 4 Client Profile")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace MoonSharp.VsCodeDebugger
{
	public class MoonSharpVsCodeDebugServer : IDisposable
	{
		private object m_Lock = new object();

		private List<AsyncDebugger> m_DebuggerList = new List<AsyncDebugger>();

		private AsyncDebugger m_Current;

		private ManualResetEvent m_StopEvent = new ManualResetEvent(initialState: false);

		private bool m_Started;

		private int m_Port;

		public int? CurrentId
		{
			get
			{
				lock (m_Lock)
				{
					return (m_Current != null) ? new int?(m_Current.Id) : null;
				}
			}
			set
			{
				lock (m_Lock)
				{
					if (!value.HasValue)
					{
						m_Current = null;
						return;
					}
					AsyncDebugger asyncDebugger = m_DebuggerList.FirstOrDefault((AsyncDebugger d) => d.Id == value);
					if (asyncDebugger == null)
					{
						throw new ArgumentException("Cannot find debugger with given Id.");
					}
					m_Current = asyncDebugger;
				}
			}
		}

		public Script Current
		{
			get
			{
				lock (m_Lock)
				{
					return (m_Current != null) ? m_Current.Script : null;
				}
			}
			set
			{
				lock (m_Lock)
				{
					if (value == null)
					{
						m_Current = null;
						return;
					}
					AsyncDebugger asyncDebugger = m_DebuggerList.FirstOrDefault((AsyncDebugger d) => d.Script == value);
					if (asyncDebugger == null)
					{
						throw new ArgumentException("Cannot find debugger with given script associated.");
					}
					m_Current = asyncDebugger;
				}
			}
		}

		public Action<string> Logger { get; set; }

		public MoonSharpVsCodeDebugServer(int port = 41912)
		{
			m_Port = port;
		}

		[Obsolete("Use the constructor taking only a port, and the 'Attach' method instead.")]
		public MoonSharpVsCodeDebugServer(Script script, int port, Func<SourceCode, string> sourceFinder = null)
		{
			m_Port = port;
			m_Current = new AsyncDebugger(script, sourceFinder ?? ((Func<SourceCode, string>)((SourceCode s) => s.Name)), "Default script");
			m_DebuggerList.Add(m_Current);
		}

		public void AttachToScript(Script script, string name, Func<SourceCode, string> sourceFinder = null)
		{
			lock (m_Lock)
			{
				if (m_DebuggerList.Any((AsyncDebugger d) => d.Script == script))
				{
					throw new ArgumentException("Script already attached to this debugger.");
				}
				AsyncDebugger asyncDebugger = new AsyncDebugger(script, sourceFinder ?? ((Func<SourceCode, string>)((SourceCode s) => s.Name)), name);
				script.AttachDebugger((IDebugger)(object)asyncDebugger);
				m_DebuggerList.Add(asyncDebugger);
				if (m_Current == null)
				{
					m_Current = asyncDebugger;
				}
			}
		}

		public IEnumerable<KeyValuePair<int, string>> GetAttachedDebuggersByIdAndName()
		{
			lock (m_Lock)
			{
				return (from d in m_DebuggerList
					orderby d.Id
					select new KeyValuePair<int, string>(d.Id, d.Name)).ToArray();
			}
		}

		public void Detach(Script script)
		{
			lock (m_Lock)
			{
				AsyncDebugger asyncDebugger = m_DebuggerList.FirstOrDefault((AsyncDebugger d) => d.Script == script);
				if (asyncDebugger == null)
				{
					throw new ArgumentException("Cannot detach script - not found.");
				}
				asyncDebugger.Client = null;
				m_DebuggerList.Remove(asyncDebugger);
				if (m_Current == asyncDebugger)
				{
					if (m_DebuggerList.Count > 0)
					{
						m_Current = m_DebuggerList[m_DebuggerList.Count - 1];
					}
					else
					{
						m_Current = null;
					}
				}
			}
		}

		[Obsolete("Use the Attach method instead.")]
		public IDebugger GetDebugger()
		{
			lock (m_Lock)
			{
				return (IDebugger)(object)m_Current;
			}
		}

		public void Dispose()
		{
			m_StopEvent.Set();
		}

		public MoonSharpVsCodeDebugServer Start()
		{
			lock (m_Lock)
			{
				if (m_Started)
				{
					throw new InvalidOperationException("Cannot start; server has already been started.");
				}
				m_StopEvent.Reset();
				TcpListener serverSocket = null;
				serverSocket = new TcpListener(IPAddress.Parse("127.0.0.1"), m_Port);
				serverSocket.Start();
				SpawnThread("VsCodeDebugServer_" + m_Port, delegate
				{
					ListenThread(serverSocket);
				});
				m_Started = true;
				return this;
			}
		}

		private void ListenThread(TcpListener serverSocket)
		{
			try
			{
				while (!m_StopEvent.WaitOne(0))
				{
					Socket clientSocket = serverSocket.AcceptSocket();
					if (clientSocket == null)
					{
						continue;
					}
					string sessionId = Guid.NewGuid().ToString("N");
					Log("[{0}] : Accepted connection from client {1}", sessionId, clientSocket.RemoteEndPoint);
					SpawnThread("VsCodeDebugSession_" + sessionId, delegate
					{
						using (NetworkStream stream = new NetworkStream(clientSocket))
						{
							try
							{
								RunSession(sessionId, stream);
							}
							catch (Exception ex2)
							{
								Log("[{0}] : Error : {1}", ex2.Message);
							}
						}
						clientSocket.Close();
						Log("[{0}] : Client connection closed", sessionId);
					});
				}
			}
			catch (Exception ex)
			{
				Log("Fatal error in listening thread : {0}", ex.Message);
			}
			finally
			{
				serverSocket?.Stop();
			}
		}

		private void RunSession(string sessionId, NetworkStream stream)
		{
			DebugSession debugSession = null;
			lock (m_Lock)
			{
				debugSession = ((m_Current == null) ? ((DebugSession)new EmptyDebugSession(this)) : ((DebugSession)new MoonSharpDebugSession(this, m_Current)));
			}
			debugSession.ProcessLoop(stream, stream);
		}

		private void Log(string format, params object[] args)
		{
			Action<string> logger = Logger;
			if (logger != null)
			{
				string obj = string.Format(format, args);
				logger(obj);
			}
		}

		private static void SpawnThread(string name, Action threadProc)
		{
			System.Threading.Thread thread = new System.Threading.Thread((ThreadStart)delegate
			{
				threadProc();
			});
			thread.IsBackground = true;
			thread.Name = name;
			thread.Start();
		}
	}
}
namespace MoonSharp.VsCodeDebugger.SDK
{
	public class Message
	{
		public int id { get; private set; }

		public string format { get; private set; }

		public object variables { get; private set; }

		public object showUser { get; private set; }

		public object sendTelemetry { get; private set; }

		public Message(int id, string format, object variables = null, bool user = true, bool telemetry = false)
		{
			this.id = id;
			this.format = format;
			this.variables = variables;
			showUser = user;
			sendTelemetry = telemetry;
		}
	}
	public class StackFrame
	{
		public int id { get; private set; }

		public Source source { get; private set; }

		public int line { get; private set; }

		public int column { get; private set; }

		public string name { get; private set; }

		public int? endLine { get; private set; }

		public int? endColumn { get; private set; }

		public StackFrame(int id, string name, Source source, int line, int column = 0, int? endLine = null, int? endColumn = null)
		{
			this.id = id;
			this.name = name;
			this.source = source;
			this.line = line;
			this.column = column;
			this.endLine = endLine;
			this.endColumn = endColumn;
		}
	}
	public class Scope
	{
		public string name { get; private set; }

		public int variablesReference { get; private set; }

		public bool expensive { get; private set; }

		public Scope(string name, int variablesReference, bool expensive = false)
		{
			this.name = name;
			this.variablesReference = variablesReference;
			this.expensive = expensive;
		}
	}
	public class Variable
	{
		public string name { get; private set; }

		public string value { get; private set; }

		public int variablesReference { get; private set; }

		public Variable(string name, string value, int variablesReference = 0)
		{
			this.name = name;
			this.value = value;
			this.variablesReference = variablesReference;
		}
	}
	public class Thread
	{
		public int id { get; private set; }

		public string name { get; private set; }

		public Thread(int id, string name)
		{
			this.id = id;
			if (name == null || name.Length == 0)
			{
				this.name = $"Thread #{id}";
			}
			else
			{
				this.name = name;
			}
		}
	}
	public class Source
	{
		public string name { get; private set; }

		public string path { get; private set; }

		public int sourceReference { get; private set; }

		public Source(string name, string path, int sourceReference = 0)
		{
			this.name = name;
			this.path = path;
			this.sourceReference = sourceReference;
		}

		public Source(string path, int sourceReference = 0)
		{
			name = Path.GetFileName(path);
			this.path = path;
			this.sourceReference = sourceReference;
		}
	}
	public class Breakpoint
	{
		public bool verified { get; private set; }

		public int line { get; private set; }

		public Breakpoint(bool verified, int line)
		{
			this.verified = verified;
			this.line = line;
		}
	}
	public class InitializedEvent : Event
	{
		public InitializedEvent()
			: base("initialized")
		{
		}
	}
	public class StoppedEvent : Event
	{
		public StoppedEvent(int tid, string reasn, string txt = null)
			: base("stopped", new
			{
				threadId = tid,
				reason = reasn,
				text = txt
			})
		{
		}
	}
	public class ExitedEvent : Event
	{
		public ExitedEvent(int exCode)
			: base("exited", new
			{
				exitCode = exCode
			})
		{
		}
	}
	public class TerminatedEvent : Event
	{
		public TerminatedEvent()
			: base("terminated")
		{
		}
	}
	public class ThreadEvent : Event
	{
		public ThreadEvent(string reasn, int tid)
			: base("thread", new
			{
				reason = reasn,
				threadId = tid
			})
		{
		}
	}
	public class OutputEvent : Event
	{
		public OutputEvent(string cat, string outpt)
			: base("output", new
			{
				category = cat,
				output = outpt
			})
		{
		}
	}
	public class Capabilities : ResponseBody
	{
		public bool supportsConfigurationDoneRequest;

		public bool supportsFunctionBreakpoints;

		public bool supportsConditionalBreakpoints;

		public bool supportsEvaluateForHovers;

		public object[] exceptionBreakpointFilters;
	}
	public class ErrorResponseBody : ResponseBody
	{
		public Message error { get; private set; }

		public ErrorResponseBody(Message error)
		{
			this.error = error;
		}
	}
	public class StackTraceResponseBody : ResponseBody
	{
		public StackFrame[] stackFrames { get; private set; }

		public StackTraceResponseBody(List<StackFrame> frames = null)
		{
			if (frames == null)
			{
				stackFrames = new StackFrame[0];
			}
			else
			{
				stackFrames = Enumerable.ToArray(frames);
			}
		}
	}
	public class ScopesResponseBody : ResponseBody
	{
		public Scope[] scopes { get; private set; }

		public ScopesResponseBody(List<Scope> scps = null)
		{
			if (scps == null)
			{
				scopes = new Scope[0];
			}
			else
			{
				scopes = Enumerable.ToArray(scps);
			}
		}
	}
	public class VariablesResponseBody : ResponseBody
	{
		public Variable[] variables { get; private set; }

		public VariablesResponseBody(List<Variable> vars = null)
		{
			if (vars == null)
			{
				variables = new Variable[0];
			}
			else
			{
				variables = Enumerable.ToArray(vars);
			}
		}
	}
	public class ThreadsResponseBody : ResponseBody
	{
		public Thread[] threads { get; private set; }

		public ThreadsResponseBody(List<Thread> vars = null)
		{
			if (vars == null)
			{
				threads = new Thread[0];
			}
			else
			{
				threads = Enumerable.ToArray(vars);
			}
		}
	}
	public class EvaluateResponseBody : ResponseBody
	{
		public string result { get; private set; }

		public string type { get; set; }

		public int variablesReference { get; private set; }

		public EvaluateResponseBody(string value, int reff = 0)
		{
			result = value;
			variablesReference = reff;
		}
	}
	public class SetBreakpointsResponseBody : ResponseBody
	{
		public Breakpoint[] breakpoints { get; private set; }

		public SetBreakpointsResponseBody(List<Breakpoint> bpts = null)
		{
			if (bpts == null)
			{
				breakpoints = new Breakpoint[0];
			}
			else
			{
				breakpoints = Enumerable.ToArray(bpts);
			}
		}
	}
	public abstract class DebugSession : ProtocolServer
	{
		private bool _debuggerLinesStartAt1;

		private bool _debuggerPathsAreURI;

		private bool _clientLinesStartAt1 = true;

		private bool _clientPathsAreURI = true;

		public DebugSession(bool debuggerLinesStartAt1, bool debuggerPathsAreURI = false)
		{
			_debuggerLinesStartAt1 = debuggerLinesStartAt1;
			_debuggerPathsAreURI = debuggerPathsAreURI;
		}

		public void SendResponse(Response response, ResponseBody body = null)
		{
			if (body != null)
			{
				response.SetBody(body);
			}
			SendMessage(response);
		}

		public void SendErrorResponse(Response response, int id, string format, object arguments = null, bool user = true, bool telemetry = false)
		{
			Message message = new Message(id, format, arguments, user, telemetry);
			string msg = Utilities.ExpandVariables(message.format, message.variables);
			response.SetErrorBody(msg, new ErrorResponseBody(message));
			SendMessage(response);
		}

		protected override void DispatchRequest(string command, Table args, Response response)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			if (args == null)
			{
				args = new Table((Script)null);
			}
			try
			{
				switch (command)
				{
				case "initialize":
				{
					if (args[(object)"linesStartAt1"] != null)
					{
						_clientLinesStartAt1 = args.Get("linesStartAt1").ToObject<bool>();
					}
					string text = args.Get("pathFormat").ToObject<string>();
					switch (text)
					{
					case "uri":
						_clientPathsAreURI = true;
						break;
					case "path":
						_clientPathsAreURI = false;
						break;
					default:
						SendErrorResponse(response, 1015, "initialize: bad value '{_format}' for pathFormat", new
						{
							_format = text
						});
						return;
					case null:
						break;
					}
					Initialize(response, args);
					break;
				}
				case "launch":
					Launch(response, args);
					break;
				case "attach":
					Attach(response, args);
					break;
				case "disconnect":
					Disconnect(response, args);
					break;
				case "next":
					Next(response, args);
					break;
				case "continue":
					Continue(response, args);
					break;
				case "stepIn":
					StepIn(response, args);
					break;
				case "stepOut":
					StepOut(response, args);
					break;
				case "pause":
					Pause(response, args);
					break;
				case "stackTrace":
					StackTrace(response, args);
					break;
				case "scopes":
					Scopes(response, args);
					break;
				case "variables":
					Variables(response, args);
					break;
				case "source":
					Source(response, args);
					break;
				case "threads":
					Threads(response, args);
					break;
				case "setBreakpoints":
					SetBreakpoints(response, args);
					break;
				case "setFunctionBreakpoints":
					SetFunctionBreakpoints(response, args);
					break;
				case "setExceptionBreakpoints":
					SetExceptionBreakpoints(response, args);
					break;
				case "evaluate":
					Evaluate(response, args);
					break;
				default:
					SendErrorResponse(response, 1014, "unrecognized request: {_request}", new
					{
						_request = command
					});
					break;
				}
			}
			catch (Exception ex)
			{
				SendErrorResponse(response, 1104, "error while processing request '{_request}' (exception: {_exception})", new
				{
					_request = command,
					_exception = ex.Message
				});
			}
			if (command == "disconnect")
			{
				Stop();
			}
		}

		public abstract void Initialize(Response response, Table args);

		public abstract void Launch(Response response, Table arguments);

		public abstract void Attach(Response response, Table arguments);

		public abstract void Disconnect(Response response, Table arguments);

		public virtual void SetFunctionBreakpoints(Response response, Table arguments)
		{
		}

		public virtual void SetExceptionBreakpoints(Response response, Table arguments)
		{
		}

		public abstract void SetBreakpoints(Response response, Table arguments);

		public abstract void Continue(Response response, Table arguments);

		public abstract void Next(Response response, Table arguments);

		public abstract void StepIn(Response response, Table arguments);

		public abstract void StepOut(Response response, Table arguments);

		public abstract void Pause(Response response, Table arguments);

		public abstract void StackTrace(Response response, Table arguments);

		public abstract void Scopes(Response response, Table arguments);

		public abstract void Variables(Response response, Table arguments);

		public virtual void Source(Response response, Table arguments)
		{
			SendErrorResponse(response, 1020, "Source not supported");
		}

		public abstract void Threads(Response response, Table arguments);

		public abstract void Evaluate(Response response, Table arguments);

		protected int ConvertDebuggerLineToClient(int line)
		{
			if (_debuggerLinesStartAt1)
			{
				if (!_clientLinesStartAt1)
				{
					return line - 1;
				}
				return line;
			}
			if (!_clientLinesStartAt1)
			{
				return line;
			}
			return line + 1;
		}

		protected int ConvertClientLineToDebugger(int line)
		{
			if (_debuggerLinesStartAt1)
			{
				if (!_clientLinesStartAt1)
				{
					return line + 1;
				}
				return line;
			}
			if (!_clientLinesStartAt1)
			{
				return line;
			}
			return line - 1;
		}

		protected string ConvertDebuggerPathToClient(string path)
		{
			if (_debuggerPathsAreURI)
			{
				if (_clientPathsAreURI)
				{
					return path;
				}
				return new Uri(path).LocalPath;
			}
			if (_clientPathsAreURI)
			{
				try
				{
					return new Uri(path).AbsoluteUri;
				}
				catch
				{
					return null;
				}
			}
			return path;
		}

		protected string ConvertClientPathToDebugger(string clientPath)
		{
			if (clientPath == null)
			{
				return null;
			}
			if (_debuggerPathsAreURI)
			{
				if (_clientPathsAreURI)
				{
					return clientPath;
				}
				return new Uri(clientPath).AbsoluteUri;
			}
			if (_clientPathsAreURI)
			{
				if (Uri.IsWellFormedUriString(clientPath, UriKind.Absolute))
				{
					return new Uri(clientPath).LocalPath;
				}
				Console.Error.WriteLine("path not well formed: '{0}'", clientPath);
				return null;
			}
			return clientPath;
		}
	}
	public class ProtocolMessage
	{
		public int seq;

		public string type { get; private set; }

		public ProtocolMessage(string typ)
		{
			type = typ;
		}

		public ProtocolMessage(string typ, int sq)
		{
			type = typ;
			seq = sq;
		}
	}
	public class Request : ProtocolMessage
	{
		public string command;

		public Table arguments;

		public Request(int id, string cmd, Table arg)
			: base("request", id)
		{
			command = cmd;
			arguments = arg;
		}
	}
	public class ResponseBody
	{
	}
	public class Response : ProtocolMessage
	{
		public bool success { get; private set; }

		public string message { get; private set; }

		public int request_seq { get; private set; }

		public string command { get; private set; }

		public ResponseBody body { get; private set; }

		public Response(Table req)
			: base("response")
		{
			success = true;
			request_seq = req.Get("seq").ToObject<int>();
			command = req.Get("command").ToObject<string>();
		}

		public void SetBody(ResponseBody bdy)
		{
			success = true;
			body = bdy;
		}

		public void SetErrorBody(string msg, ResponseBody bdy = null)
		{
			success = false;
			message = msg;
			body = bdy;
		}
	}
	public class Event : ProtocolMessage
	{
		public string @event { get; private set; }

		public object body { get; private set; }

		public Event(string type, object bdy = null)
			: base("event")
		{
			@event = type;
			body = bdy;
		}
	}
	public abstract class ProtocolServer
	{
		public bool TRACE;

		public bool TRACE_RESPONSE;

		protected const int BUFFER_SIZE = 4096;

		protected const string TWO_CRLF = "\r\n\r\n";

		protected static readonly Regex CONTENT_LENGTH_MATCHER = new Regex("Content-Length: (\\d+)");

		protected static readonly Encoding Encoding = Encoding.UTF8;

		private int _sequenceNumber;

		private Stream _outputStream;

		private ByteBuffer _rawData;

		private int _bodyLength;

		private bool _stopRequested;

		public ProtocolServer()
		{
			_sequenceNumber = 1;
			_bodyLength = -1;
			_rawData = new ByteBuffer();
		}

		public void ProcessLoop(Stream inputStream, Stream outputStream)
		{
			_outputStream = outputStream;
			byte[] array = new byte[4096];
			_stopRequested = false;
			while (!_stopRequested)
			{
				int num = inputStream.Read(array, 0, array.Length);
				if (num != 0)
				{
					if (num > 0)
					{
						_rawData.Append(array, num);
						ProcessData();
					}
					continue;
				}
				break;
			}
		}

		public void Stop()
		{
			_stopRequested = true;
		}

		public void SendEvent(Event e)
		{
			SendMessage(e);
		}

		protected abstract void DispatchRequest(string command, Table args, Response response);

		private void ProcessData()
		{
			while (true)
			{
				if (_bodyLength >= 0)
				{
					if (_rawData.Length >= _bodyLength)
					{
						byte[] bytes = _rawData.RemoveFirst(_bodyLength);
						_bodyLength = -1;
						Dispatch(Encoding.GetString(bytes));
						continue;
					}
					break;
				}
				string @string = _rawData.GetString(Encoding);
				int num = @string.IndexOf("\r\n\r\n");
				if (num != -1)
				{
					Match match = CONTENT_LENGTH_MATCHER.Match(@string);
					if (match.Success && match.Groups.Count == 2)
					{
						_bodyLength = Convert.ToInt32(match.Groups[1].ToString());
						_rawData.RemoveFirst(num + "\r\n\r\n".Length);
						continue;
					}
					break;
				}
				break;
			}
		}

		private void Dispatch(string req)
		{
			try
			{
				Table val = JsonTableConverter.JsonToTable(req, (Script)null);
				if (val != null && val[(object)"type"].ToString() == "request")
				{
					if (TRACE)
					{
						Console.Error.WriteLine(string.Format("C {0}: {1}", val[(object)"command"], req));
					}
					Response response = new Response(val);
					DispatchRequest(val.Get("command").String, val.Get("arguments").Table, response);
					SendMessage(response);
				}
			}
			catch
			{
			}
		}

		protected void SendMessage(ProtocolMessage message)
		{
			message.seq = _sequenceNumber++;
			if (TRACE_RESPONSE && message.type == "response")
			{
				Console.Error.WriteLine($" R: {JsonTableConverter.ObjectToJson((object)message)}");
			}
			if (TRACE && message.type == "event")
			{
				Event @event = (Event)message;
				Console.Error.WriteLine($"E {@event.@event}: {JsonTableConverter.ObjectToJson(@event.body)}");
			}
			byte[] array = ConvertToBytes(message);
			try
			{
				_outputStream.Write(array, 0, array.Length);
				_outputStream.Flush();
			}
			catch (Exception)
			{
			}
		}

		private static byte[] ConvertToBytes(ProtocolMessage request)
		{
			string s = JsonTableConverter.ObjectToJson((object)request);
			byte[] bytes = Encoding.GetBytes(s);
			string s2 = string.Format("Content-Length: {0}{1}", bytes.Length, "\r\n\r\n");
			byte[] bytes2 = Encoding.GetBytes(s2);
			byte[] array = new byte[bytes2.Length + bytes.Length];
			Buffer.BlockCopy(bytes2, 0, array, 0, bytes2.Length);
			Buffer.BlockCopy(bytes, 0, array, bytes2.Length, bytes.Length);
			return array;
		}
	}
	internal class ByteBuffer
	{
		private byte[] _buffer;

		public int Length => _buffer.Length;

		public ByteBuffer()
		{
			_buffer = new byte[0];
		}

		public string GetString(Encoding enc)
		{
			return enc.GetString(_buffer);
		}

		public void Append(byte[] b, int length)
		{
			byte[] array = new byte[_buffer.Length + length];
			Buffer.BlockCopy(_buffer, 0, array, 0, _buffer.Length);
			Buffer.BlockCopy(b, 0, array, _buffer.Length, length);
			_buffer = array;
		}

		public byte[] RemoveFirst(int n)
		{
			byte[] array = new byte[n];
			Buffer.BlockCopy(_buffer, 0, array, 0, n);
			byte[] array2 = new byte[_buffer.Length - n];
			Buffer.BlockCopy(_buffer, n, array2, 0, _buffer.Length - n);
			_buffer = array2;
			return array;
		}
	}
	internal class Utilities
	{
		private static readonly Regex VARIABLE = new Regex("\\{(\\w+)\\}");

		public static string ExpandVariables(string format, object variables, bool underscoredOnly = true)
		{
			if (variables == null)
			{
				variables = new { };
			}
			Type type = variables.GetType();
			return VARIABLE.Replace(format, delegate(Match match)
			{
				string value = match.Groups[1].Value;
				if (!underscoredOnly || value.StartsWith("_"))
				{
					PropertyInfo property = Framework.Do.GetProperty(type, value);
					if (property != null)
					{
						return property.GetValue(variables, null).ToString();
					}
					return "{" + value + ": not found}";
				}
				return match.Groups[0].Value;
			});
		}

		public static string MakeRelativePath(string dirPath, string absPath)
		{
			if (!dirPath.EndsWith("/"))
			{
				dirPath += "/";
			}
			if (absPath.StartsWith(dirPath))
			{
				return absPath.Replace(dirPath, "");
			}
			return absPath;
		}
	}
}
namespace MoonSharp.VsCodeDebugger.DebuggerLogic
{
	internal class AsyncDebugger : IDebugger
	{
		private static object s_AsyncDebuggerIdLock = new object();

		private static int s_AsyncDebuggerIdCounter = 0;

		private object m_Lock = new object();

		private IAsyncDebuggerClient m_Client__;

		private DebuggerAction m_PendingAction;

		private List<WatchItem>[] m_WatchItems;

		private Dictionary<int, SourceCode> m_SourcesMap = new Dictionary<int, SourceCode>();

		private Dictionary<int, string> m_SourcesOverride = new Dictionary<int, string>();

		private Func<SourceCode, string> m_SourceFinder;

		public DebugService DebugService { get; private set; }

		public Regex ErrorRegex { get; set; }

		public Script Script { get; private set; }

		public bool PauseRequested { get; set; }

		public string Name { get; set; }

		public int Id { get; private set; }

		public IAsyncDebuggerClient Client
		{
			get
			{
				return m_Client__;
			}
			set
			{
				lock (m_Lock)
				{
					if (m_Client__ != null && m_Client__ != value)
					{
						m_Client__.Unbind();
					}
					if (value != null)
					{
						for (int i = 0; i < Script.SourceCodeCount; i++)
						{
							if (m_SourcesMap.ContainsKey(i))
							{
								value.OnSourceCodeChanged(i);
							}
						}
					}
					m_Client__ = value;
				}
			}
		}

		public AsyncDebugger(Script script, Func<SourceCode, string> sourceFinder, string name)
		{
			lock (s_AsyncDebuggerIdLock)
			{
				Id = s_AsyncDebuggerIdCounter++;
			}
			m_SourceFinder = sourceFinder;
			ErrorRegex = new Regex("\\A.*\\Z");
			Script = script;
			m_WatchItems = new List<WatchItem>[6];
			Name = name;
			for (int i = 0; i < m_WatchItems.Length; i++)
			{
				m_WatchItems[i] = new List<WatchItem>(64);
			}
		}

		DebuggerAction IDebugger.GetAction(int ip, SourceRef sourceref)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			PauseRequested = false;
			lock (m_Lock)
			{
				if (Client != null)
				{
					Client.SendStopEvent();
				}
			}
			while (true)
			{
				lock (m_Lock)
				{
					if (Client == null)
					{
						return new DebuggerAction
						{
							Action = (ActionType)6
						};
					}
					if (m_PendingAction != null)
					{
						DebuggerAction pendingAction = m_PendingAction;
						m_PendingAction = null;
						return pendingAction;
					}
				}
				Sleep(10);
			}
		}

		public void QueueAction(DebuggerAction action)
		{
			while (true)
			{
				lock (m_Lock)
				{
					if (m_PendingAction == null)
					{
						m_PendingAction = action;
						break;
					}
				}
				Sleep(10);
			}
		}

		private void Sleep(int v)
		{
			System.Threading.Thread.Sleep(10);
		}

		private DynamicExpression CreateDynExpr(string code)
		{
			try
			{
				return Script.CreateDynamicExpression(code);
			}
			catch (Exception ex)
			{
				return Script.CreateConstantDynamicExpression(code, DynValue.NewString(ex.Message));
			}
		}

		List<DynamicExpression> IDebugger.GetWatchItems()
		{
			return new List<DynamicExpression>();
		}

		bool IDebugger.IsPauseRequested()
		{
			return PauseRequested;
		}

		void IDebugger.RefreshBreakpoints(IEnumerable<SourceRef> refs)
		{
		}

		void IDebugger.SetByteCode(string[] byteCode)
		{
		}

		void IDebugger.SetSourceCode(SourceCode sourceCode)
		{
			m_SourcesMap[sourceCode.SourceID] = sourceCode;
			bool flag = false;
			string text = m_SourceFinder(sourceCode);
			if (!string.IsNullOrEmpty(text))
			{
				try
				{
					if (!File.Exists(text))
					{
						flag = true;
					}
				}
				catch
				{
					flag = true;
				}
			}
			else
			{
				flag = true;
			}
			if (flag)
			{
				text = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N") + ".lua");
				File.WriteAllText(text, sourceCode.Code + GetFooterForTempFile());
				m_SourcesOverride[sourceCode.SourceID] = text;
			}
			else if (text != sourceCode.Name)
			{
				m_SourcesOverride[sourceCode.SourceID] = text;
			}
			lock (m_Lock)
			{
				if (Client != null)
				{
					Client.OnSourceCodeChanged(sourceCode.SourceID);
				}
			}
		}

		private string GetFooterForTempFile()
		{
			return "\n\n----------------------------------------------------------------------------------------------------------\n-- This file has been generated by the debugger as a placeholder for a script snippet stored in memory. --\n-- If you restart the host process, the contents of this file are not valid anymore.                    --\n----------------------------------------------------------------------------------------------------------\n";
		}

		public string GetSourceFile(int sourceId)
		{
			if (m_SourcesOverride.ContainsKey(sourceId))
			{
				return m_SourcesOverride[sourceId];
			}
			if (m_SourcesMap.ContainsKey(sourceId))
			{
				return m_SourcesMap[sourceId].Name;
			}
			return null;
		}

		public bool IsSourceOverride(int sourceId)
		{
			return m_SourcesOverride.ContainsKey(sourceId);
		}

		void IDebugger.SignalExecutionEnded()
		{
			lock (m_Lock)
			{
				if (Client != null)
				{
					Client.OnExecutionEnded();
				}
			}
		}

		bool IDebugger.SignalRuntimeException(ScriptRuntimeException ex)
		{
			lock (m_Lock)
			{
				if (Client == null)
				{
					return false;
				}
			}
			Client.OnException(ex);
			PauseRequested = ErrorRegex.IsMatch(((Exception)(object)ex).Message);
			return PauseRequested;
		}

		void IDebugger.Update(WatchType watchType, IEnumerable<WatchItem> items)
		{
			//IL_0006: 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)
			List<WatchItem> obj = m_WatchItems[watchType];
			obj.Clear();
			obj.AddRange(items);
			lock (m_Lock)
			{
				if (Client != null)
				{
					Client.OnWatchesUpdated(watchType);
				}
			}
		}

		public List<WatchItem> GetWatches(WatchType watchType)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return m_WatchItems[watchType];
		}

		public SourceCode GetSource(int id)
		{
			if (m_SourcesMap.ContainsKey(id))
			{
				return m_SourcesMap[id];
			}
			return null;
		}

		public SourceCode FindSourceByName(string path)
		{
			path = path.Replace('\\', '/').ToUpperInvariant();
			foreach (KeyValuePair<int, string> item in m_SourcesOverride)
			{
				if (item.Value.Replace('\\', '/').ToUpperInvariant() == path)
				{
					return m_SourcesMap[item.Key];
				}
			}
			return ((IEnumerable<SourceCode>)m_SourcesMap.Values).FirstOrDefault((Func<SourceCode, bool>)((SourceCode s) => s.Name.Replace('\\', '/').ToUpperInvariant() == path));
		}

		void IDebugger.SetDebugService(DebugService debugService)
		{
			DebugService = debugService;
		}

		public DynValue Evaluate(string expression)
		{
			return CreateDynExpr(expression).Evaluate((ScriptExecutionContext)null);
		}

		DebuggerCaps IDebugger.GetDebuggerCaps()
		{
			return (DebuggerCaps)5;
		}
	}
	internal interface IAsyncDebuggerClient
	{
		void SendStopEvent();

		void OnWatchesUpdated(WatchType watchType);

		void OnSourceCodeChanged(int sourceID);

		void OnExecutionEnded();

		void OnException(ScriptRuntimeException ex);

		void Unbind();
	}
	internal class EmptyDebugSession : DebugSession
	{
		private MoonSharpVsCodeDebugServer m_Server;

		internal EmptyDebugSession(MoonSharpVsCodeDebugServer server)
			: base(debuggerLinesStartAt1: true)
		{
			m_Server = server;
		}

		public override void Initialize(Response response, Table args)
		{
			SendText("Connected to MoonSharp {0} [{1}] on process {2} (PID {3})", "2.0.0.0", Script.GlobalOptions.Platform.GetPlatformName(), Process.GetCurrentProcess().ProcessName, Process.GetCurrentProcess().Id);
			SendText("No script is set as default for debugging; use the debug console to select the script to debug.\n");
			SendList();
			SendResponse(response, new Capabilities
			{
				supportsConfigurationDoneRequest = false,
				supportsFunctionBreakpoints = false,
				supportsConditionalBreakpoints = false,
				supportsEvaluateForHovers = false,
				exceptionBreakpointFilters = new object[0]
			});
			SendEvent(new InitializedEvent());
		}

		private void SendList()
		{
			int num = m_Server.CurrentId ?? (-1000);
			SendText("==========================================================");
			foreach (KeyValuePair<int, string> item in m_Server.GetAttachedDebuggersByIdAndName())
			{
				string text = ((item.Key == num) ? " (default)" : "");
				SendText("{0} : {1}{2}", item.Key.ToString().PadLeft(9), item.Value, text);
			}
			SendText("");
			SendText("Type the number of the script to debug, or '!' to refresh");
		}

		public override void Attach(Response response, Table arguments)
		{
			SendResponse(response);
		}

		public override void Continue(Response response, Table arguments)
		{
			SendList();
			SendResponse(response);
		}

		public override void Disconnect(Response response, Table arguments)
		{
			SendResponse(response);
		}

		private static string getString(Table args, string property, string dflt = null)
		{
			string text = (string)args[(object)property];
			if (text == null)
			{
				return dflt;
			}
			text = text.Trim();
			if (text.Length == 0)
			{
				return dflt;
			}
			return text;
		}

		public override void Evaluate(Response response, Table args)
		{
			string @string = getString(args, "expression");
			if ((getString(args, "context") ?? "hover") == "repl")
			{
				ExecuteRepl(@string);
			}
			SendResponse(response);
		}

		private void ExecuteRepl(string cmd)
		{
			int result = 0;
			if (int.TryParse(cmd, out result))
			{
				m_Server.CurrentId = result;
				SendText("Re-attach the debugger to debug the selected script.");
				Unbind();
			}
			else
			{
				SendList();
			}
		}

		public override void Launch(Response response, Table arguments)
		{
			SendResponse(response);
		}

		public override void Next(Response response, Table arguments)
		{
			SendList();
			SendResponse(response);
		}

		public override void Pause(Response response, Table arguments)
		{
			SendList();
			SendResponse(response);
		}

		public override void Scopes(Response response, Table arguments)
		{
			SendResponse(response);
		}

		public override void SetBreakpoints(Response response, Table args)
		{
			SendResponse(response);
		}

		public override void StackTrace(Response response, Table args)
		{
			SendResponse(response);
		}

		public override void StepIn(Response response, Table arguments)
		{
			SendList();
			SendResponse(response);
		}

		public override void StepOut(Response response, Table arguments)
		{
			SendList();
			SendResponse(response);
		}

		public override void Threads(Response response, Table arguments)
		{
			List<MoonSharp.VsCodeDebugger.SDK.Thread> vars = new List<MoonSharp.VsCodeDebugger.SDK.Thread>
			{
				new MoonSharp.VsCodeDebugger.SDK.Thread(0, "Main Thread")
			};
			SendResponse(response, new ThreadsResponseBody(vars));
		}

		public override void Variables(Response response, Table arguments)
		{
			SendResponse(response);
		}

		private void SendText(string msg, params object[] args)
		{
			msg = string.Format(msg, args);
			SendEvent(new OutputEvent("console", msg + "\n"));
		}

		public void Unbind()
		{
			SendText("Bye.");
			SendEvent(new TerminatedEvent());
		}
	}
	internal class MoonSharpDebugSession : DebugSession, IAsyncDebuggerClient
	{
		private AsyncDebugger m_Debug;

		private MoonSharpVsCodeDebugServer m_Server;

		private List<DynValue> m_Variables = new List<DynValue>();

		private bool m_NotifyExecutionEnd;

		private const int SCOPE_LOCALS = 65536;

		private const int SCOPE_SELF = 65537;

		private readonly SourceRef DefaultSourceRef = new SourceRef(-1, 0, 0, 0, 0, false);

		internal MoonSharpDebugSession(MoonSharpVsCodeDebugServer server, AsyncDebugger debugger)
			: base(debuggerLinesStartAt1: true)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			m_Server = server;
			m_Debug = debugger;
		}

		public override void Initialize(Response response, Table args)
		{
			SendText("Connected to MoonSharp {0} [{1}] on process {2} (PID {3})", "2.0.0.0", Script.GlobalOptions.Platform.GetPlatformName(), Process.GetCurrentProcess().ProcessName, Process.GetCurrentProcess().Id);
			SendText("Debugging script '{0}'; use the debug console to debug another script.", m_Debug.Name);
			SendText("Type '!help' in the Debug Console for available commands.");
			SendResponse(response, new Capabilities
			{
				supportsConfigurationDoneRequest = false,
				supportsFunctionBreakpoints = false,
				supportsConditionalBreakpoints = false,
				supportsEvaluateForHovers = false,
				exceptionBreakpointFilters = new object[0]
			});
			SendEvent(new InitializedEvent());
			m_Debug.Client = this;
		}

		public override void Attach(Response response, Table arguments)
		{
			SendResponse(response);
		}

		public override void Continue(Response response, Table arguments)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			m_Debug.QueueAction(new DebuggerAction
			{
				Action = (ActionType)6
			});
			SendResponse(response);
		}

		public override void Disconnect(Response response, Table arguments)
		{
			m_Debug.Client = null;
			SendResponse(response);
		}

		private static string getString(Table args, string property, string dflt = null)
		{
			string text = (string)args[(object)property];
			if (text == null)
			{
				return dflt;
			}
			text = text.Trim();
			if (text.Length == 0)
			{
				return dflt;
			}
			return text;
		}

		public override void Evaluate(Response response, Table args)
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			string @string = getString(args, "expression");
			int @int = getInt(args, "frameId", 0);
			string text = getString(args, "context") ?? "hover";
			if (@int != 0 && text != "repl")
			{
				SendText("Warning : Evaluation of variables/watches is always done with the top-level scope.");
			}
			if (text == "repl" && @string.StartsWith("!"))
			{
				ExecuteRepl(@string.Substring(1));
				SendResponse(response);
				return;
			}
			DynValue val = m_Debug.Evaluate(@string) ?? DynValue.Nil;
			m_Variables.Add(val);
			SendResponse(response, new EvaluateResponseBody(val.ToDebugPrintString(), m_Variables.Count - 1)
			{
				type = LuaTypeExtensions.ToLuaDebuggerString(val.Type)
			});
		}

		private void ExecuteRepl(string cmd)
		{
			bool flag = false;
			cmd = cmd.Trim();
			if (cmd == "help")
			{
				flag = true;
			}
			else if (cmd.StartsWith("geterror"))
			{
				SendText("Current error regex : {0}", m_Debug.ErrorRegex.ToString());
			}
			else if (cmd.StartsWith("seterror"))
			{
				string pattern = cmd.Substring("seterror".Length).Trim();
				try
				{
					Regex errorRegex = new Regex(pattern);
					m_Debug.ErrorRegex = errorRegex;
					SendText("Current error regex : {0}", m_Debug.ErrorRegex.ToString());
				}
				catch (Exception ex)
				{
					SendText("Error setting regex: {0}", ex.Message);
				}
			}
			else if (cmd.StartsWith("execendnotify"))
			{
				string text = cmd.Substring("execendnotify".Length).Trim();
				if (text == "off")
				{
					m_NotifyExecutionEnd = false;
				}
				else if (text == "on")
				{
					m_NotifyExecutionEnd = true;
				}
				else if (text.Length > 0)
				{
					SendText("Error : expected 'on' or 'off'");
				}
				SendText("Notifications of execution end are : {0}", m_NotifyExecutionEnd ? "enabled" : "disabled");
			}
			else if (cmd == "list")
			{
				int num = m_Server.CurrentId ?? (-1000);
				foreach (KeyValuePair<int, string> item in m_Server.GetAttachedDebuggersByIdAndName())
				{
					string text2 = ((item.Key == m_Debug.Id) ? " (this)" : "");
					string text3 = ((item.Key == num) ? " (default)" : "");
					SendText("{0} : {1}{2}{3}", item.Key.ToString().PadLeft(9), item.Value, text3, text2);
				}
			}
			else if (cmd.StartsWith("select") || cmd.StartsWith("switch"))
			{
				string s = cmd.Substring("switch".Length).Trim();
				try
				{
					int num2 = int.Parse(s);
					m_Server.CurrentId = num2;
					if (cmd.StartsWith("switch"))
					{
						Unbind();
					}
					else
					{
						SendText("Next time you'll attach the debugger, it will be atteched to script #{0}", num2);
					}
				}
				catch (Exception ex2)
				{
					SendText("Error setting regex: {0}", ex2.Message);
				}
			}
			else
			{
				SendText("Syntax error : {0}\n", cmd);
				flag = true;
			}
			if (flag)
			{
				SendText("Available commands : ");
				SendText("    !help - gets this help");
				SendText("    !list - lists the other scripts which can be debugged");
				SendText("    !select <id> - select another script for future sessions");
				SendText("    !switch <id> - switch to another script (same as select + disconnect)");
				SendText("    !seterror <regex> - sets the regex which tells which errors to trap");
				SendText("    !geterror - gets the current value of the regex which tells which errors to trap");
				SendText("    !execendnotify [on|off] - sets the notification of end of execution on or off (default = off)");
				SendText("    ... or type an expression to evaluate it on the fly.");
			}
		}

		public override void Launch(Response response, Table arguments)
		{
			SendResponse(response);
		}

		public override void Next(Response response, Table arguments)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			m_Debug.QueueAction(new DebuggerAction
			{
				Action = (ActionType)4
			});
			SendResponse(response);
		}

		private StoppedEvent CreateStoppedEvent(string reason, string text = null)
		{
			return new StoppedEvent(0, reason, text);
		}

		public override void Pause(Response response, Table arguments)
		{
			m_Debug.PauseRequested = true;
			SendResponse(response);
			SendText("Pause pending -- will pause at first script statement.");
		}

		public override void Scopes(Response response, Table arguments)
		{
			List<Scope> list = new List<Scope>();
			list.Add(new Scope("Locals", 65536));
			list.Add(new Scope("Self", 65537));
			SendResponse(response, new ScopesResponseBody(list));
		}

		public override void SetBreakpoints(Response response, Table args)
		{
			string text = null;
			object obj = args[(object)"source"];
			Table val = (Table)((obj is Table) ? obj : null);
			if (val != null)
			{
				string text2 = val[(object)"path"].ToString();
				if (text2 != null && text2.Trim().Length > 0)
				{
					text = text2;
				}
			}
			if (text == null)
			{
				SendErrorResponse(response, 3010, "setBreakpoints: property 'source' is empty or misformed", null, user: false, telemetry: true);
				return;
			}
			text = ConvertClientPathToDebugger(text);
			SourceCode val2 = m_Debug.FindSourceByName(text);
			if (val2 == null)
			{
				SendResponse(response, new SetBreakpointsResponseBody());
				return;
			}
			HashSet<int> hashSet = new HashSet<int>(args.Get("lines").Table.Values.Select((DynValue jt) => ConvertClientLineToDebugger(jt.ToObject<int>())).ToArray());
			HashSet<int> hashSet2 = m_Debug.DebugService.ResetBreakPoints(val2, hashSet);
			List<Breakpoint> list = new List<Breakpoint>();
			foreach (int item in hashSet)
			{
				list.Add(new Breakpoint(hashSet2.Contains(item), item));
			}
			response.SetBody(new SetBreakpointsResponseBody(list));
			SendResponse(response);
		}

		public override void StackTrace(Response response, Table args)
		{
			int @int = getInt(args, "levels", 10);
			List<MoonSharp.VsCodeDebugger.SDK.StackFrame> list = new List<MoonSharp.VsCodeDebugger.SDK.StackFrame>();
			List<WatchItem> watches = m_Debug.GetWatches((WatchType)2);
			WatchItem val = m_Debug.GetWatches((WatchType)5).LastOrDefault();
			int i = 0;
			for (int num = Math.Min(@int - 3, watches.Count); i < num; i++)
			{
				WatchItem obj = watches[i];
				string name = obj.Name;
				SourceRef val2 = obj.Location ?? DefaultSourceRef;
				int sourceIdx = val2.SourceIdx;
				string path = (val2.IsClrLocation ? "(native)" : (m_Debug.GetSourceFile(sourceIdx) ?? "???"));
				Source source = new Source(Path.GetFileName(path), path);
				list.Add(new MoonSharp.VsCodeDebugger.SDK.StackFrame(i, name, source, ConvertDebuggerLineToClient(val2.FromLine), val2.FromChar, ConvertDebuggerLineToClient(val2.ToLine), val2.ToChar));
			}
			if (watches.Count > @int - 3)
			{
				list.Add(new MoonSharp.VsCodeDebugger.SDK.StackFrame(i++, "(...)", null, 0));
			}
			if (val != null)
			{
				list.Add(new MoonSharp.VsCodeDebugger.SDK.StackFrame(i++, "(" + val.Name + ")", null, 0));
			}
			else
			{
				list.Add(new MoonSharp.VsCodeDebugger.SDK.StackFrame(i++, "(main coroutine)", null, 0));
			}
			list.Add(new MoonSharp.VsCodeDebugger.SDK.StackFrame(i++, "(native)", null, 0));
			SendResponse(response, new StackTraceResponseBody(list));
		}

		private int getInt(Table args, string propName, int defaultValue)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			DynValue val = args.Get(propName);
			if ((int)val.Type != 3)
			{
				return defaultValue;
			}
			return val.ToObject<int>();
		}

		public override void StepIn(Response response, Table arguments)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			m_Debug.QueueAction(new DebuggerAction
			{
				Action = (ActionType)3
			});
			SendResponse(response);
		}

		public override void StepOut(Response response, Table arguments)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			m_Debug.QueueAction(new DebuggerAction
			{
				Action = (ActionType)5
			});
			SendResponse(response);
		}

		public override void Threads(Response response, Table arguments)
		{
			List<MoonSharp.VsCodeDebugger.SDK.Thread> vars = new List<MoonSharp.VsCodeDebugger.SDK.Thread>
			{
				new MoonSharp.VsCodeDebugger.SDK.Thread(0, "Main Thread")
			};
			SendResponse(response, new ThreadsResponseBody(vars));
		}

		public override void Variables(Response response, Table arguments)
		{
			int @int = getInt(arguments, "variablesReference", -1);
			List<Variable> list = new List<Variable>();
			if (@int == 65537)
			{
				VariableInspector.InspectVariable(m_Debug.Evaluate("self"), list);
			}
			else if (@int == 65536)
			{
				foreach (WatchItem watch in m_Debug.GetWatches((WatchType)4))
				{
					list.Add(new Variable(watch.Name, (watch.Value ?? DynValue.Void).ToDebugPrintString()));
				}
			}
			else if (@int < 0 || @int >= m_Variables.Count)
			{
				list.Add(new Variable("<error>", null));
			}
			else
			{
				VariableInspector.InspectVariable(m_Variables[@int], list);
			}
			SendResponse(response, new VariablesResponseBody(list));
		}

		void IAsyncDebuggerClient.SendStopEvent()
		{
			SendEvent(CreateStoppedEvent("step"));
		}

		void IAsyncDebuggerClient.OnWatchesUpdated(WatchType watchType)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			if ((int)watchType == 2)
			{
				m_Variables.Clear();
			}
		}

		void IAsyncDebuggerClient.OnSourceCodeChanged(int sourceID)
		{
			if (m_Debug.IsSourceOverride(sourceID))
			{
				SendText("Loaded source '{0}' -> '{1}'", m_Debug.GetSource(sourceID).Name, m_Debug.GetSourceFile(sourceID));
			}
			else
			{
				SendText("Loaded source '{0}'", m_Debug.GetSource(sourceID).Name);
			}
		}

		public void OnExecutionEnded()
		{
			if (m_NotifyExecutionEnd)
			{
				SendText("Execution ended.");
			}
		}

		private void SendText(string msg, params object[] args)
		{
			msg = string.Format(msg, args);
			SendEvent(new OutputEvent("console", msg + "\n"));
		}

		public void OnException(ScriptRuntimeException ex)
		{
			SendText("runtime error : {0}", ((InterpreterException)ex).DecoratedMessage);
		}

		public void Unbind()
		{
			SendText("Debug session has been closed by the hosting process.");
			SendText("Bye.");
			SendEvent(new TerminatedEvent());
		}
	}
	internal static class VariableInspector
	{
		internal static void InspectVariable(DynValue v, List<Variable> variables)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected I4, but got Unknown
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_039f: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			variables.Add(new Variable("(value)", v.ToPrintString()));
			variables.Add(new Variable("(type)", LuaTypeExtensions.ToLuaDebuggerString(v.Type)));
			variables.Add(new Variable("(val #id)", v.ReferenceID.ToString()));
			DataType type = v.Type;
			switch ((int)type)
			{
			case 7:
			{
				for (int i = 0; i < v.Tuple.Length; i++)
				{
					variables.Add(new Variable("[i]", (v.Tuple[i] ?? DynValue.Void).ToDebugPrintString()));
				}
				break;
			}
			case 5:
			{
				variables.Add(new Variable("(address)", v.Function.EntryPointByteCodeLocation.ToString("X8")));
				variables.Add(new Variable("(upvalues)", v.Function.GetUpvaluesCount().ToString()));
				UpvaluesType upvaluesType = v.Function.GetUpvaluesType();
				variables.Add(new Variable("(upvalues type)", ((object)(UpvaluesType)(ref upvaluesType)).ToString()));
				break;
			}
			case 6:
				if (v.Table.MetaTable != null && v.Table.OwnerScript == null)
				{
					variables.Add(new Variable("(table type)", "prime table with metatable"));
				}
				else if (v.Table.MetaTable != null)
				{
					variables.Add(new Variable("(table type)", "has metatable"));
				}
				else if (v.Table.OwnerScript == null)
				{
					variables.Add(new Variable("(table type)", "prime table"));
				}
				else
				{
					variables.Add(new Variable("(table type)", "standard"));
				}
				variables.Add(new Variable("(table #id)", ((RefIdObject)v.Table).ReferenceID.ToString()));
				if (v.Table.MetaTable != null)
				{
					variables.Add(new Variable("(metatable #id)", ((RefIdObject)v.Table.MetaTable).ReferenceID.ToString()));
				}
				variables.Add(new Variable("(length)", v.Table.Length.ToString()));
				{
					foreach (TablePair pair in v.Table.Pairs)
					{
						TablePair current = pair;
						variables.Add(new Variable("[" + ((TablePair)(ref current)).Key.ToDebugPrintString() + "]", ((TablePair)(ref current)).Value.ToDebugPrintString()));
					}
					break;
				}
			case 8:
				if (v.UserData.Descriptor != null)
				{
					variables.Add(new Variable("(descriptor)", v.UserData.Descriptor.Name));
					variables.Add(new Variable("(native type)", v.UserData.Descriptor.Type.ToString()));
				}
				else
				{
					variables.Add(new Variable("(descriptor)", "null!"));
				}
				variables.Add(new Variable("(native object)", (v.UserData.Object != null) ? v.UserData.Object.ToString() : "(null)"));
				break;
			case 9:
			{
				CoroutineState state = v.Coroutine.State;
				variables.Add(new Variable("(coroutine state)", ((object)(CoroutineState)(ref state)).ToString()));
				CoroutineType type2 = v.Coroutine.Type;
				variables.Add(new Variable("(coroutine type)", ((object)(CoroutineType)(ref type2)).ToString()));
				variables.Add(new Variable("(auto-yield counter)", v.Coroutine.AutoYieldCounter.ToString()));
				break;
			}
			case 10:
				variables.Add(new Variable("(name)", v.Callback.Name ?? "(unnamed)"));
				break;
			case 0:
			case 1:
			case 2:
			case 3:
			case 4:
			case 11:
			case 12:
				break;
			}
		}
	}
}

mapMaker/System.IO.Compression.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO.Compression;
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 System.Threading;
using System.Threading.Tasks;
using FxResources.System.IO.Compression;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: SecurityTransparent]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyTitle("System.IO.Compression")]
[assembly: AssemblyDescription("System.IO.Compression")]
[assembly: AssemblyDefaultAlias("System.IO.Compression")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: AssemblyCopyright("© Microsoft Corporation.  All rights reserved.")]
[assembly: AssemblyFileVersion("4.6.24705.01")]
[assembly: AssemblyInformationalVersion("4.6.24705.01. Commit Hash: 4d1af962ca0fede10beb01d197367c2f90e92c97")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.1.2.0")]
[assembly: TypeForwardedTo(typeof(CompressionLevel))]
[assembly: TypeForwardedTo(typeof(CompressionMode))]
[assembly: TypeForwardedTo(typeof(DeflateStream))]
[assembly: TypeForwardedTo(typeof(GZipStream))]
[module: UnverifiableCode]
internal enum MatchState
{
	HasSymbol = 1,
	HasMatch,
	HasSymbolAndMatch
}
namespace FxResources.System.IO.Compression
{
	internal static class SR
	{
	}
}
namespace System
{
	internal static class SR
	{
		private static ResourceManager s_resourceManager;

		private const string s_resourcesName = "FxResources.System.IO.Compression.SR";

		private static ResourceManager ResourceManager
		{
			get
			{
				if (s_resourceManager == null)
				{
					s_resourceManager = new ResourceManager(ResourceType);
				}
				return s_resourceManager;
			}
		}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		internal static Type ResourceType => typeof(FxResources.System.IO.Compression.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.IO
{
	internal static class PathInternal
	{
		internal const string ExtendedPathPrefix = "\\\\?\\";

		internal const string UncPathPrefix = "\\\\";

		internal const string UncExtendedPrefixToInsert = "?\\UNC\\";

		internal const string UncExtendedPathPrefix = "\\\\?\\UNC\\";

		internal const string DevicePathPrefix = "\\\\.\\";

		internal const int MaxShortPath = 260;

		internal const int MaxShortDirectoryPath = 248;

		internal const int MaxLongPath = 32767;

		internal const int DevicePrefixLength = 4;

		internal const int UncPrefixLength = 2;

		internal const int UncExtendedPrefixLength = 8;

		internal static readonly int MaxComponentLength = 255;

		internal static void CheckInvalidPathChars(string path)
		{
			if (path == null)
			{
				throw new ArgumentNullException("path");
			}
			if (HasIllegalCharacters(path))
			{
				throw new ArgumentException(System.SR.Argument_InvalidPathChars, "path");
			}
		}

		internal static bool StartsWithOrdinal(this StringBuilder builder, string value)
		{
			if (value == null || builder.Length < value.Length)
			{
				return false;
			}
			for (int i = 0; i < value.Length; i++)
			{
				if (builder[i] != value[i])
				{
					return false;
				}
			}
			return true;
		}

		internal static bool StartsWithOrdinal(this string source, string value)
		{
			if (value == null || source.Length < value.Length)
			{
				return false;
			}
			return source.StartsWith(value, StringComparison.Ordinal);
		}

		internal static StringBuilder TrimEnd(this StringBuilder builder, params char[] trimChars)
		{
			if (trimChars == null || trimChars.Length == 0)
			{
				return builder;
			}
			int num;
			for (num = builder.Length - 1; num >= 0; num--)
			{
				int i = 0;
				for (char c = builder[num]; i < trimChars.Length && trimChars[i] != c; i++)
				{
				}
				if (i == trimChars.Length)
				{
					break;
				}
			}
			builder.Length = num + 1;
			return builder;
		}

		internal static int FindFileNameIndex(string path)
		{
			CheckInvalidPathChars(path);
			for (int num = path.Length - 1; num >= 0; num--)
			{
				char ch = path[num];
				if (IsDirectoryOrVolumeSeparator(ch))
				{
					return num + 1;
				}
			}
			return 0;
		}

		internal static char[] GetInvalidPathChars()
		{
			return new char[36]
			{
				'"', '<', '>', '|', '\0', '\u0001', '\u0002', '\u0003', '\u0004', '\u0005',
				'\u0006', '\a', '\b', '\t', '\n', '\v', '\f', '\r', '\u000e', '\u000f',
				'\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016', '\u0017', '\u0018', '\u0019',
				'\u001a', '\u001b', '\u001c', '\u001d', '\u001e', '\u001f'
			};
		}

		internal static bool IsValidDriveChar(char value)
		{
			if (value < 'A' || value > 'Z')
			{
				if (value >= 'a')
				{
					return value <= 'z';
				}
				return false;
			}
			return true;
		}

		internal static bool IsPathTooLong(string fullPath)
		{
			if (fullPath.Length < 32767 - "\\\\?\\UNC\\".Length)
			{
				return false;
			}
			if (IsDevice(fullPath))
			{
				return fullPath.Length >= 32767;
			}
			if (fullPath.StartsWith("\\\\", StringComparison.Ordinal))
			{
				return fullPath.Length + "?\\UNC\\".Length >= 32767;
			}
			return fullPath.Length + "\\\\?\\".Length >= 32767;
		}

		internal static bool IsDirectoryTooLong(string fullPath)
		{
			return IsPathTooLong(fullPath);
		}

		internal static string EnsureExtendedPrefixOverMaxPath(string path)
		{
			if (path != null && path.Length >= 260)
			{
				return EnsureExtendedPrefix(path);
			}
			return path;
		}

		internal static string EnsureExtendedPrefix(string path)
		{
			if (IsPartiallyQualified(path) || IsDevice(path))
			{
				return path;
			}
			if (path.StartsWith("\\\\", StringComparison.OrdinalIgnoreCase))
			{
				return path.Insert(2, "?\\UNC\\");
			}
			return "\\\\?\\" + path;
		}

		internal static bool IsDevice(string path)
		{
			if (!IsExtended(path))
			{
				if (path.Length >= 4 && IsDirectorySeparator(path[0]) && IsDirectorySeparator(path[1]) && (path[2] == '.' || path[2] == '?'))
				{
					return IsDirectorySeparator(path[3]);
				}
				return false;
			}
			return true;
		}

		internal static bool IsExtended(string path)
		{
			if (path.Length >= 4 && path[0] == '\\' && (path[1] == '\\' || path[1] == '?') && path[2] == '?')
			{
				return path[3] == '\\';
			}
			return false;
		}

		internal static bool HasIllegalCharacters(string path)
		{
			foreach (char c in path)
			{
				if (c <= '\u001f')
				{
					return true;
				}
				switch (c)
				{
				case '"':
				case '<':
				case '>':
				case '|':
					return true;
				}
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static bool HasWildCardCharacters(string path)
		{
			int num = (IsExtended(path) ? "\\\\?\\".Length : 0);
			for (int i = num; i < path.Length; i++)
			{
				char c = path[i];
				if (c == '*' || c == '?')
				{
					return true;
				}
			}
			return false;
		}

		internal unsafe static int GetRootLength(string path)
		{
			fixed (char* path2 = path)
			{
				return (int)GetRootLength(path2, (uint)path.Length);
			}
		}

		private unsafe static uint GetRootLength(char* path, uint pathLength)
		{
			uint num = 0u;
			uint num2 = 2u;
			uint num3 = 2u;
			bool flag = StartsWithOrdinal(path, pathLength, "\\\\?\\");
			bool flag2 = StartsWithOrdinal(path, pathLength, "\\\\?\\UNC\\");
			if (flag)
			{
				if (flag2)
				{
					num3 = (uint)"\\\\?\\UNC\\".Length;
				}
				else
				{
					num2 += (uint)"\\\\?\\".Length;
				}
			}
			if ((!flag || flag2) && pathLength != 0 && IsDirectorySeparator(*path))
			{
				num = 1u;
				if (flag2 || (pathLength > 1 && IsDirectorySeparator(path[1])))
				{
					num = num3;
					int num4 = 2;
					for (; num < pathLength; num++)
					{
						if (IsDirectorySeparator(path[num]) && --num4 <= 0)
						{
							break;
						}
					}
				}
			}
			else if (pathLength >= num2 && path[num2 - 1] == Path.VolumeSeparatorChar)
			{
				num = num2;
				if (pathLength >= num2 + 1 && IsDirectorySeparator(path[num2]))
				{
					num++;
				}
			}
			return num;
		}

		private unsafe static bool StartsWithOrdinal(char* source, uint sourceLength, string value)
		{
			if (sourceLength < (uint)value.Length)
			{
				return false;
			}
			for (int i = 0; i < value.Length; i++)
			{
				if (value[i] != source[i])
				{
					return false;
				}
			}
			return true;
		}

		internal static bool IsPartiallyQualified(string path)
		{
			if (path.Length < 2)
			{
				return true;
			}
			if (IsDirectorySeparator(path[0]))
			{
				if (path[1] != '?')
				{
					return !IsDirectorySeparator(path[1]);
				}
				return false;
			}
			if (path.Length >= 3 && path[1] == Path.VolumeSeparatorChar)
			{
				return !IsDirectorySeparator(path[2]);
			}
			return true;
		}

		internal static int PathStartSkip(string path)
		{
			int i;
			for (i = 0; i < path.Length && path[i] == ' '; i++)
			{
			}
			if ((i > 0 && i < path.Length && IsDirectorySeparator(path[i])) || (i + 1 < path.Length && path[i + 1] == ':' && IsValidDriveChar(path[i])))
			{
				return i;
			}
			return 0;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static bool IsDirectorySeparator(char c)
		{
			if (c != Path.DirectorySeparatorChar)
			{
				return c == Path.AltDirectorySeparatorChar;
			}
			return true;
		}

		internal static string NormalizeDirectorySeparators(string path)
		{
			if (string.IsNullOrEmpty(path))
			{
				return path;
			}
			int num = PathStartSkip(path);
			if (num == 0)
			{
				bool flag = true;
				for (int i = 0; i < path.Length; i++)
				{
					char c = path[i];
					if (IsDirectorySeparator(c) && (c != Path.DirectorySeparatorChar || (i > 0 && i + 1 < path.Length && IsDirectorySeparator(path[i + 1]))))
					{
						flag = false;
						break;
					}
				}
				if (flag)
				{
					return path;
				}
			}
			StringBuilder stringBuilder = new StringBuilder(path.Length);
			if (IsDirectorySeparator(path[num]))
			{
				num++;
				stringBuilder.Append(Path.DirectorySeparatorChar);
			}
			for (int j = num; j < path.Length; j++)
			{
				char c = path[j];
				if (IsDirectorySeparator(c))
				{
					if (j + 1 < path.Length && IsDirectorySeparator(path[j + 1]))
					{
						continue;
					}
					c = Path.DirectorySeparatorChar;
				}
				stringBuilder.Append(c);
			}
			return stringBuilder.ToString();
		}

		internal static bool IsDirectoryOrVolumeSeparator(char ch)
		{
			if (!IsDirectorySeparator(ch))
			{
				return Path.VolumeSeparatorChar == ch;
			}
			return true;
		}
	}
}
namespace System.IO.Compression
{
	internal static class Crc32Helper
	{
		private static readonly uint[] s_crcTable_0 = new uint[256]
		{
			0u, 1996959894u, 3993919788u, 2567524794u, 124634137u, 1886057615u, 3915621685u, 2657392035u, 249268274u, 2044508324u,
			3772115230u, 2547177864u, 162941995u, 2125561021u, 3887607047u, 2428444049u, 498536548u, 1789927666u, 4089016648u, 2227061214u,
			450548861u, 1843258603u, 4107580753u, 2211677639u, 325883990u, 1684777152u, 4251122042u, 2321926636u, 335633487u, 1661365465u,
			4195302755u, 2366115317u, 997073096u, 1281953886u, 3579855332u, 2724688242u, 1006888145u, 1258607687u, 3524101629u, 2768942443u,
			901097722u, 1119000684u, 3686517206u, 2898065728u, 853044451u, 1172266101u, 3705015759u, 2882616665u, 651767980u, 1373503546u,
			3369554304u, 3218104598u, 565507253u, 1454621731u, 3485111705u, 3099436303u, 671266974u, 1594198024u, 3322730930u, 2970347812u,
			795835527u, 1483230225u, 3244367275u, 3060149565u, 1994146192u, 31158534u, 2563907772u, 4023717930u, 1907459465u, 112637215u,
			2680153253u, 3904427059u, 2013776290u, 251722036u, 2517215374u, 3775830040u, 2137656763u, 141376813u, 2439277719u, 3865271297u,
			1802195444u, 476864866u, 2238001368u, 4066508878u, 1812370925u, 453092731u, 2181625025u, 4111451223u, 1706088902u, 314042704u,
			2344532202u, 4240017532u, 1658658271u, 366619977u, 2362670323u, 4224994405u, 1303535960u, 984961486u, 2747007092u, 3569037538u,
			1256170817u, 1037604311u, 2765210733u, 3554079995u, 1131014506u, 879679996u, 2909243462u, 3663771856u, 1141124467u, 855842277u,
			2852801631u, 3708648649u, 1342533948u, 654459306u, 3188396048u, 3373015174u, 1466479909u, 544179635u, 3110523913u, 3462522015u,
			1591671054u, 702138776u, 2966460450u, 3352799412u, 1504918807u, 783551873u, 3082640443u, 3233442989u, 3988292384u, 2596254646u,
			62317068u, 1957810842u, 3939845945u, 2647816111u, 81470997u, 1943803523u, 3814918930u, 2489596804u, 225274430u, 2053790376u,
			3826175755u, 2466906013u, 167816743u, 2097651377u, 4027552580u, 2265490386u, 503444072u, 1762050814u, 4150417245u, 2154129355u,
			426522225u, 1852507879u, 4275313526u, 2312317920u, 282753626u, 1742555852u, 4189708143u, 2394877945u, 397917763u, 1622183637u,
			3604390888u, 2714866558u, 953729732u, 1340076626u, 3518719985u, 2797360999u, 1068828381u, 1219638859u, 3624741850u, 2936675148u,
			906185462u, 1090812512u, 3747672003u, 2825379669u, 829329135u, 1181335161u, 3412177804u, 3160834842u, 628085408u, 1382605366u,
			3423369109u, 3138078467u, 570562233u, 1426400815u, 3317316542u, 2998733608u, 733239954u, 1555261956u, 3268935591u, 3050360625u,
			752459403u, 1541320221u, 2607071920u, 3965973030u, 1969922972u, 40735498u, 2617837225u, 3943577151u, 1913087877u, 83908371u,
			2512341634u, 3803740692u, 2075208622u, 213261112u, 2463272603u, 3855990285u, 2094854071u, 198958881u, 2262029012u, 4057260610u,
			1759359992u, 534414190u, 2176718541u, 4139329115u, 1873836001u, 414664567u, 2282248934u, 4279200368u, 1711684554u, 285281116u,
			2405801727u, 4167216745u, 1634467795u, 376229701u, 2685067896u, 3608007406u, 1308918612u, 956543938u, 2808555105u, 3495958263u,
			1231636301u, 1047427035u, 2932959818u, 3654703836u, 1088359270u, 936918000u, 2847714899u, 3736837829u, 1202900863u, 817233897u,
			3183342108u, 3401237130u, 1404277552u, 615818150u, 3134207493u, 3453421203u, 1423857449u, 601450431u, 3009837614u, 3294710456u,
			1567103746u, 711928724u, 3020668471u, 3272380065u, 1510334235u, 755167117u
		};

		private static readonly uint[] s_crcTable_1 = new uint[256]
		{
			0u, 421212481u, 842424962u, 724390851u, 1684849924u, 2105013317u, 1448781702u, 1329698503u, 3369699848u, 3519200073u,
			4210026634u, 3824474571u, 2897563404u, 3048111693u, 2659397006u, 2274893007u, 1254232657u, 1406739216u, 2029285587u, 1643069842u,
			783210325u, 934667796u, 479770071u, 92505238u, 2182846553u, 2600511768u, 2955803355u, 2838940570u, 3866582365u, 4285295644u,
			3561045983u, 3445231262u, 2508465314u, 2359236067u, 2813478432u, 3198777185u, 4058571174u, 3908292839u, 3286139684u, 3670389349u,
			1566420650u, 1145479147u, 1869335592u, 1987116393u, 959540142u, 539646703u, 185010476u, 303839341u, 3745920755u, 3327985586u,
			3983561841u, 4100678960u, 3140154359u, 2721170102u, 2300350837u, 2416418868u, 396344571u, 243568058u, 631889529u, 1018359608u,
			1945336319u, 1793607870u, 1103436669u, 1490954812u, 4034481925u, 3915546180u, 3259968903u, 3679722694u, 2484439553u, 2366552896u,
			2787371139u, 3208174018u, 950060301u, 565965900u, 177645455u, 328046286u, 1556873225u, 1171730760u, 1861902987u, 2011255754u,
			3132841300u, 2745199637u, 2290958294u, 2442530455u, 3738671184u, 3352078609u, 3974232786u, 4126854035u, 1919080284u, 1803150877u,
			1079293406u, 1498383519u, 370020952u, 253043481u, 607678682u, 1025720731u, 1711106983u, 2095471334u, 1472923941u, 1322268772u,
			26324643u, 411738082u, 866634785u, 717028704u, 2904875439u, 3024081134u, 2668790573u, 2248782444u, 3376948395u, 3495106026u,
			4219356713u, 3798300520u, 792689142u, 908347575u, 487136116u, 68299317u, 1263779058u, 1380486579u, 2036719216u, 1618931505u,
			3890672638u, 4278043327u, 3587215740u, 3435896893u, 2206873338u, 2593195963u, 2981909624u, 2829542713u, 998479947u, 580430090u,
			162921161u, 279890824u, 1609522511u, 1190423566u, 1842954189u, 1958874764u, 4082766403u, 3930137346u, 3245109441u, 3631694208u,
			2536953671u, 2385372678u, 2768287173u, 3155920004u, 1900120602u, 1750776667u, 1131931800u, 1517083097u, 355290910u, 204897887u,
			656092572u, 1040194781u, 3113746450u, 2692952403u, 2343461520u, 2461357009u, 3723805974u, 3304059991u, 4022511508u, 4141455061u,
			2919742697u, 3072101800u, 2620513899u, 2234183466u, 3396041197u, 3547351212u, 4166851439u, 3779471918u, 1725839073u, 2143618976u,
			1424512099u, 1307796770u, 45282277u, 464110244u, 813994343u, 698327078u, 3838160568u, 4259225593u, 3606301754u, 3488152955u,
			2158586812u, 2578602749u, 2996767038u, 2877569151u, 740041904u, 889656817u, 506086962u, 120682355u, 1215357364u, 1366020341u,
			2051441462u, 1667084919u, 3422213966u, 3538019855u, 4190942668u, 3772220557u, 2945847882u, 3062702859u, 2644537544u, 2226864521u,
			52649286u, 439905287u, 823476164u, 672009861u, 1733269570u, 2119477507u, 1434057408u, 1281543041u, 2167981343u, 2552493150u,
			3004082077u, 2853541596u, 3847487515u, 4233048410u, 3613549209u, 3464057816u, 1239502615u, 1358593622u, 2077699477u, 1657543892u,
			764250643u, 882293586u, 532408465u, 111204816u, 1585378284u, 1197851309u, 1816695150u, 1968414767u, 974272232u, 587794345u,
			136598634u, 289367339u, 2527558116u, 2411481253u, 2760973158u, 3179948583u, 4073438432u, 3956313505u, 3237863010u, 3655790371u,
			347922877u, 229101820u, 646611775u, 1066513022u, 1892689081u, 1774917112u, 1122387515u, 1543337850u, 3697634229u, 3313392372u,
			3998419255u, 4148705398u, 3087642289u, 2702352368u, 2319436851u, 2468674930u
		};

		private static readonly uint[] s_crcTable_2 = new uint[256]
		{
			0u, 29518391u, 59036782u, 38190681u, 118073564u, 114017003u, 76381362u, 89069189u, 236147128u, 265370511u,
			228034006u, 206958561u, 152762724u, 148411219u, 178138378u, 190596925u, 472294256u, 501532999u, 530741022u, 509615401u,
			456068012u, 451764635u, 413917122u, 426358261u, 305525448u, 334993663u, 296822438u, 275991697u, 356276756u, 352202787u,
			381193850u, 393929805u, 944588512u, 965684439u, 1003065998u, 973863097u, 1061482044u, 1049003019u, 1019230802u, 1023561829u,
			912136024u, 933002607u, 903529270u, 874031361u, 827834244u, 815125939u, 852716522u, 856752605u, 611050896u, 631869351u,
			669987326u, 640506825u, 593644876u, 580921211u, 551983394u, 556069653u, 712553512u, 733666847u, 704405574u, 675154545u,
			762387700u, 749958851u, 787859610u, 792175277u, 1889177024u, 1901651959u, 1931368878u, 1927033753u, 2006131996u, 1985040171u,
			1947726194u, 1976933189u, 2122964088u, 2135668303u, 2098006038u, 2093965857u, 2038461604u, 2017599123u, 2047123658u, 2076625661u,
			1824272048u, 1836991623u, 1866005214u, 1861914857u, 1807058540u, 1786244187u, 1748062722u, 1777547317u, 1655668488u, 1668093247u,
			1630251878u, 1625932113u, 1705433044u, 1684323811u, 1713505210u, 1742760333u, 1222101792u, 1226154263u, 1263738702u, 1251046777u,
			1339974652u, 1310460363u, 1281013650u, 1301863845u, 1187289752u, 1191637167u, 1161842422u, 1149379777u, 1103966788u, 1074747507u,
			1112139306u, 1133218845u, 1425107024u, 1429406311u, 1467333694u, 1454888457u, 1408811148u, 1379576507u, 1350309090u, 1371438805u,
			1524775400u, 1528845279u, 1499917702u, 1487177649u, 1575719220u, 1546255107u, 1584350554u, 1605185389u, 3778354048u, 3774312887u,
			3803303918u, 3816007129u, 3862737756u, 3892238699u, 3854067506u, 3833203973u, 4012263992u, 4007927823u, 3970080342u, 3982554209u,
			3895452388u, 3924658387u, 3953866378u, 3932773565u, 4245928176u, 4241609415u, 4271336606u, 4283762345u, 4196012076u, 4225268251u,
			4187931714u, 4166823541u, 4076923208u, 4072833919u, 4035198246u, 4047918865u, 4094247316u, 4123732899u, 4153251322u, 4132437965u,
			3648544096u, 3636082519u, 3673983246u, 3678331705u, 3732010428u, 3753090955u, 3723829714u, 3694611429u, 3614117080u, 3601426159u,
			3572488374u, 3576541825u, 3496125444u, 3516976691u, 3555094634u, 3525581405u, 3311336976u, 3298595879u, 3336186494u, 3340255305u,
			3260503756u, 3281337595u, 3251864226u, 3222399125u, 3410866088u, 3398419871u, 3368647622u, 3372945905u, 3427010420u, 3448139075u,
			3485520666u, 3456284973u, 2444203584u, 2423127159u, 2452308526u, 2481530905u, 2527477404u, 2539934891u, 2502093554u, 2497740997u,
			2679949304u, 2659102159u, 2620920726u, 2650438049u, 2562027300u, 2574714131u, 2603727690u, 2599670141u, 2374579504u, 2353749767u,
			2383274334u, 2412743529u, 2323684844u, 2336421851u, 2298759554u, 2294686645u, 2207933576u, 2186809023u, 2149495014u, 2178734801u,
			2224278612u, 2236720739u, 2266437690u, 2262135309u, 2850214048u, 2820717207u, 2858812622u, 2879680249u, 2934667388u, 2938704459u,
			2909776914u, 2897069605u, 2817622296u, 2788420399u, 2759153014u, 2780249921u, 2700618180u, 2704950259u, 2742877610u, 2730399645u,
			3049550800u, 3020298727u, 3057690558u, 3078802825u, 2999835404u, 3004150075u, 2974355298u, 2961925461u, 3151438440u, 3121956959u,
			3092510214u, 3113327665u, 3168701108u, 3172786307u, 3210370778u, 3197646061u
		};

		private static readonly uint[] s_crcTable_3 = new uint[256]
		{
			0u, 3099354981u, 2852767883u, 313896942u, 2405603159u, 937357362u, 627793884u, 2648127673u, 3316918511u, 2097696650u,
			1874714724u, 3607201537u, 1255587768u, 4067088605u, 3772741427u, 1482887254u, 1343838111u, 3903140090u, 4195393300u, 1118632049u,
			3749429448u, 1741137837u, 1970407491u, 3452858150u, 2511175536u, 756094997u, 1067759611u, 2266550430u, 449832999u, 2725482306u,
			2965774508u, 142231497u, 2687676222u, 412010587u, 171665333u, 2995192016u, 793786473u, 2548850444u, 2237264098u, 1038456711u,
			1703315409u, 3711623348u, 3482275674u, 1999841343u, 3940814982u, 1381529571u, 1089329165u, 4166106984u, 4029413537u, 1217896388u,
			1512189994u, 3802027855u, 2135519222u, 3354724499u, 3577784189u, 1845280792u, 899665998u, 2367928107u, 2677414085u, 657096608u,
			3137160985u, 37822588u, 284462994u, 2823350519u, 2601801789u, 598228824u, 824021174u, 2309093331u, 343330666u, 2898962447u,
			3195996129u, 113467524u, 1587572946u, 3860600759u, 4104763481u, 1276501820u, 3519211397u, 1769898208u, 2076913422u, 3279374443u,
			3406630818u, 1941006535u, 1627703081u, 3652755532u, 1148164341u, 4241751952u, 3999682686u, 1457141531u, 247015245u, 3053797416u,
			2763059142u, 470583459u, 2178658330u, 963106687u, 735213713u, 2473467892u, 992409347u, 2207944806u, 2435792776u, 697522413u,
			3024379988u, 217581361u, 508405983u, 2800865210u, 4271038444u, 1177467017u, 1419450215u, 3962007554u, 1911572667u, 3377213406u,
			3690561584u, 1665525589u, 1799331996u, 3548628985u, 3241568279u, 2039091058u, 3831314379u, 1558270126u, 1314193216u, 4142438437u,
			2928380019u, 372764438u, 75645176u, 3158189981u, 568925988u, 2572515393u, 2346768303u, 861712586u, 3982079547u, 1441124702u,
			1196457648u, 4293663189u, 1648042348u, 3666298377u, 3358779879u, 1888390786u, 686661332u, 2421291441u, 2196002399u, 978858298u,
			2811169155u, 523464422u, 226935048u, 3040519789u, 3175145892u, 100435649u, 390670639u, 2952089162u, 841119475u, 2325614998u,
			2553003640u, 546822429u, 2029308235u, 3225988654u, 3539796416u, 1782671013u, 4153826844u, 1328167289u, 1570739863u, 3844338162u,
			1298864389u, 4124540512u, 3882013070u, 1608431339u, 3255406162u, 2058742071u, 1744848601u, 3501990332u, 2296328682u, 811816591u,
			584513889u, 2590678532u, 129869501u, 3204563416u, 2914283062u, 352848211u, 494030490u, 2781751807u, 3078325777u, 264757620u,
			2450577869u, 715964072u, 941166918u, 2158327331u, 3636881013u, 1618608400u, 1926213374u, 3396585883u, 1470427426u, 4011365959u,
			4255988137u, 1158766284u, 1984818694u, 3471935843u, 3695453837u, 1693991400u, 4180638033u, 1100160564u, 1395044826u, 3952793279u,
			3019491049u, 189112716u, 435162722u, 2706139399u, 1016811966u, 2217162459u, 2526189877u, 774831696u, 643086745u, 2666061564u,
			2354934034u, 887166583u, 2838900430u, 294275499u, 54519365u, 3145957664u, 3823145334u, 1532818963u, 1240029693u, 4048895640u,
			1820460577u, 3560857924u, 3331051178u, 2117577167u, 3598663992u, 1858283101u, 2088143283u, 3301633750u, 1495127663u, 3785470218u,
			4078182116u, 1269332353u, 332098007u, 2876706482u, 3116540252u, 25085497u, 2628386432u, 605395429u, 916469259u, 2384220526u,
			2254837415u, 1054503362u, 745528876u, 2496903497u, 151290352u, 2981684885u, 2735556987u, 464596510u, 1137851976u, 4218313005u,
			3923506883u, 1365741990u, 3434129695u, 1946996346u, 1723425172u, 3724871409u
		};

		private static readonly uint[] s_crcTable_4 = new uint[256]
		{
			0u, 1029712304u, 2059424608u, 1201699536u, 4118849216u, 3370159984u, 2403399072u, 2988497936u, 812665793u, 219177585u,
			1253054625u, 2010132753u, 3320900865u, 4170237105u, 3207642721u, 2186319825u, 1625331586u, 1568718386u, 438355170u, 658566482u,
			2506109250u, 2818578674u, 4020265506u, 3535817618u, 1351670851u, 1844508147u, 709922595u, 389064339u, 2769320579u, 2557498163u,
			3754961379u, 3803185235u, 3250663172u, 4238411444u, 3137436772u, 2254525908u, 876710340u, 153198708u, 1317132964u, 1944187668u,
			4054934725u, 3436268917u, 2339452837u, 3054575125u, 70369797u, 961670069u, 2129760613u, 1133623509u, 2703341702u, 2621542710u,
			3689016294u, 3867263574u, 1419845190u, 1774270454u, 778128678u, 318858390u, 2438067015u, 2888948471u, 3952189479u, 3606153623u,
			1691440519u, 1504803895u, 504432359u, 594620247u, 1492342857u, 1704161785u, 573770537u, 525542041u, 2910060169u, 2417219385u,
			3618876905u, 3939730521u, 1753420680u, 1440954936u, 306397416u, 790849880u, 2634265928u, 2690882808u, 3888375336u, 3668168600u,
			940822475u, 91481723u, 1121164459u, 2142483739u, 3448989963u, 4042473659u, 3075684971u, 2318603227u, 140739594u, 889433530u,
			1923340138u, 1338244826u, 4259521226u, 3229813626u, 2267247018u, 3124975642u, 2570221389u, 2756861693u, 3824297005u, 3734113693u,
			1823658381u, 1372780605u, 376603373u, 722643805u, 2839690380u, 2485261628u, 3548540908u, 4007806556u, 1556257356u, 1638052860u,
			637716780u, 459464860u, 4191346895u, 3300051327u, 2199040943u, 3195181599u, 206718479u, 825388991u, 1989285231u, 1274166495u,
			3382881038u, 4106388158u, 3009607790u, 2382549470u, 1008864718u, 21111934u, 1189240494u, 2072147742u, 2984685714u, 2357631266u,
			3408323570u, 4131834434u, 1147541074u, 2030452706u, 1051084082u, 63335554u, 2174155603u, 3170292451u, 4216760371u, 3325460867u,
			1947622803u, 1232499747u, 248909555u, 867575619u, 3506841360u, 3966111392u, 2881909872u, 2527485376u, 612794832u, 434546784u,
			1581699760u, 1663499008u, 3782634705u, 3692447073u, 2612412337u, 2799048193u, 351717905u, 697754529u, 1849071985u, 1398190273u,
			1881644950u, 1296545318u, 182963446u, 931652934u, 2242328918u, 3100053734u, 4284967478u, 3255255942u, 1079497815u, 2100821479u,
			983009079u, 133672583u, 3050795671u, 2293717799u, 3474399735u, 4067887175u, 281479188u, 765927844u, 1778867060u, 1466397380u,
			3846680276u, 3626469220u, 2676489652u, 2733102084u, 548881365u, 500656741u, 1517752501u, 1729575173u, 3577210133u, 3898068133u,
			2952246901u, 2459410373u, 3910527195u, 3564487019u, 2480257979u, 2931134987u, 479546907u, 569730987u, 1716854139u, 1530213579u,
			3647316762u, 3825568426u, 2745561210u, 2663766474u, 753206746u, 293940330u, 1445287610u, 1799716618u, 2314567513u, 3029685993u,
			4080348217u, 3461678473u, 2088098201u, 1091956777u, 112560889u, 1003856713u, 3112514712u, 2229607720u, 3276105720u, 4263857736u,
			1275433560u, 1902492648u, 918929720u, 195422344u, 685033439u, 364179055u, 1377080511u, 1869921551u, 3713294623u, 3761522863u,
			2811507327u, 2599689167u, 413436958u, 633644462u, 1650777982u, 1594160846u, 3978570462u, 3494118254u, 2548332990u, 2860797966u,
			1211387997u, 1968470509u, 854852413u, 261368461u, 3182753437u, 2161434413u, 3346310653u, 4195650637u, 2017729436u, 1160000044u,
			42223868u, 1071931724u, 2378480988u, 2963576044u, 4144295484u, 3395602316u
		};

		private static readonly uint[] s_crcTable_5 = new uint[256]
		{
			0u, 3411858341u, 1304994059u, 2257875630u, 2609988118u, 1355649459u, 3596215069u, 486879416u, 3964895853u, 655315400u,
			2711298918u, 1791488195u, 2009251963u, 3164476382u, 973758832u, 4048990933u, 64357019u, 3364540734u, 1310630800u, 2235723829u,
			2554806413u, 1394316072u, 3582976390u, 517157411u, 4018503926u, 618222419u, 2722963965u, 1762783832u, 1947517664u, 3209171269u,
			970744811u, 4068520014u, 128714038u, 3438335635u, 1248109629u, 2167961496u, 2621261600u, 1466012805u, 3522553387u, 447296910u,
			3959392091u, 547575038u, 2788632144u, 1835791861u, 1886307661u, 3140622056u, 1034314822u, 4143626211u, 75106221u, 3475428360u,
			1236444838u, 2196665603u, 2682996155u, 1421317662u, 3525567664u, 427767573u, 3895035328u, 594892389u, 2782995659u, 1857943406u,
			1941489622u, 3101955187u, 1047553757u, 4113347960u, 257428076u, 3288652233u, 1116777319u, 2311878850u, 2496219258u, 1603640287u,
			3640781169u, 308099796u, 3809183745u, 676813732u, 2932025610u, 1704983215u, 2023410199u, 3016104370u, 894593820u, 4262377657u,
			210634999u, 3352484690u, 1095150076u, 2316991065u, 2535410401u, 1547934020u, 3671583722u, 294336591u, 3772615322u, 729897279u,
			2903845777u, 1716123700u, 2068629644u, 2953845545u, 914647431u, 4258839074u, 150212442u, 3282623743u, 1161604689u, 2388688372u,
			2472889676u, 1480171241u, 3735940167u, 368132066u, 3836185911u, 805002898u, 2842635324u, 1647574937u, 2134298401u, 3026852996u,
			855535146u, 4188192143u, 186781121u, 3229539940u, 1189784778u, 2377547631u, 2427670487u, 1542429810u, 3715886812u, 371670393u,
			3882979244u, 741170185u, 2864262823u, 1642462466u, 2095107514u, 3082559007u, 824732849u, 4201955092u, 514856152u, 3589064573u,
			1400419795u, 2552522358u, 2233554638u, 1316849003u, 3370776517u, 62202976u, 4075001525u, 968836368u, 3207280574u, 1954014235u,
			1769133219u, 2720925446u, 616199592u, 4024870413u, 493229635u, 3594175974u, 1353627464u, 2616354029u, 2264355925u, 1303087088u,
			3409966430u, 6498043u, 4046820398u, 979978123u, 3170710821u, 2007099008u, 1789187640u, 2717386141u, 661419827u, 3962610838u,
			421269998u, 3527459403u, 1423225061u, 2676515648u, 2190300152u, 1238466653u, 3477467891u, 68755798u, 4115633027u, 1041448998u,
			3095868040u, 1943789869u, 1860096405u, 2776760880u, 588673182u, 3897205563u, 449450869u, 3516317904u, 1459794558u, 2623431131u,
			2170245475u, 1242006214u, 3432247400u, 131015629u, 4137259288u, 1036337853u, 3142660115u, 1879958454u, 1829294862u, 2790523051u,
			549483013u, 3952910752u, 300424884u, 3669282065u, 1545650111u, 2541513754u, 2323209378u, 1092980487u, 3350330793u, 216870412u,
			4256931033u, 921128828u, 2960342482u, 2066738807u, 1714085583u, 2910195050u, 736264132u, 3770592353u, 306060335u, 3647131530u,
			1610005796u, 2494197377u, 2309971513u, 1123257756u, 3295149874u, 255536279u, 4268596802u, 892423655u, 3013951305u, 2029645036u,
			1711070292u, 2929725425u, 674528607u, 3815288570u, 373562242u, 3709388839u, 1535949449u, 2429577516u, 2379569556u, 1183418929u,
			3223189663u, 188820282u, 4195850735u, 827017802u, 3084859620u, 2089020225u, 1636228089u, 2866415708u, 743340786u, 3876759895u,
			361896217u, 3738094268u, 1482340370u, 2466671543u, 2382584591u, 1163888810u, 3284924932u, 144124321u, 4190215028u, 849168593u,
			3020503679u, 2136336858u, 1649465698u, 2836138695u, 798521449u, 3838094284u
		};

		private static readonly uint[] s_crcTable_6 = new uint[256]
		{
			0u, 2792819636u, 2543784233u, 837294749u, 4098827283u, 1379413927u, 1674589498u, 3316072078u, 871321191u, 2509784531u,
			2758827854u, 34034938u, 3349178996u, 1641505216u, 1346337629u, 4131942633u, 1742642382u, 3249117050u, 4030828007u, 1446413907u,
			2475800797u, 904311657u, 68069876u, 2725880384u, 1412551337u, 4064729373u, 3283010432u, 1708771380u, 2692675258u, 101317902u,
			937551763u, 2442587175u, 3485284764u, 1774858792u, 1478633653u, 4266992385u, 1005723023u, 2642744891u, 2892827814u, 169477906u,
			4233263099u, 1512406095u, 1808623314u, 3451546982u, 136139752u, 2926205020u, 2676114113u, 972376437u, 2825102674u, 236236518u,
			1073525883u, 2576072655u, 1546420545u, 4200303349u, 3417542760u, 1841601500u, 2609703733u, 1039917185u, 202635804u, 2858742184u,
			1875103526u, 3384067218u, 4166835727u, 1579931067u, 1141601657u, 3799809741u, 3549717584u, 1977839588u, 2957267306u, 372464350u,
			668680259u, 2175552503u, 2011446046u, 3516084394u, 3766168119u, 1175200131u, 2209029901u, 635180217u, 338955812u, 2990736784u,
			601221559u, 2242044419u, 3024812190u, 306049834u, 3617246628u, 1911408144u, 1074125965u, 3866285881u, 272279504u, 3058543716u,
			2275784441u, 567459149u, 3832906691u, 1107462263u, 1944752874u, 3583875422u, 2343980261u, 767641425u, 472473036u, 3126744696u,
			2147051766u, 3649987394u, 3899029983u, 1309766251u, 3092841090u, 506333494u, 801510315u, 2310084639u, 1276520081u, 3932237093u,
			3683203000u, 2113813516u, 3966292011u, 1243601823u, 2079834370u, 3716205238u, 405271608u, 3192979340u, 2411259153u, 701492901u,
			3750207052u, 2045810168u, 1209569125u, 4000285905u, 734575199u, 2378150379u, 3159862134u, 438345922u, 2283203314u, 778166598u,
			529136603u, 3120492655u, 2086260449u, 3660498261u, 3955679176u, 1303499900u, 3153699989u, 495890209u, 744928700u, 2316418568u,
			1337360518u, 3921775410u, 3626602927u, 2120129051u, 4022892092u, 1237286280u, 2018993941u, 3726666913u, 461853231u, 3186645403u,
			2350400262u, 711936178u, 3693557851u, 2052076527u, 1270360434u, 3989775046u, 677911624u, 2384402428u, 3220639073u, 427820757u,
			1202443118u, 3789347034u, 3493118535u, 1984154099u, 3018127229u, 362020041u, 612099668u, 2181885408u, 1950653705u, 3526596285u,
			3822816288u, 1168934804u, 2148251930u, 645706414u, 395618355u, 2984485767u, 544559008u, 2248295444u, 3085590153u, 295523645u,
			3560598451u, 1917673479u, 1134918298u, 3855773998u, 328860103u, 3052210803u, 2214924526u, 577903450u, 3889505748u, 1101147744u,
			1883911421u, 3594338121u, 3424493451u, 1785369663u, 1535282850u, 4260726038u, 944946072u, 2653270060u, 2949491377u, 163225861u,
			4294103532u, 1501944408u, 1752023237u, 3457862513u, 196998655u, 2915761739u, 2619532502u, 978710370u, 2881684293u, 229902577u,
			1012666988u, 2586515928u, 1603020630u, 4193987810u, 3356702335u, 1852063179u, 2553040162u, 1046169238u, 263412747u, 2848217023u,
			1818454321u, 3390333573u, 4227627032u, 1569420204u, 60859927u, 2782375331u, 2487203646u, 843627658u, 4159668740u, 1368951216u,
			1617990445u, 3322386585u, 810543216u, 2520310724u, 2815490393u, 27783917u, 3288386659u, 1652017111u, 1402985802u, 4125677310u,
			1685994201u, 3255382381u, 4091620336u, 1435902020u, 2419138250u, 910562686u, 128847843u, 2715354199u, 1469150398u, 4058414858u,
			3222168983u, 1719234083u, 2749255853u, 94984985u, 876691844u, 2453031472u
		};

		private static readonly uint[] s_crcTable_7 = new uint[256]
		{
			0u, 3433693342u, 1109723005u, 2391738339u, 2219446010u, 1222643300u, 3329165703u, 180685081u, 3555007413u, 525277995u,
			2445286600u, 1567235158u, 1471092047u, 2600801745u, 361370162u, 3642757804u, 2092642603u, 2953916853u, 1050555990u, 4063508168u,
			4176560081u, 878395215u, 3134470316u, 1987983410u, 2942184094u, 1676945920u, 3984272867u, 567356797u, 722740324u, 3887998202u,
			1764827929u, 2778407815u, 4185285206u, 903635656u, 3142804779u, 2012833205u, 2101111980u, 2979425330u, 1058630609u, 4088621903u,
			714308067u, 3862526333u, 1756790430u, 2753330688u, 2933487385u, 1651734407u, 3975966820u, 542535930u, 2244825981u, 1231508451u,
			3353891840u, 188896414u, 25648519u, 3442302233u, 1134713594u, 2399689316u, 1445480648u, 2592229462u, 336416693u, 3634843435u,
			3529655858u, 516441772u, 2420588879u, 1559052753u, 698204909u, 3845636723u, 1807271312u, 2803025166u, 2916600855u, 1635634313u,
			4025666410u, 593021940u, 4202223960u, 919787974u, 3093159461u, 1962401467u, 2117261218u, 2996361020u, 1008193759u, 4038971457u,
			1428616134u, 2576151384u, 386135227u, 3685348389u, 3513580860u, 499580322u, 2471098945u, 1608776415u, 2260985971u, 1248454893u,
			3303468814u, 139259792u, 42591881u, 3458459159u, 1085071860u, 2349261162u, 3505103035u, 474062885u, 2463016902u, 1583654744u,
			1419882049u, 2550902495u, 377792828u, 3660491170u, 51297038u, 3483679632u, 1093385331u, 2374089965u, 2269427188u, 1273935210u,
			3311514249u, 164344343u, 2890961296u, 1627033870u, 4000683757u, 585078387u, 672833386u, 3836780532u, 1782552599u, 2794821769u,
			2142603813u, 3005188795u, 1032883544u, 4047146438u, 4227826911u, 928351297u, 3118105506u, 1970307900u, 1396409818u, 2677114180u,
			287212199u, 3719594553u, 3614542624u, 467372990u, 2505346141u, 1509854403u, 2162073199u, 1282711281u, 3271268626u, 240228748u,
			76845205u, 3359543307u, 1186043880u, 2317064054u, 796964081u, 3811226735u, 1839575948u, 2702160658u, 2882189835u, 1734392469u,
			3924802934u, 625327592u, 4234522436u, 818917338u, 3191908409u, 1927981223u, 2016387518u, 3028656416u, 973776579u, 4137723485u,
			2857232268u, 1726474002u, 3899187441u, 616751215u, 772270454u, 3803048424u, 1814228491u, 2693328533u, 2041117753u, 3036871847u,
			999160644u, 4146592730u, 4259508931u, 826864221u, 3217552830u, 1936586016u, 3606501031u, 442291769u, 2496909786u, 1484378436u,
			1388107869u, 2652297411u, 278519584u, 3694387134u, 85183762u, 3384397196u, 1194773103u, 2342308593u, 2170143720u, 1307820918u,
			3279733909u, 265733131u, 2057717559u, 3054258089u, 948125770u, 4096344276u, 4276898253u, 843467091u, 3167309488u, 1885556270u,
			2839764098u, 1709792284u, 3949353983u, 667704161u, 755585656u, 3785577190u, 1865176325u, 2743489947u, 102594076u, 3401021058u,
			1144549729u, 2291298815u, 2186770662u, 1325234296u, 3228729243u, 215514885u, 3589828009u, 424832311u, 2547870420u, 1534552650u,
			1370645331u, 2635621325u, 328688686u, 3745342640u, 2211456353u, 1333405183u, 3254067740u, 224338562u, 127544219u, 3408931589u,
			1170156774u, 2299866232u, 1345666772u, 2627681866u, 303053225u, 3736746295u, 3565105198u, 416624816u, 2522494803u, 1525692365u,
			4285207626u, 868291796u, 3176010551u, 1910772649u, 2065767088u, 3079346734u, 956571085u, 4121828691u, 747507711u, 3760459617u,
			1856702594u, 2717976604u, 2831417605u, 1684930971u, 3940615800u, 642451174u
		};

		public static uint UpdateCrc32(uint crc32, byte[] buffer, int offset, int length)
		{
			return ManagedCrc32(crc32, buffer, offset, length);
		}

		private static uint ManagedCrc32(uint crc32, byte[] buffer, int offset, int length)
		{
			uint num = 0u;
			crc32 ^= 0xFFFFFFFFu;
			int num2 = length / 8 * 8;
			int num3 = length - num2;
			for (int i = 0; i < num2 / 8; i++)
			{
				crc32 ^= (uint)(buffer[offset] | (buffer[offset + 1] << 8) | (buffer[offset + 2] << 16) | (buffer[offset + 3] << 24));
				offset += 4;
				uint num4 = s_crcTable_7[crc32 & 0xFF] ^ s_crcTable_6[(crc32 >> 8) & 0xFF];
				uint num5 = crc32 >> 16;
				crc32 = num4 ^ s_crcTable_5[num5 & 0xFF] ^ s_crcTable_4[(num5 >> 8) & 0xFF];
				num = (uint)(buffer[offset] | (buffer[offset + 1] << 8) | (buffer[offset + 2] << 16) | (buffer[offset + 3] << 24));
				offset += 4;
				num4 = s_crcTable_3[num & 0xFF] ^ s_crcTable_2[(num >> 8) & 0xFF];
				num5 = num >> 16;
				crc32 ^= num4 ^ s_crcTable_1[num5 & 0xFF] ^ s_crcTable_0[(num5 >> 8) & 0xFF];
			}
			for (int j = 0; j < num3; j++)
			{
				crc32 = s_crcTable_0[(crc32 ^ buffer[offset++]) & 0xFF] ^ (crc32 >> 8);
			}
			crc32 ^= 0xFFFFFFFFu;
			return crc32;
		}
	}
	public class ZipArchive : IDisposable
	{
		private Stream _archiveStream;

		private ZipArchiveEntry _archiveStreamOwner;

		private BinaryReader _archiveReader;

		private ZipArchiveMode _mode;

		private List<ZipArchiveEntry> _entries;

		private ReadOnlyCollection<ZipArchiveEntry> _entriesCollection;

		private Dictionary<string, ZipArchiveEntry> _entriesDictionary;

		private bool _readEntries;

		private bool _leaveOpen;

		private long _centralDirectoryStart;

		private bool _isDisposed;

		private uint _numberOfThisDisk;

		private long _expectedNumberOfEntries;

		private Stream _backingStream;

		private byte[] _archiveComment;

		private Encoding _entryNameEncoding;

		public ReadOnlyCollection<ZipArchiveEntry> Entries
		{
			get
			{
				if (_mode == ZipArchiveMode.Create)
				{
					throw new NotSupportedException(System.SR.EntriesInCreateMode);
				}
				ThrowIfDisposed();
				EnsureCentralDirectoryRead();
				return _entriesCollection;
			}
		}

		public ZipArchiveMode Mode => _mode;

		internal BinaryReader ArchiveReader => _archiveReader;

		internal Stream ArchiveStream => _archiveStream;

		internal uint NumberOfThisDisk => _numberOfThisDisk;

		internal Encoding EntryNameEncoding
		{
			get
			{
				return _entryNameEncoding;
			}
			private set
			{
				if (value != null && (value.Equals(Encoding.BigEndianUnicode) || value.Equals(Encoding.Unicode)))
				{
					throw new ArgumentException(System.SR.EntryNameEncodingNotSupported, "EntryNameEncoding");
				}
				_entryNameEncoding = value;
			}
		}

		public ZipArchive(Stream stream)
			: this(stream, ZipArchiveMode.Read, leaveOpen: false, null)
		{
		}

		public ZipArchive(Stream stream, ZipArchiveMode mode)
			: this(stream, mode, leaveOpen: false, null)
		{
		}

		public ZipArchive(Stream stream, ZipArchiveMode mode, bool leaveOpen)
			: this(stream, mode, leaveOpen, null)
		{
		}

		public ZipArchive(Stream stream, ZipArchiveMode mode, bool leaveOpen, Encoding entryNameEncoding)
		{
			if (stream == null)
			{
				throw new ArgumentNullException("stream");
			}
			EntryNameEncoding = entryNameEncoding;
			Init(stream, mode, leaveOpen);
		}

		public ZipArchiveEntry CreateEntry(string entryName)
		{
			return DoCreateEntry(entryName, null);
		}

		public ZipArchiveEntry CreateEntry(string entryName, CompressionLevel compressionLevel)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return DoCreateEntry(entryName, compressionLevel);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (!disposing || _isDisposed)
			{
				return;
			}
			try
			{
				switch (_mode)
				{
				case ZipArchiveMode.Read:
					return;
				}
				WriteFile();
			}
			finally
			{
				CloseStreams();
				_isDisposed = true;
			}
		}

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

		public ZipArchiveEntry GetEntry(string entryName)
		{
			if (entryName == null)
			{
				throw new ArgumentNullException("entryName");
			}
			if (_mode == ZipArchiveMode.Create)
			{
				throw new NotSupportedException(System.SR.EntriesInCreateMode);
			}
			EnsureCentralDirectoryRead();
			_entriesDictionary.TryGetValue(entryName, out var value);
			return value;
		}

		private ZipArchiveEntry DoCreateEntry(string entryName, CompressionLevel? compressionLevel)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (entryName == null)
			{
				throw new ArgumentNullException("entryName");
			}
			if (string.IsNullOrEmpty(entryName))
			{
				throw new ArgumentException(System.SR.CannotBeEmpty, "entryName");
			}
			if (_mode == ZipArchiveMode.Read)
			{
				throw new NotSupportedException(System.SR.CreateInReadMode);
			}
			ThrowIfDisposed();
			ZipArchiveEntry zipArchiveEntry = (compressionLevel.HasValue ? new ZipArchiveEntry(this, entryName, compressionLevel.Value) : new ZipArchiveEntry(this, entryName));
			AddEntry(zipArchiveEntry);
			return zipArchiveEntry;
		}

		internal void AcquireArchiveStream(ZipArchiveEntry entry)
		{
			if (_archiveStreamOwner != null)
			{
				if (_archiveStreamOwner.EverOpenedForWrite)
				{
					throw new IOException(System.SR.CreateModeCreateEntryWhileOpen);
				}
				_archiveStreamOwner.WriteAndFinishLocalEntry();
			}
			_archiveStreamOwner = entry;
		}

		private void AddEntry(ZipArchiveEntry entry)
		{
			_entries.Add(entry);
			string fullName = entry.FullName;
			if (!_entriesDictionary.ContainsKey(fullName))
			{
				_entriesDictionary.Add(fullName, entry);
			}
		}

		internal bool IsStillArchiveStreamOwner(ZipArchiveEntry entry)
		{
			return _archiveStreamOwner == entry;
		}

		internal void ReleaseArchiveStream(ZipArchiveEntry entry)
		{
			_archiveStreamOwner = null;
		}

		internal void RemoveEntry(ZipArchiveEntry entry)
		{
			_entries.Remove(entry);
			_entriesDictionary.Remove(entry.FullName);
		}

		internal void ThrowIfDisposed()
		{
			if (_isDisposed)
			{
				throw new ObjectDisposedException(GetType().ToString());
			}
		}

		private void CloseStreams()
		{
			if (!_leaveOpen)
			{
				_archiveStream.Dispose();
				if (_backingStream != null)
				{
					_backingStream.Dispose();
				}
				if (_archiveReader != null)
				{
					_archiveReader.Dispose();
				}
			}
			else if (_backingStream != null)
			{
				_archiveStream.Dispose();
			}
		}

		private void EnsureCentralDirectoryRead()
		{
			if (!_readEntries)
			{
				ReadCentralDirectory();
				_readEntries = true;
			}
		}

		private void Init(Stream stream, ZipArchiveMode mode, bool leaveOpen)
		{
			Stream stream2 = null;
			try
			{
				_backingStream = null;
				switch (mode)
				{
				case ZipArchiveMode.Create:
					if (!stream.CanWrite)
					{
						throw new ArgumentException(System.SR.CreateModeCapabilities);
					}
					break;
				case ZipArchiveMode.Read:
					if (!stream.CanRead)
					{
						throw new ArgumentException(System.SR.ReadModeCapabilities);
					}
					if (!stream.CanSeek)
					{
						_backingStream = stream;
						stream2 = (stream = new MemoryStream());
						_backingStream.CopyTo(stream);
						stream.Seek(0L, SeekOrigin.Begin);
					}
					break;
				case ZipArchiveMode.Update:
					if (!stream.CanRead || !stream.CanWrite || !stream.CanSeek)
					{
						throw new ArgumentException(System.SR.UpdateModeCapabilities);
					}
					break;
				default:
					throw new ArgumentOutOfRangeException("mode");
				}
				_mode = mode;
				_archiveStream = stream;
				_archiveStreamOwner = null;
				if (mode == ZipArchiveMode.Create)
				{
					_archiveReader = null;
				}
				else
				{
					_archiveReader = new BinaryReader(stream);
				}
				_entries = new List<ZipArchiveEntry>();
				_entriesCollection = new ReadOnlyCollection<ZipArchiveEntry>(_entries);
				_entriesDictionary = new Dictionary<string, ZipArchiveEntry>();
				_readEntries = false;
				_leaveOpen = leaveOpen;
				_centralDirectoryStart = 0L;
				_isDisposed = false;
				_numberOfThisDisk = 0u;
				_archiveComment = null;
				switch (mode)
				{
				case ZipArchiveMode.Create:
					_readEntries = true;
					return;
				case ZipArchiveMode.Read:
					ReadEndOfCentralDirectory();
					return;
				}
				if (_archiveStream.Length == 0L)
				{
					_readEntries = true;
					return;
				}
				ReadEndOfCentralDirectory();
				EnsureCentralDirectoryRead();
				foreach (ZipArchiveEntry entry in _entries)
				{
					entry.ThrowIfNotOpenable(needToUncompress: false, needToLoadIntoMemory: true);
				}
			}
			catch
			{
				stream2?.Dispose();
				throw;
			}
		}

		private void ReadCentralDirectory()
		{
			try
			{
				_archiveStream.Seek(_centralDirectoryStart, SeekOrigin.Begin);
				long num = 0L;
				bool saveExtraFieldsAndComments = Mode == ZipArchiveMode.Update;
				System.IO.Compression.ZipCentralDirectoryFileHeader header;
				while (System.IO.Compression.ZipCentralDirectoryFileHeader.TryReadBlock(_archiveReader, saveExtraFieldsAndComments, out header))
				{
					AddEntry(new ZipArchiveEntry(this, header));
					num++;
				}
				if (num != _expectedNumberOfEntries)
				{
					throw new InvalidDataException(System.SR.NumEntriesWrong);
				}
			}
			catch (EndOfStreamException p)
			{
				throw new InvalidDataException(System.SR.Format(System.SR.CentralDirectoryInvalid, p));
			}
		}

		private void ReadEndOfCentralDirectory()
		{
			try
			{
				_archiveStream.Seek(-18L, SeekOrigin.End);
				if (!System.IO.Compression.ZipHelper.SeekBackwardsToSignature(_archiveStream, 101010256u))
				{
					throw new InvalidDataException(System.SR.EOCDNotFound);
				}
				long position = _archiveStream.Position;
				System.IO.Compression.ZipEndOfCentralDirectoryBlock eocdBlock;
				bool flag = System.IO.Compression.ZipEndOfCentralDirectoryBlock.TryReadBlock(_archiveReader, out eocdBlock);
				if (eocdBlock.NumberOfThisDisk != eocdBlock.NumberOfTheDiskWithTheStartOfTheCentralDirectory)
				{
					throw new InvalidDataException(System.SR.SplitSpanned);
				}
				_numberOfThisDisk = eocdBlock.NumberOfThisDisk;
				_centralDirectoryStart = eocdBlock.OffsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber;
				if (eocdBlock.NumberOfEntriesInTheCentralDirectory != eocdBlock.NumberOfEntriesInTheCentralDirectoryOnThisDisk)
				{
					throw new InvalidDataException(System.SR.SplitSpanned);
				}
				_expectedNumberOfEntries = eocdBlock.NumberOfEntriesInTheCentralDirectory;
				if (_mode == ZipArchiveMode.Update)
				{
					_archiveComment = eocdBlock.ArchiveComment;
				}
				if (eocdBlock.NumberOfThisDisk == ushort.MaxValue || eocdBlock.OffsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber == uint.MaxValue || eocdBlock.NumberOfEntriesInTheCentralDirectory == ushort.MaxValue)
				{
					_archiveStream.Seek(position - 16, SeekOrigin.Begin);
					if (System.IO.Compression.ZipHelper.SeekBackwardsToSignature(_archiveStream, 117853008u))
					{
						System.IO.Compression.Zip64EndOfCentralDirectoryLocator zip64EOCDLocator;
						bool flag2 = System.IO.Compression.Zip64EndOfCentralDirectoryLocator.TryReadBlock(_archiveReader, out zip64EOCDLocator);
						if (zip64EOCDLocator.OffsetOfZip64EOCD > long.MaxValue)
						{
							throw new InvalidDataException(System.SR.FieldTooBigOffsetToZip64EOCD);
						}
						long offsetOfZip64EOCD = (long)zip64EOCDLocator.OffsetOfZip64EOCD;
						_archiveStream.Seek(offsetOfZip64EOCD, SeekOrigin.Begin);
						if (!System.IO.Compression.Zip64EndOfCentralDirectoryRecord.TryReadBlock(_archiveReader, out var zip64EOCDRecord))
						{
							throw new InvalidDataException(System.SR.Zip64EOCDNotWhereExpected);
						}
						_numberOfThisDisk = zip64EOCDRecord.NumberOfThisDisk;
						if (zip64EOCDRecord.NumberOfEntriesTotal > long.MaxValue)
						{
							throw new InvalidDataException(System.SR.FieldTooBigNumEntries);
						}
						if (zip64EOCDRecord.OffsetOfCentralDirectory > long.MaxValue)
						{
							throw new InvalidDataException(System.SR.FieldTooBigOffsetToCD);
						}
						if (zip64EOCDRecord.NumberOfEntriesTotal != zip64EOCDRecord.NumberOfEntriesOnThisDisk)
						{
							throw new InvalidDataException(System.SR.SplitSpanned);
						}
						_expectedNumberOfEntries = (long)zip64EOCDRecord.NumberOfEntriesTotal;
						_centralDirectoryStart = (long)zip64EOCDRecord.OffsetOfCentralDirectory;
					}
				}
				if (_centralDirectoryStart > _archiveStream.Length)
				{
					throw new InvalidDataException(System.SR.FieldTooBigOffsetToCD);
				}
			}
			catch (EndOfStreamException innerException)
			{
				throw new InvalidDataException(System.SR.CDCorrupt, innerException);
			}
			catch (IOException innerException2)
			{
				throw new InvalidDataException(System.SR.CDCorrupt, innerException2);
			}
		}

		private void WriteFile()
		{
			if (_mode == ZipArchiveMode.Update)
			{
				List<ZipArchiveEntry> list = new List<ZipArchiveEntry>();
				foreach (ZipArchiveEntry entry in _entries)
				{
					if (!entry.LoadLocalHeaderExtraFieldAndCompressedBytesIfNeeded())
					{
						list.Add(entry);
					}
				}
				foreach (ZipArchiveEntry item in list)
				{
					item.Delete();
				}
				_archiveStream.Seek(0L, SeekOrigin.Begin);
				_archiveStream.SetLength(0L);
			}
			foreach (ZipArchiveEntry entry2 in _entries)
			{
				entry2.WriteAndFinishLocalEntry();
			}
			long position = _archiveStream.Position;
			foreach (ZipArchiveEntry entry3 in _entries)
			{
				entry3.WriteCentralDirectoryFileHeader();
			}
			long sizeOfCentralDirectory = _archiveStream.Position - position;
			WriteArchiveEpilogue(position, sizeOfCentralDirectory);
		}

		private void WriteArchiveEpilogue(long startOfCentralDirectory, long sizeOfCentralDirectory)
		{
			bool flag = false;
			if (startOfCentralDirectory >= uint.MaxValue || sizeOfCentralDirectory >= uint.MaxValue || _entries.Count >= 65535)
			{
				flag = true;
			}
			if (flag)
			{
				long position = _archiveStream.Position;
				System.IO.Compression.Zip64EndOfCentralDirectoryRecord.WriteBlock(_archiveStream, _entries.Count, startOfCentralDirectory, sizeOfCentralDirectory);
				System.IO.Compression.Zip64EndOfCentralDirectoryLocator.WriteBlock(_archiveStream, position);
			}
			System.IO.Compression.ZipEndOfCentralDirectoryBlock.WriteBlock(_archiveStream, _entries.Count, startOfCentralDirectory, sizeOfCentralDirectory, _archiveComment);
		}
	}
	public class ZipArchiveEntry
	{
		private class DirectToArchiveWriterStream : Stream
		{
			private long _position;

			private System.IO.Compression.CheckSumAndSizeWriteStream _crcSizeStream;

			private bool _everWritten;

			private bool _isDisposed;

			private ZipArchiveEntry _entry;

			private bool _usedZip64inLH;

			private bool _canWrite;

			public override long Length
			{
				get
				{
					ThrowIfDisposed();
					throw new NotSupportedException(System.SR.SeekingNotSupported);
				}
			}

			public override long Position
			{
				get
				{
					ThrowIfDisposed();
					return _position;
				}
				set
				{
					ThrowIfDisposed();
					throw new NotSupportedException(System.SR.SeekingNotSupported);
				}
			}

			public override bool CanRead => false;

			public override bool CanSeek => false;

			public override bool CanWrite => _canWrite;

			public DirectToArchiveWriterStream(System.IO.Compression.CheckSumAndSizeWriteStream crcSizeStream, ZipArchiveEntry entry)
			{
				_position = 0L;
				_crcSizeStream = crcSizeStream;
				_everWritten = false;
				_isDisposed = false;
				_entry = entry;
				_usedZip64inLH = false;
				_canWrite = true;
			}

			private void ThrowIfDisposed()
			{
				if (_isDisposed)
				{
					throw new ObjectDisposedException(GetType().ToString(), System.SR.HiddenStreamName);
				}
			}

			public override int Read(byte[] buffer, int offset, int count)
			{
				ThrowIfDisposed();
				throw new NotSupportedException(System.SR.ReadingNotSupported);
			}

			public override long Seek(long offset, SeekOrigin origin)
			{
				ThrowIfDisposed();
				throw new NotSupportedException(System.SR.SeekingNotSupported);
			}

			public override void SetLength(long value)
			{
				ThrowIfDisposed();
				throw new NotSupportedException(System.SR.SetLengthRequiresSeekingAndWriting);
			}

			public override void Write(byte[] buffer, int offset, int count)
			{
				if (buffer == null)
				{
					throw new ArgumentNullException("buffer");
				}
				if (offset < 0)
				{
					throw new ArgumentOutOfRangeException("offset", System.SR.ArgumentNeedNonNegative);
				}
				if (count < 0)
				{
					throw new ArgumentOutOfRangeException("count", System.SR.ArgumentNeedNonNegative);
				}
				if (buffer.Length - offset < count)
				{
					throw new ArgumentException(System.SR.OffsetLengthInvalid);
				}
				ThrowIfDisposed();
				if (count != 0)
				{
					if (!_everWritten)
					{
						_everWritten = true;
						_usedZip64inLH = _entry.WriteLocalFileHeader(isEmptyFile: false);
					}
					_crcSizeStream.Write(buffer, offset, count);
					_position += count;
				}
			}

			public override void Flush()
			{
				ThrowIfDisposed();
				_crcSizeStream.Flush();
			}

			protected override void Dispose(bool disposing)
			{
				if (disposing && !_isDisposed)
				{
					_crcSizeStream.Dispose();
					if (!_everWritten)
					{
						_entry.WriteLocalFileHeader(isEmptyFile: true);
					}
					else if (_entry._archive.ArchiveStream.CanSeek)
					{
						_entry.WriteCrcAndSizesInLocalHeader(_usedZip64inLH);
					}
					else
					{
						_entry.WriteDataDescriptor();
					}
					_canWrite = false;
					_isDisposed = true;
				}
				base.Dispose(disposing);
			}
		}

		[Flags]
		private enum BitFlagValues : ushort
		{
			DataDescriptor = 8,
			UnicodeFileName = 0x800
		}

		internal enum CompressionMethodValues : ushort
		{
			Stored = 0,
			Deflate = 8,
			Deflate64 = 9,
			BZip2 = 12,
			LZMA = 14
		}

		private enum OpenableValues
		{
			Openable,
			FileNonExistent,
			FileTooLarge
		}

		private const ushort DefaultVersionToExtract = 10;

		private const int MaxSingleBufferSize = 2147483591;

		private ZipArchive _archive;

		private readonly bool _originallyInArchive;

		private readonly int _diskNumberStart;

		private readonly System.IO.Compression.ZipVersionMadeByPlatform _versionMadeByPlatform;

		private System.IO.Compression.ZipVersionNeededValues _versionMadeBySpecification;

		private System.IO.Compression.ZipVersionNeededValues _versionToExtract;

		private BitFlagValues _generalPurposeBitFlag;

		private CompressionMethodValues _storedCompressionMethod;

		private DateTimeOffset _lastModified;

		private long _compressedSize;

		private long _uncompressedSize;

		private long _offsetOfLocalHeader;

		private long? _storedOffsetOfCompressedData;

		private uint _crc32;

		private byte[][] _compressedBytes;

		private MemoryStream _storedUncompressedData;

		private bool _currentlyOpenForWrite;

		private bool _everOpenedForWrite;

		private Stream _outstandingWriteStream;

		private string _storedEntryName;

		private byte[] _storedEntryNameBytes;

		private List<System.IO.Compression.ZipGenericExtraField> _cdUnknownExtraFields;

		private List<System.IO.Compression.ZipGenericExtraField> _lhUnknownExtraFields;

		private byte[] _fileComment;

		private CompressionLevel? _compressionLevel;

		private static readonly bool s_allowLargeZipArchiveEntriesInUpdateMode = IntPtr.Size > 4;

		internal const System.IO.Compression.ZipVersionMadeByPlatform CurrentZipPlatform = System.IO.Compression.ZipVersionMadeByPlatform.Windows;

		public ZipArchive Archive => _archive;

		public long CompressedLength
		{
			get
			{
				if (_everOpenedForWrite)
				{
					throw new InvalidOperationException(System.SR.LengthAfterWrite);
				}
				return _compressedSize;
			}
		}

		public string FullName
		{
			get
			{
				return _storedEntryName;
			}
			private set
			{
				if (value == null)
				{
					throw new ArgumentNullException("FullName");
				}
				_storedEntryNameBytes = EncodeEntryName(value, out var isUTF);
				_storedEntryName = value;
				if (isUTF)
				{
					_generalPurposeBitFlag |= BitFlagValues.UnicodeFileName;
				}
				else
				{
					_generalPurposeBitFlag &= ~BitFlagValues.UnicodeFileName;
				}
				if (ParseFileName(value, _versionMadeByPlatform) == "")
				{
					VersionToExtractAtLeast(System.IO.Compression.ZipVersionNeededValues.ExplicitDirectory);
				}
			}
		}

		public DateTimeOffset LastWriteTime
		{
			get
			{
				return _lastModified;
			}
			set
			{
				ThrowIfInvalidArchive();
				if (_archive.Mode == ZipArchiveMode.Read)
				{
					throw new NotSupportedException(System.SR.ReadOnlyArchive);
				}
				if (_archive.Mode == ZipArchiveMode.Create && _everOpenedForWrite)
				{
					throw new IOException(System.SR.FrozenAfterWrite);
				}
				if (value.DateTime.Year < 1980 || value.DateTime.Year > 2107)
				{
					throw new ArgumentOutOfRangeException("value", System.SR.DateTimeOutOfRange);
				}
				_lastModified = value;
			}
		}

		public long Length
		{
			get
			{
				if (_everOpenedForWrite)
				{
					throw new InvalidOperationException(System.SR.LengthAfterWrite);
				}
				return _uncompressedSize;
			}
		}

		public string Name => ParseFileName(FullName, _versionMadeByPlatform);

		internal bool EverOpenedForWrite => _everOpenedForWrite;

		private long OffsetOfCompressedData
		{
			get
			{
				if (!_storedOffsetOfCompressedData.HasValue)
				{
					_archive.ArchiveStream.Seek(_offsetOfLocalHeader, SeekOrigin.Begin);
					if (!System.IO.Compression.ZipLocalFileHeader.TrySkipBlock(_archive.ArchiveReader))
					{
						throw new InvalidDataException(System.SR.LocalFileHeaderCorrupt);
					}
					_storedOffsetOfCompressedData = _archive.ArchiveStream.Position;
				}
				return _storedOffsetOfCompressedData.Value;
			}
		}

		private MemoryStream UncompressedData
		{
			get
			{
				if (_storedUncompressedData == null)
				{
					_storedUncompressedData = new MemoryStream((int)_uncompressedSize);
					if (_originallyInArchive)
					{
						using Stream stream = OpenInReadMode(checkOpenable: false);
						try
						{
							stream.CopyTo(_storedUncompressedData);
						}
						catch (InvalidDataException)
						{
							_storedUncompressedData.Dispose();
							_storedUncompressedData = null;
							_currentlyOpenForWrite = false;
							_everOpenedForWrite = false;
							throw;
						}
					}
					CompressionMethod = CompressionMethodValues.Deflate;
				}
				return _storedUncompressedData;
			}
		}

		private CompressionMethodValues CompressionMethod
		{
			get
			{
				return _storedCompressionMethod;
			}
			set
			{
				switch (value)
				{
				case CompressionMethodValues.Deflate:
					VersionToExtractAtLeast(System.IO.Compression.ZipVersionNeededValues.ExplicitDirectory);
					break;
				case CompressionMethodValues.Deflate64:
					VersionToExtractAtLeast(System.IO.Compression.ZipVersionNeededValues.Deflate64);
					break;
				}
				_storedCompressionMethod = value;
			}
		}

		internal ZipArchiveEntry(ZipArchive archive, System.IO.Compression.ZipCentralDirectoryFileHeader cd, CompressionLevel compressionLevel)
			: this(archive, cd)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			_compressionLevel = compressionLevel;
		}

		internal ZipArchiveEntry(ZipArchive archive, System.IO.Compression.ZipCentralDirectoryFileHeader cd)
		{
			_archive = archive;
			_originallyInArchive = true;
			_diskNumberStart = cd.DiskNumberStart;
			_versionMadeByPlatform = (System.IO.Compression.ZipVersionMadeByPlatform)cd.VersionMadeByCompatibility;
			_versionMadeBySpecification = (System.IO.Compression.ZipVersionNeededValues)cd.VersionMadeBySpecification;
			_versionToExtract = (System.IO.Compression.ZipVersionNeededValues)cd.VersionNeededToExtract;
			_generalPurposeBitFlag = (BitFlagValues)cd.GeneralPurposeBitFlag;
			CompressionMethod = (CompressionMethodValues)cd.CompressionMethod;
			_lastModified = new DateTimeOffset(System.IO.Compression.ZipHelper.DosTimeToDateTime(cd.LastModified));
			_compressedSize = cd.CompressedSize;
			_uncompressedSize = cd.UncompressedSize;
			_offsetOfLocalHeader = cd.RelativeOffsetOfLocalHeader;
			_storedOffsetOfCompressedData = null;
			_crc32 = cd.Crc32;
			_compressedBytes = null;
			_storedUncompressedData = null;
			_currentlyOpenForWrite = false;
			_everOpenedForWrite = false;
			_outstandingWriteStream = null;
			FullName = DecodeEntryName(cd.Filename);
			_lhUnknownExtraFields = null;
			_cdUnknownExtraFields = cd.ExtraFields;
			_fileComment = cd.FileComment;
			_compressionLevel = null;
		}

		internal ZipArchiveEntry(ZipArchive archive, string entryName, CompressionLevel compressionLevel)
			: this(archive, entryName)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			_compressionLevel = compressionLevel;
		}

		internal ZipArchiveEntry(ZipArchive archive, string entryName)
		{
			_archive = archive;
			_originallyInArchive = false;
			_diskNumberStart = 0;
			_versionMadeByPlatform = System.IO.Compression.ZipVersionMadeByPlatform.Windows;
			_versionMadeBySpecification = System.IO.Compression.ZipVersionNeededValues.Default;
			_versionToExtract = System.IO.Compression.ZipVersionNeededValues.Default;
			_generalPurposeBitFlag = (BitFlagValues)0;
			CompressionMethod = CompressionMethodValues.Deflate;
			_lastModified = DateTimeOffset.Now;
			_compressedSize = 0L;
			_uncompressedSize = 0L;
			_offsetOfLocalHeader = 0L;
			_storedOffsetOfCompressedData = null;
			_crc32 = 0u;
			_compressedBytes = null;
			_storedUncompressedData = null;
			_currentlyOpenForWrite = false;
			_everOpenedForWrite = false;
			_outstandingWriteStream = null;
			FullName = entryName;
			_cdUnknownExtraFields = null;
			_lhUnknownExtraFields = null;
			_fileComment = null;
			_compressionLevel = null;
			if (_storedEntryNameBytes.Length > 65535)
			{
				throw new ArgumentException(System.SR.EntryNamesTooLong);
			}
			if (_archive.Mode == ZipArchiveMode.Create)
			{
				_archive.AcquireArchiveStream(this);
			}
		}

		public void Delete()
		{
			if (_archive != null)
			{
				if (_currentlyOpenForWrite)
				{
					throw new IOException(System.SR.DeleteOpenEntry);
				}
				if (_archive.Mode != ZipArchiveMode.Update)
				{
					throw new NotSupportedException(System.SR.DeleteOnlyInUpdate);
				}
				_archive.ThrowIfDisposed();
				_archive.RemoveEntry(this);
				_archive = null;
				UnloadStreams();
			}
		}

		public Stream Open()
		{
			ThrowIfInvalidArchive();
			return _archive.Mode switch
			{
				ZipArchiveMode.Read => OpenInReadMode(checkOpenable: true), 
				ZipArchiveMode.Create => OpenInWriteMode(), 
				_ => OpenInUpdateMode(), 
			};
		}

		public override string ToString()
		{
			return FullName;
		}

		private string DecodeEntryName(byte[] entryNameBytes)
		{
			Encoding encoding = (((_generalPurposeBitFlag & BitFlagValues.UnicodeFileName) != 0) ? Encoding.UTF8 : ((_archive == null) ? Encoding.UTF8 : (_archive.EntryNameEncoding ?? Encoding.UTF8)));
			return encoding.GetString(entryNameBytes);
		}

		private byte[] EncodeEntryName(string entryName, out bool isUTF8)
		{
			Encoding encoding = ((_archive == null || _archive.EntryNameEncoding == null) ? (System.IO.Compression.ZipHelper.RequiresUnicode(entryName) ? Encoding.UTF8 : Encoding.ASCII) : _archive.EntryNameEncoding);
			isUTF8 = encoding.Equals(Encoding.UTF8);
			return encoding.GetBytes(entryName);
		}

		internal void WriteAndFinishLocalEntry()
		{
			CloseStreams();
			WriteLocalFileHeaderAndDataIfNeeded();
			UnloadStreams();
		}

		internal void WriteCentralDirectoryFileHeader()
		{
			BinaryWriter binaryWriter = new BinaryWriter(_archive.ArchiveStream);
			System.IO.Compression.Zip64ExtraField zip64ExtraField = default(System.IO.Compression.Zip64ExtraField);
			bool flag = false;
			uint value;
			uint value2;
			if (SizesTooLarge())
			{
				flag = true;
				value = uint.MaxValue;
				value2 = uint.MaxValue;
				zip64ExtraField.CompressedSize = _compressedSize;
				zip64ExtraField.UncompressedSize = _uncompressedSize;
			}
			else
			{
				value = (uint)_compressedSize;
				value2 = (uint)_uncompressedSize;
			}
			uint value3;
			if (_offsetOfLocalHeader > uint.MaxValue)
			{
				flag = true;
				value3 = uint.MaxValue;
				zip64ExtraField.LocalHeaderOffset = _offsetOfLocalHeader;
			}
			else
			{
				value3 = (uint)_offsetOfLocalHeader;
			}
			if (flag)
			{
				VersionToExtractAtLeast(System.IO.Compression.ZipVersionNeededValues.Zip64);
			}
			int num = (flag ? zip64ExtraField.TotalSize : 0) + ((_cdUnknownExtraFields != null) ? System.IO.Compression.ZipGenericExtraField.TotalSize(_cdUnknownExtraFields) : 0);
			ushort value4;
			if (num > 65535)
			{
				value4 = (ushort)(flag ? zip64ExtraField.TotalSize : 0);
				_cdUnknownExtraFields = null;
			}
			else
			{
				value4 = (ushort)num;
			}
			binaryWriter.Write(33639248u);
			binaryWriter.Write((byte)_versionMadeBySpecification);
			binaryWriter.Write((byte)0);
			binaryWriter.Write((ushort)_versionToExtract);
			binaryWriter.Write((ushort)_generalPurposeBitFlag);
			binaryWriter.Write((ushort)CompressionMethod);
			binaryWriter.Write(System.IO.Compression.ZipHelper.DateTimeToDosTime(_lastModified.DateTime));
			binaryWriter.Write(_crc32);
			binaryWriter.Write(value);
			binaryWriter.Write(value2);
			binaryWriter.Write((ushort)_storedEntryNameBytes.Length);
			binaryWriter.Write(value4);
			binaryWriter.Write((ushort)((_fileComment != null) ? ((ushort)_fileComment.Length) : 0));
			binaryWriter.Write((ushort)0);
			binaryWriter.Write((ushort)0);
			binaryWriter.Write(0u);
			binaryWriter.Write(value3);
			binaryWriter.Write(_storedEntryNameBytes);
			if (flag)
			{
				zip64ExtraField.WriteBlock(_archive.ArchiveStream);
			}
			if (_cdUnknownExtraFields != null)
			{
				System.IO.Compression.ZipGenericExtraField.WriteAllBlocks(_cdUnknownExtraFields, _archive.ArchiveStream);
			}
			if (_fileComment != null)
			{
				binaryWriter.Write(_fileComment);
			}
		}

		internal bool LoadLocalHeaderExtraFieldAndCompressedBytesIfNeeded()
		{
			if (_originallyInArchive)
			{
				_archive.ArchiveStream.Seek(_offsetOfLocalHeader, SeekOrigin.Begin);
				_lhUnknownExtraFields = System.IO.Compression.ZipLocalFileHeader.GetExtraFields(_archive.ArchiveReader);
			}
			if (!_everOpenedForWrite && _originallyInArchive)
			{
				_compressedBytes = new byte[_compressedSize / 2147483591 + 1][];
				for (int i = 0; i < _compressedBytes.Length - 1; i++)
				{
					_compressedBytes[i] = new byte[2147483591];
				}
				_compressedBytes[_compressedBytes.Length - 1] = new byte[_compressedSize % 2147483591];
				_archive.ArchiveStream.Seek(OffsetOfCompressedData, SeekOrigin.Begin);
				for (int j = 0; j < _compressedBytes.Length - 1; j++)
				{
					System.IO.Compression.ZipHelper.ReadBytes(_archive.ArchiveStream, _compressedBytes[j], 2147483591);
				}
				System.IO.Compression.ZipHelper.ReadBytes(_archive.ArchiveStream, _compressedBytes[_compressedBytes.Length - 1], (int)(_compressedSize % 2147483591));
			}
			return true;
		}

		internal void ThrowIfNotOpenable(bool needToUncompress, bool needToLoadIntoMemory)
		{
			if (!IsOpenable(needToUncompress, needToLoadIntoMemory, out var message))
			{
				throw new InvalidDataException(message);
			}
		}

		private System.IO.Compression.CheckSumAndSizeWriteStream GetDataCompressor(Stream backingStream, bool leaveBackingStreamOpen, EventHandler onClose)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			Stream baseStream = (Stream)(_compressionLevel.HasValue ? new DeflateStream(backingStream, _compressionLevel.Value, leaveBackingStreamOpen) : new DeflateStream(backingStream, (CompressionMode)1, leaveBackingStreamOpen));
			bool flag = true;
			bool leaveOpenOnClose = leaveBackingStreamOpen && !flag;
			return new System.IO.Compression.CheckSumAndSizeWriteStream(baseStream, backingStream, leaveOpenOnClose, this, onClose, delegate(long initialPosition, long currentPosition, uint checkSum, Stream backing, ZipArchiveEntry thisRef, EventHandler closeHandler)
			{
				thisRef._crc32 = checkSum;
				thisRef._uncompressedSize = currentPosition;
				thisRef._compressedSize = backing.Position - initialPosition;
				closeHandler?.Invoke(thisRef, EventArgs.Empty);
			});
		}

		private Stream GetDataDecompressor(Stream compressedStreamToRead)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			Stream stream = null;
			return CompressionMethod switch
			{
				CompressionMethodValues.Deflate => (Stream)new DeflateStream(compressedStreamToRead, (CompressionMode)0), 
				CompressionMethodValues.Deflate64 => new System.IO.Compression.DeflateManagedStream(compressedStreamToRead, CompressionMethodValues.Deflate64), 
				_ => compressedStreamToRead, 
			};
		}

		private Stream OpenInReadMode(bool checkOpenable)
		{
			if (checkOpenable)
			{
				ThrowIfNotOpenable(needToUncompress: true, needToLoadIntoMemory: false);
			}
			Stream compressedStreamToRead = new System.IO.Compression.SubReadStream(_archive.ArchiveStream, OffsetOfCompressedData, _compressedSize);
			return GetDataDecompressor(compressedStreamToRead);
		}

		private Stream OpenInWriteMode()
		{
			if (_everOpenedForWrite)
			{
				throw new IOException(System.SR.CreateModeWriteOnceAndOneEntryAtATime);
			}
			_everOpenedForWrite = true;
			System.IO.Compression.CheckSumAndSizeWriteStream dataCompressor = GetDataCompressor(_archive.ArchiveStream, leaveBackingStreamOpen: true, delegate(object o, EventArgs e)
			{
				ZipArchiveEntry zipArchiveEntry = (ZipArchiveEntry)o;
				zipArchiveEntry._archive.ReleaseArchiveStream(zipArchiveEntry);
				zipArchiveEntry._outstandingWriteStream = null;
			});
			_outstandingWriteStream = new DirectToArchiveWriterStream(dataCompressor, this);
			return new System.IO.Compression.WrappedStream(_outstandingWriteStream, closeBaseStream: true);
		}

		private Stream OpenInUpdateMode()
		{
			if (_currentlyOpenForWrite)
			{
				throw new IOException(System.SR.UpdateModeOneStream);
			}
			ThrowIfNotOpenable(needToUncompress: true, needToLoadIntoMemory: true);
			_everOpenedForWrite = true;
			_currentlyOpenForWrite = true;
			UncompressedData.Seek(0L, SeekOrigin.Begin);
			return new System.IO.Compression.WrappedStream(UncompressedData, this, delegate(ZipArchiveEntry thisRef)
			{
				thisRef._currentlyOpenForWrite = false;
			});
		}

		private bool IsOpenable(bool needToUncompress, bool needToLoadIntoMemory, out string message)
		{
			message = null;
			if (_originallyInArchive)
			{
				if (needToUncompress && CompressionMethod != 0 && CompressionMethod != CompressionMethodValues.Deflate && CompressionMethod != CompressionMethodValues.Deflate64)
				{
					CompressionMethodValues compressionMethod = CompressionMethod;
					if (compressionMethod == CompressionMethodValues.BZip2 || compressionMethod == CompressionMethodValues.LZMA)
					{
						message = System.SR.Format(System.SR.UnsupportedCompressionMethod, CompressionMethod.ToString());
					}
					else
					{
						message = System.SR.UnsupportedCompression;
					}
					return false;
				}
				if (_diskNumberStart != _archive.NumberOfThisDisk)
				{
					message = System.SR.SplitSpanned;
					return false;
				}
				if (_offsetOfLocalHeader > _archive.ArchiveStream.Length)
				{
					message = System.SR.LocalFileHeaderCorrupt;
					return false;
				}
				_archive.ArchiveStream.Seek(_offsetOfLocalHeader, SeekOrigin.Begin);
				if (!System.IO.Compression.ZipLocalFileHeader.TrySkipBlock(_archive.ArchiveReader))
				{
					message = System.SR.LocalFileHeaderCorrupt;
					return false;
				}
				if (OffsetOfCompressedData + _compressedSize > _archive.ArchiveStream.Length)
				{
					message = System.SR.LocalFileHeaderCorrupt;
					return false;
				}
				if (needToLoadIntoMemory && _compressedSize > int.MaxValue && !s_allowLargeZipArchiveEntriesInUpdateMode)
				{
					message = System.SR.EntryTooLarge;
					return false;
				}
			}
			return true;
		}

		private bool SizesTooLarge()
		{
			if (_compressedSize <= uint.MaxValue)
			{
				return _uncompressedSize > uint.MaxValue;
			}
			return true;
		}

		private bool WriteLocalFileHeader(bool isEmptyFile)
		{
			BinaryWriter binaryWriter = new BinaryWriter(_archive.ArchiveStream);
			System.IO.Compression.Zip64ExtraField zip64ExtraField = default(System.IO.Compression.Zip64ExtraField);
			bool flag = false;
			uint value;
			uint value2;
			if (isEmptyFile)
			{
				CompressionMethod = CompressionMethodValues.Stored;
				value = 0u;
				value2 = 0u;
			}
			else if (_archive.Mode == ZipArchiveMode.Create && !_archive.ArchiveStream.CanSeek && !isEmptyFile)
			{
				_generalPurposeBitFlag |= BitFlagValues.DataDescriptor;
				flag = false;
				value = 0u;
				value2 = 0u;
			}
			else if (SizesTooLarge())
			{
				flag = true;
				value = uint.MaxValue;
				value2 = uint.MaxValue;
				zip64ExtraField.CompressedSize = _compressedSize;
				zip64ExtraField.UncompressedSize = _uncompressedSize;
				VersionToExtractAtLeast(System.IO.Compression.ZipVersionNeededValues.Zip64);
			}
			else
			{
				flag = false;
				value = (uint)_compressedSize;
				value2 = (uint)_uncompressedSize;
			}
			_offsetOfLocalHeader = binaryWriter.BaseStream.Position;
			int num = (flag ? zip64ExtraField.TotalSize : 0) + ((_lhUnknownExtraFields != null) ? System.IO.Compression.ZipGenericExtraField.TotalSize(_lhUnknownExtraFields) : 0);
			ushort value3;
			if (num > 65535)
			{
				value3 = (ushort)(flag ? zip64ExtraField.TotalSize : 0);
				_lhUnknownExtraFields = null;
			}
			else
			{
				value3 = (ushort)num;
			}
			binaryWriter.Write(67324752u);
			binaryWriter.Write((ushort)_versionToExtract);
			binaryWriter.Write((ushort)_generalPurposeBitFlag);
			binaryWriter.Write((ushort)CompressionMethod);
			binaryWriter.Write(System.IO.Compression.ZipHelper.DateTimeToDosTime(_lastModified.DateTime));
			binaryWriter.Write(_crc32);
			binaryWriter.Write(value);
			binaryWriter.Write(value2);
			binaryWriter.Write((ushort)_storedEntryNameBytes.Length);
			binaryWriter.Write(value3);
			binaryWriter.Write(_storedEntryNameBytes);
			if (flag)
			{
				zip64ExtraField.WriteBlock(_archive.ArchiveStream);
			}
			if (_lhUnknownExtraFields != null)
			{
				System.IO.Compression.ZipGenericExtraField.WriteAllBlocks(_lhUnknownExtraFields, _archive.ArchiveStream);
			}
			return flag;
		}

		private void WriteLocalFileHeaderAndDataIfNeeded()
		{
			if (_storedUncompressedData != null || _compressedBytes != null)
			{
				if (_storedUncompressedData != null)
				{
					_uncompressedSize = _storedUncompressedData.Length;
					using Stream destination = new DirectToArchiveWriterStream(GetDataCompressor(_archive.ArchiveStream, leaveBackingStreamOpen: true, null), this);
					_storedUncompressedData.Seek(0L, SeekOrigin.Begin);
					_storedUncompressedData.CopyTo(destination);
					_storedUncompressedData.Dispose();
					_storedUncompressedData = null;
					return;
				}
				if (_uncompressedSize == 0L)
				{
					CompressionMethod = CompressionMethodValues.Stored;
				}
				WriteLocalFileHeader(isEmptyFile: false);
				byte[][] compressedBytes = _compressedBytes;
				foreach (byte[] array in compressedBytes)
				{
					_archive.ArchiveStream.Write(array, 0, array.Length);
				}
			}
			else if (_archive.Mode == ZipArchiveMode.Update || !_everOpenedForWrite)
			{
				_everOpenedForWrite = true;
				WriteLocalFileHeader(isEmptyFile: true);
			}
		}

		private void WriteCrcAndSizesInLocalHeader(bool zip64HeaderUsed)
		{
			long position = _archive.ArchiveStream.Position;
			BinaryWriter binaryWriter = new BinaryWriter(_archive.ArchiveStream);
			bool flag = SizesTooLarge();
			bool flag2 = flag && !zip64HeaderUsed;
			uint value = (uint)(flag ? uint.MaxValue : _compressedSize);
			uint value2 = (uint)(flag ? uint.MaxValue : _uncompressedSize);
			if (flag2)
			{
				_generalPurposeBitFlag |= BitFlagValues.DataDescriptor;
				_archive.ArchiveStream.Seek(_offsetOfLocalHeader + 6, SeekOrigin.Begin);
				binaryWriter.Write((ushort)_generalPurposeBitFlag);
			}
			_archive.ArchiveStream.Seek(_offsetOfLocalHeader + 14, SeekOrigin.Begin);
			if (!flag2)
			{
				binaryWriter.Write(_crc32);
				binaryWriter.Write(value);
				binaryWriter.Write(value2);
			}
			else
			{
				binaryWriter.Write(0u);
				binaryWriter.Write(0u);
				binaryWriter.Write(0u);
			}
			if (zip64HeaderUsed)
			{
				_archive.ArchiveStream.Seek(_offsetOfLocalHeader + 30 + _storedEntryNameBytes.Length + 4, SeekOrigin.Begin);
				binaryWriter.Write(_uncompressedSize);
				binaryWriter.Write(_compressedSize);
				_archive.ArchiveStream.Seek(position, SeekOrigin.Begin);
			}
			_archive.ArchiveStream.Seek(position, SeekOrigin.Begin);
			if (flag2)
			{
				binaryWriter.Write(_crc32);
				binaryWriter.Write(_compressedSize);
				binaryWriter.Write(_uncompressedSize);
			}
		}

		private void WriteDataDescriptor()
		{
			BinaryWriter binaryWriter = new BinaryWriter(_archive.ArchiveStream);
			binaryWriter.Write(134695760u);
			binaryWriter.Write(_crc32);
			if (SizesTooLarge())
			{
				binaryWriter.Write(_compressedSize);
				binaryWriter.Write(_uncompressedSize);
			}
			else
			{
				binaryWriter.Write((uint)_compressedSize);
				binaryWriter.Write((uint)_uncompressedSize);
			}
		}

		private void UnloadStreams()
		{
			if (_storedUncompressedData != null)
			{
				_storedUncompressedData.Dispose();
			}
			_compressedBytes = null;
			_outstandingWriteStream = null;
		}

		private void CloseStreams()
		{
			if (_outstandingWriteStream != null)
			{
				_outstandingWriteStream.Dispose();
			}
		}

		private void VersionToExtractAtLeast(System.IO.Compression.ZipVersionNeededValues value)
		{
			if ((int)_versionToExtract < (int)value)
			{
				_versionToExtract = value;
			}
			if ((int)_versionMadeBySpecification < (int)value)
			{
				_versionMadeBySpecification = value;
			}
		}

		private void ThrowIfInvalidArchive()
		{
			if (_archive == null)
			{
				throw new InvalidOperationException(System.SR.DeletedEntry);
			}
			_archive.ThrowIfDisposed();
		}

		private static string GetFileName_Windows(string path)
		{
			int length = path.Length;
			int num = length;
			while (--num >= 0)
			{
				char c = path[num];
				if (c == '\\' || c == '/' || c == ':')
				{
					return path.Substring(num + 1);
				}
			}
			return path;
		}

		private static string GetFileName_Unix(string path)
		{
			int length = path.Length;
			int num = length;
			while (--num >= 0)
			{
				if (path[num] == '/')
				{
					return path.Substring(num + 1);
				}
			}
			return path;
		}

		internal static string ParseFileName(string path, System.IO.Compression.ZipVersionMadeByPlatform madeByPlatform)
		{
			if (madeByPlatform == System.IO.Compression.ZipVersionMadeByPlatform.Unix)
			{
				return GetFileName_Unix(path);
			}
			return GetFileName_Windows(path);
		}
	}
	public enum ZipArchiveMode
	{
		Read,
		Create,
		Update
	}
	internal struct ZipGenericExtraField
	{
		private const int SizeOfHeader = 4;

		private ushort _tag;

		private ushort _size;

		private byte[] _data;

		public ushort Tag => _tag;

		public ushort Size => _size;

		public byte[] Data => _data;

		public void WriteBlock(Stream stream)
		{
			BinaryWriter binaryWriter = new BinaryWriter(stream);
			binaryWriter.Write(Tag);
			binaryWriter.Write(Size);
			binaryWriter.Write(Data);
		}

		public static bool TryReadBlock(BinaryReader reader, long endExtraField, out System.IO.Compression.ZipGenericExtraField field)
		{
			field = default(System.IO.Compression.ZipGenericExtraField);
			if (endExtraField - reader.BaseStream.Position < 4)
			{
				return false;
			}
			field._tag = reader.ReadUInt16();
			field._size = reader.ReadUInt16();
			if (endExtraField - reader.BaseStream.Position < field._size)
			{
				return false;
			}
			field._data = reader.ReadBytes(field._size);
			return true;
		}

		public static List<System.IO.Compression.ZipGenericExtraField> ParseExtraField(Stream extraFieldData)
		{
			List<System.IO.Compression.ZipGenericExtraField> list = new List<System.IO.Compression.ZipGenericExtraField>();
			using BinaryReader reader = new BinaryReader(extraFieldData);
			System.IO.Compression.ZipGenericExtraField field;
			while (TryReadBlock(reader, extraFieldData.Length, out field))
			{
				list.Add(field);
			}
			return list;
		}

		public static int TotalSize(List<System.IO.Compression.ZipGenericExtraField> fields)
		{
			int num = 0;
			foreach (System.IO.Compression.ZipGenericExtraField field in fields)
			{
				num += field.Size + 4;
			}
			return num;
		}

		public static void WriteAllBlocks(List<System.IO.Compression.ZipGenericExtraField> fields, Stream stream)
		{
			foreach (System.IO.Compression.ZipGenericExtraField field in fields)
			{
				field.WriteBlock(stream);
			}
		}
	}
	internal struct Zip64ExtraField
	{
		public const int OffsetToFirstField = 4;

		private const ushort TagConstant = 1;

		private ushort _size;

		private long? _uncompressedSize;

		private long? _compressedSize;

		private long? _localHeaderOffset;

		private int? _startDiskNumber;

		public ushort TotalSize => (ushort)(_size + 4);

		public long? UncompressedSize
		{
			get
			{
				return _uncompressedSize;
			}
			set
			{
				_uncompressedSize = value;
				UpdateSize();
			}
		}

		public long? CompressedSize
		{
			get
			{
				return _compressedSize;
			}
			set
			{
				_compressedSize = value;
				UpdateSize();
			}
		}

		public long? LocalHeaderOffset
		{
			get
			{
				return _localHeaderOffset;
			}
			set
			{
				_localHeaderOffset = value;
				UpdateSize();
			}
		}

		public int? StartDiskNumber => _startDiskNumber;

		private void UpdateSize()
		{
			_size = 0;
			if (_uncompressedSize.HasValue)
			{
				_size += 8;
			}
			if (_compressedSize.HasValue)
			{
				_size += 8;
			}
			if (_localHeaderOffset.HasValue)
			{
				_size += 8;
			}
			if (_startDiskNumber.HasValue)
			{
				_size += 4;
			}
		}

		public static System.IO.Compression.Zip64ExtraField GetJustZip64Block(Stream extraFieldStream, bool readUncompressedSize, bool readCompressedSize, bool readLocalHeaderOffset, bool readStartDiskNumber)
		{
			System.IO.Compression.Zip64ExtraField zip64Block;
			using (BinaryReader reader = new BinaryReader(extraFieldStream))
			{
				System.IO.Compression.ZipGenericExtraField field;
				while (System.IO.Compression.ZipGenericExtraField.TryReadBlock(reader, extraFieldStream.Length, out field))
				{
					if (TryGetZip64BlockFromGenericExtraField(field, readUncompressedSize, readCompressedSize, readLocalHeaderOffset, readStartDiskNumber, out zip64Block))
					{
						return zip64Block;
					}
				}
			}
			zip64Block = default(System.IO.Compression.Zip64ExtraField);
			zip64Block._compressedSize = null;
			zip64Block._uncompressedSize = null;
			zip64Block._localHeaderOffset = null;
			zip64Block._startDiskNumber = null;
			return zip64Block;
		}

		private static bool TryGetZip64BlockFromGenericExtraField(System.IO.Compression.ZipGenericExtraField extraField, bool readUncompressedSize, bool readCompressedSize, bool readLocalHeaderOffset, bool readStartDiskNumber, out System.IO.Compression.Zip64ExtraField zip64Block)
		{
			zip64Block = default(System.IO.Compression.Zip64ExtraField);
			zip64Block._compressedSize = null;
			zip64Block._uncompressedSize = null;
			zip64Block._localHeaderOffset = null;
			zip64Block._startDiskNumber = null;
			if (extraField.Tag != 1)
			{
				return false;
			}
			MemoryStream memoryStream = null;
			try
			{
				memoryStream = new MemoryStream(extraField.Data);
				using BinaryReader binaryReader = new BinaryReader(memoryStream);
				memoryStream = null;
				zip64Block._size = extraField.Size;
				ushort num = 0;
				if (readUncompressedSize)
				{
					num += 8;
				}
				if (readCompressedSize)
				{
					num += 8;
				}
				if (readLocalHeaderOffset)
				{
					num += 8;
				}
				if (readStartDiskNumber)
				{
					num += 4;
				}
				if (num != zip64Block._size)
				{
					return false;
				}
				if (readUncompressedSize)
				{
					zip64Block._uncompressedSize = binaryReader.ReadInt64();
				}
				if (readCompressedSize)
				{
					zip64Block._compressedSize = binaryReader.ReadInt64();
				}
				if (readLocalHeaderOffset)
				{
					zip64Block._localHeaderOffset = binaryReader.ReadInt64();
				}
				if (readStartDiskNumber)
				{
					zip64Block._startDiskNumber = binaryReader.ReadInt32();
				}
				if (zip64Block._uncompressedSize < 0)
				{
					throw new InvalidDataException(System.SR.FieldTooBigUncompressedSize);
				}
				if (zip64Block._compressedSize < 0)
				{
					throw new InvalidDataException(System.SR.FieldTooBigCompressedSize);
				}
				if (zip64Block._localHeaderOffset < 0)
				{
					throw new InvalidDataException(System.SR.FieldTooBigLocalHeaderOffset);
				}
				if (zip64Block._startDiskNumber < 0)
				{
					throw new InvalidDataException(System.SR.FieldTooBigStartDiskNumber);
				}
				return true;
			}
			finally
			{
				memoryStream?.Dispose();
			}
		}

		public static System.IO.Compression.Zip64ExtraField GetAndRemoveZip64Block(List<System.IO.Compression.ZipGenericExtraField> extraFields, bool readUncompressedSize, bool readCompressedSize, bool readLocalHeaderOffset, bool readStartDiskNumber)
		{
			System.IO.Compression.Zip64ExtraField zip64Block = default(System.IO.Compression.Zip64ExtraField);
			zip64Block._compressedSize = null;
			zip64Block._uncompressedSize = null;
			zip64Block._localHeaderOffset = null;
			zip64Block._startDiskNumber = null;
			List<System.IO.Compression.ZipGenericExtraField> list = new List<System.IO.Compression.ZipGenericExtraField>();
			bool flag = false;
			foreach (System.IO.Compression.ZipGenericExtraField extraField in extraFields)
			{
				if (extraField.Tag == 1)
				{
					list.Add(extraField);
					if (!flag && TryGetZip64BlockFromGenericExtraField(extraField, readUncompressedSize, readCompressedSize, readLocalHeaderOffset, readStartDiskNumber, out zip64Block))
					{
						flag = true;
					}
				}
			}
			foreach (System.IO.Compression.ZipGenericExtraField item in list)
			{
				extraFields.Remove(item);
			}
			return zip64Block;
		}

		public static void RemoveZip64Blocks(List<System.IO.Compression.ZipGenericExtraField> extraFields)
		{
			List<System.IO.Compression.ZipGenericExtraField> list = new List<System.IO.Compression.ZipGenericExtraField>();
			foreach (System.IO.Compression.ZipGenericExtraField extraField in extraFields)
			{
				if (extraField.Tag == 1)
				{
					list.Add(extraField);
				}
			}
			foreach (System.IO.Compression.ZipGenericExtraField item in list)
			{
				extraFields.Remove(item);
			}
		}

		public void WriteBlock(Stream stream)
		{
			BinaryWriter binaryWriter = new BinaryWriter(stream);
			binaryWriter.Write((ushort)1);
			binaryWriter.Write(_size);
			if (_uncompressedSize.HasValue)
			{
				binaryWriter.Write(_uncompressedSize.Value);
			}
			if (_compressedSize.HasValue)
			{
				binaryWriter.Write(_compressedSize.Value);
			}
			if (_localHeaderOffset.HasValue)
			{
				binaryWriter.Write(_localHeaderOffset.Value);
			}
			if (_startDiskNumber.HasValue)
			{
				binaryWriter.Write(_startDiskNumber.Value);
			}
		}
	}
	internal struct Zip64EndOfCentralDirectoryLocator
	{
		public const uint SignatureConstant = 117853008u;

		public const int SizeOfBlockWithoutSignature = 16;

		public uint NumberOfDiskWithZip64EOCD;

		public ulong OffsetOfZip64EOCD;

		public uint TotalNumberOfDisks;

		public static bool TryReadBlock(BinaryReader reader, out System.IO.Compression.Zip64EndOfCentralDirectoryLocator zip64EOCDLocator)
		{
			zip64EOCDLocator = default(System.IO.Compression.Zip64EndOfCentralDirectoryLocator);
			if (reader.ReadUInt32() != 117853008)
			{
				return false;
			}
			zip64EOCDLocator.NumberOfDiskWithZip64EOCD = reader.ReadUInt32();
			zip64EOCDLocator.OffsetOfZip64EOCD = reader.ReadUInt64();
			zip64EOCDLocator.TotalNumberOfDisks = reader.ReadUInt32();
			return true;
		}

		public static void WriteBlock(Stream stream, long zip64EOCDRecordStart)
		{
			BinaryWriter binaryWriter = new BinaryWriter(stream);
			binaryWriter.Write(117853008u);
			binaryWriter.Write(0u);
			binaryWriter.Write(zip64EOCDRecordStart);
			binaryWriter.Write(1u);
		}
	}
	internal struct Zip64EndOfCentralDirectoryRecord
	{
		private const uint SignatureConstant = 101075792u;

		private const ulong NormalSize = 44uL;

		public ulong SizeOfThisRecord;

		public ushort VersionMadeBy;

		public ushort VersionNeededToExtract;

		public uint NumberOfThisDisk;

		public uint NumberOfDiskWithStartOfCD;

		public ulong NumberOfEntriesOnThisDisk;

		public ulong NumberOfEntriesTotal;

		public ulong SizeOfCentralDirectory;

		public ulong OffsetOfCentralDirectory;

		public static bool TryReadBlock(BinaryReader reader, out System.IO.Compression.Zip64EndOfCentralDirectoryRecord zip64EOCDRecord)
		{
			zip64EOCDRecord = default(System.IO.Compression.Zip64EndOfCentralDirectoryRecord);
			if (reader.ReadUInt32() != 101075792)
			{
				return false;
			}
			zip64EOCDRecord.SizeOfThisRecord = reader.ReadUInt64();
			zip64EOCDRecord.VersionMadeBy = reader.ReadUInt16();
			zip64EOCDRecord.VersionNeededToExtract = reader.ReadUInt16();
			zip64EOCDRecord.NumberOfThisDisk = reader.ReadUInt32();
			zip64EOCDRecord.NumberOfDiskWithStartOfCD = reader.ReadUInt32();
			zip64EOCDRecord.NumberOfEntriesOnThisDisk = reader.ReadUInt64();
			zip64EOCDRecord.NumberOfEntriesTotal = reader.ReadUInt64();
			zip64EOCDRecord.SizeOfCentralDirectory = reader.ReadUInt64();
			zip64EOCDRecord.OffsetOfCentralDirectory = reader.ReadUInt64();
			return true;
		}

		public static void WriteBlock(Stream stream, long numberOfEntries, long startOfCentralDirectory, long sizeOfCentralDirectory)
		{
			BinaryWriter binaryWriter = new BinaryWriter(stream);
			binaryWriter.Write(101075792u);
			binaryWriter.Write(44uL);
			binaryWriter.Write((ushort)45);
			binaryWriter.Write((ushort)45);
			binaryWriter.Write(0u);
			binaryWriter.Write(0u);
			binaryWriter.Write(numberOfEntries);
			binaryWriter.Write(numberOfEntries);
			binaryWriter.Write(sizeOfCentralDirectory);
			binaryWriter.Write(startOfCentralDirectory);
		}
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	internal struct ZipLocalFileHeader
	{
		public const uint DataDescriptorSignature = 134695760u;

		public const uint SignatureConstant = 67324752u;

		public const int OffsetToCrcFromHeaderStart = 14;

		public const int OffsetToBitFlagFromHeaderStart = 6;

		public const int SizeOfLocalHeader = 30;

		public static List<System.IO.Compression.ZipGenericExtraField> GetExtraFields(BinaryReader reader)
		{
			reader.BaseStream.Seek(26L, SeekOrigin.Current);
			ushort num = reader.ReadUInt16();
			ushort num2 = reader.ReadUInt16();
			reader.BaseStream.Seek(num, SeekOrigin.Current);
			List<System.IO.Compression.ZipGenericExtraField> list;
			using (Stream extraFieldData = new System.IO.Compression.SubReadStream(reader.BaseStream, reader.BaseStream.Position, num2))
			{
				list = System.IO.Compression.ZipGenericExtraField.ParseExtraField(extraFieldData);
			}
			System.IO.Compression.Zip64ExtraField.RemoveZip64Blocks(list);
			return list;
		}

		pu