Decompiled source of DSPTechTreeUXOverhaul v1.0.0

TechTreeOverhaul.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;
using crecheng.DSPModSave;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("TechTreeOverhaul")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("TechTreeOverhaul")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("3c515864-c361-43d9-babe-1e87cf7fa23c")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace DSPTechTreeUX;

[BepInPlugin("lee.dsp.techtree.ux", "DSP Tech Tree UX Overhaul", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class Plugin : BaseUnityPlugin, IModCanSave
{
	public const string PluginGuid = "lee.dsp.techtree.ux";

	public const string PluginName = "DSP Tech Tree UX Overhaul";

	public const string PluginVersion = "1.0.0";

	internal static ConfigEntry<float> LineThickness;

	internal static ConfigEntry<float> MainLineThickness;

	private const int SaveDataVersion = 2;

	internal static TechTreeSavedViewState SavedViewState = TechTreeSavedViewState.CreateDefault();

	public void Export(BinaryWriter w)
	{
		TechTreeView activeInstance = TechTreeView.ActiveInstance;
		if ((Object)(object)activeInstance != (Object)null)
		{
			SavedViewState = activeInstance.CaptureSavedViewState();
		}
		w.Write(2);
		w.Write(SavedViewState.Page);
		w.Write(SavedViewState.MatrixFilter);
		w.Write(SavedViewState.CombatFilter);
		w.Write(SavedViewState.InfiniteOnly);
		for (int i = 0; i < 2; i++)
		{
			w.Write(SavedViewState.Zoom[i]);
			w.Write(SavedViewState.Pan[i].x);
			w.Write(SavedViewState.Pan[i].y);
		}
	}

	public void Import(BinaryReader r)
	{
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		int num = r.ReadInt32();
		TechTreeSavedViewState techTreeSavedViewState = TechTreeSavedViewState.CreateDefault();
		if (num >= 1)
		{
			techTreeSavedViewState.Page = Mathf.Clamp(r.ReadInt32(), 0, 1);
			techTreeSavedViewState.MatrixFilter = Mathf.Clamp(r.ReadInt32(), -1, 5);
			techTreeSavedViewState.CombatFilter = Mathf.Clamp(r.ReadInt32(), 0, 2);
			if (num >= 2)
			{
				techTreeSavedViewState.InfiniteOnly = r.ReadBoolean();
			}
			for (int i = 0; i < 2; i++)
			{
				techTreeSavedViewState.Zoom[i] = Mathf.Clamp(r.ReadSingle(), 0.45f, 1.3333334f);
				techTreeSavedViewState.Pan[i] = new Vector2(r.ReadSingle(), r.ReadSingle());
			}
		}
		SavedViewState = techTreeSavedViewState;
		TechTreeView activeInstance = TechTreeView.ActiveInstance;
		if ((Object)(object)activeInstance != (Object)null)
		{
			activeInstance.MarkSavedViewStatePending();
		}
	}

	public void IntoOtherSave()
	{
		SavedViewState = TechTreeSavedViewState.CreateDefault();
		TechTreeView activeInstance = TechTreeView.ActiveInstance;
		if ((Object)(object)activeInstance != (Object)null)
		{
			activeInstance.MarkSavedViewStatePending();
		}
	}

	private void Awake()
	{
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		LineThickness = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "LineThickness", 5f, "Thickness of ordinary technology dependency lines.");
		MainLineThickness = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "MainLineThickness", 9f, "Thickness of the main research line from Electromagnetism to Mission Completed.");
		new Harmony("lee.dsp.techtree.ux").PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"DSP Tech Tree UX Overhaul 1.0.0 loaded.");
	}
}
internal sealed class TechTreeSavedViewState
{
	internal int Page;

	internal int MatrixFilter;

	internal int CombatFilter;

	internal bool InfiniteOnly;

	internal readonly float[] Zoom = new float[2];

	internal readonly Vector2[] Pan = (Vector2[])(object)new Vector2[2];

	internal static TechTreeSavedViewState CreateDefault()
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		TechTreeSavedViewState obj = new TechTreeSavedViewState
		{
			Page = 0,
			MatrixFilter = -1,
			CombatFilter = 0,
			InfiniteOnly = false
		};
		obj.Zoom[0] = 0.72f;
		obj.Zoom[1] = 0.72f;
		obj.Pan[0] = Vector2.zero;
		obj.Pan[1] = Vector2.zero;
		return obj;
	}
}
[HarmonyPatch(typeof(UITechTree), "_OnOpen")]
internal static class UITechTree_OnOpen_Patch
{
	[HarmonyPostfix]
	private static void Postfix(UITechTree __instance)
	{
		TechTreeView techTreeView = ((Component)__instance).GetComponent<TechTreeView>();
		if ((Object)(object)techTreeView == (Object)null)
		{
			techTreeView = ((Component)__instance).gameObject.AddComponent<TechTreeView>();
			techTreeView.Initialize(__instance);
		}
		techTreeView.Show();
	}
}
[HarmonyPatch(typeof(UITechTree), "_OnClose")]
internal static class UITechTree_OnClose_Patch
{
	[HarmonyPrefix]
	private static void Prefix(UITechTree __instance)
	{
		TechTreeView component = ((Component)__instance).GetComponent<TechTreeView>();
		if ((Object)(object)component != (Object)null)
		{
			component.Hide();
		}
	}
}
[HarmonyPatch(typeof(UITechTree), "OnPageChanged")]
internal static class UITechTree_OnPageChanged_Patch
{
	[HarmonyPostfix]
	private static void Postfix(UITechTree __instance)
	{
		TechTreeView component = ((Component)__instance).GetComponent<TechTreeView>();
		if ((Object)(object)component != (Object)null && component.IsVisible)
		{
			component.RefreshPage();
		}
	}
}
internal sealed class TechTreeInputCatcher : MonoBehaviour, IScrollHandler, IEventSystemHandler, IPointerDownHandler, IBeginDragHandler, IDragHandler, IPointerClickHandler
{
	internal TechTreeView Owner;

	private bool _dragged;

	public void OnScroll(PointerEventData eventData)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)Owner == (Object)null) && eventData != null)
		{
			Owner.HandleScrollDelta(eventData.scrollDelta.y);
			((AbstractEventData)eventData).Use();
		}
	}

	public void OnPointerDown(PointerEventData eventData)
	{
		_dragged = false;
	}

	public void OnBeginDrag(PointerEventData eventData)
	{
		_dragged = true;
		if (eventData != null)
		{
			((AbstractEventData)eventData).Use();
		}
	}

	public void OnDrag(PointerEventData eventData)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)Owner == (Object)null) && eventData != null)
		{
			_dragged = true;
			Owner.HandlePanDelta(eventData.delta);
			((AbstractEventData)eventData).Use();
		}
	}

	public void OnPointerClick(PointerEventData eventData)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)Owner == (Object)null) && eventData != null)
		{
			if (_dragged)
			{
				((AbstractEventData)eventData).Use();
			}
			else if ((int)eventData.button == 0)
			{
				Owner.ClearSelection();
				((AbstractEventData)eventData).Use();
			}
		}
	}
}
internal sealed class TechTreeResearchWingGraphic : Graphic
{
	internal Color BorderColor = Color.white;

	internal Color FillColor = Color.black;

	internal Color ArrowColor = new Color(0.25f, 0.75f, 1f, 1f);

	internal void SetColors(Color border, Color fill)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		if (!(BorderColor == border) || !(FillColor == fill))
		{
			BorderColor = border;
			FillColor = fill;
			((Graphic)this).SetVerticesDirty();
		}
	}

	protected override void OnPopulateMesh(VertexHelper vh)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: 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_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0152: 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_016a: Unknown result type (might be due to invalid IL or missing references)
		vh.Clear();
		Rect rect = ((Graphic)this).rectTransform.rect;
		float width = ((Rect)(ref rect)).width;
		float height = ((Rect)(ref rect)).height;
		if (!(width <= 0f) && !(height <= 0f))
		{
			Vector2[] points = (Vector2[])(object)new Vector2[6]
			{
				new Vector2(0f, 0f),
				new Vector2(width * 0.42f, 0f),
				new Vector2(width, height * 0.23f),
				new Vector2(width, height * 0.77f),
				new Vector2(width * 0.42f, height),
				new Vector2(0f, height)
			};
			float num = 4f;
			Vector2[] points2 = (Vector2[])(object)new Vector2[6]
			{
				new Vector2(num, num),
				new Vector2(width * 0.42f - 1f, num),
				new Vector2(width - num, height * 0.23f + 3f),
				new Vector2(width - num, height * 0.77f - 3f),
				new Vector2(width * 0.42f - 1f, height - num),
				new Vector2(num, height - num)
			};
			AddConvex(vh, points, BorderColor);
			AddConvex(vh, points2, FillColor);
		}
	}

	private static void AddConvex(VertexHelper vh, Vector2[] points, Color color)
	{
		//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_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: 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_003c: Unknown result type (might be due to invalid IL or missing references)
		if (points != null && points.Length >= 3)
		{
			int currentVertCount = vh.currentVertCount;
			for (int i = 0; i < points.Length; i++)
			{
				UIVertex simpleVert = UIVertex.simpleVert;
				simpleVert.position = Vector2.op_Implicit(points[i]);
				simpleVert.color = Color32.op_Implicit(color);
				vh.AddVert(simpleVert);
			}
			for (int j = 1; j < points.Length - 1; j++)
			{
				vh.AddTriangle(currentVertCount, currentVertCount + j, currentVertCount + j + 1);
			}
		}
	}

	private static void AddLine(VertexHelper vh, Vector2 a, Vector2 b, float thickness, Color color)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: 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_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		Vector2 val = b - a;
		if (!(((Vector2)(ref val)).sqrMagnitude < 0.0001f))
		{
			((Vector2)(ref val)).Normalize();
			Vector2 val2 = new Vector2(0f - val.y, val.x) * (thickness * 0.5f);
			int currentVertCount = vh.currentVertCount;
			AddVert(vh, a - val2, color);
			AddVert(vh, a + val2, color);
			AddVert(vh, b + val2, color);
			AddVert(vh, b - val2, color);
			vh.AddTriangle(currentVertCount, currentVertCount + 1, currentVertCount + 2);
			vh.AddTriangle(currentVertCount, currentVertCount + 2, currentVertCount + 3);
		}
	}

	private static void AddVert(VertexHelper vh, Vector2 position, Color color)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		UIVertex simpleVert = UIVertex.simpleVert;
		simpleVert.position = Vector2.op_Implicit(position);
		simpleVert.color = Color32.op_Implicit(color);
		vh.AddVert(simpleVert);
	}
}
internal sealed class TechTreeView : MonoBehaviour
{
	private sealed class NodeView
	{
		internal TechProto Proto;

		internal RectTransform Root;

		internal Vector2 OriginalPosition;

		internal Image Border;

		internal Image Inner;

		internal Image Icon;

		internal Text Level;

		internal GameObject LevelBadge;

		internal CanvasGroup CanvasGroup;

		internal int DirectMatrixMask;

		internal Image[] Pips;

		internal GameObject ResearchWing;

		internal RectTransform ResearchWingRect;

		internal Button ResearchWingButton;

		internal TechTreeResearchWingGraphic ResearchWingGraphic;

		internal CanvasGroup ResearchWingCanvas;

		internal bool ResearchWingOpen;

		internal bool Hovered;
	}

	private sealed class EdgeView
	{
		internal int FromId;

		internal int ToId;

		internal bool Implicit;

		internal bool Inferred;

		internal bool Backbone;

		internal int SegmentStart;

		internal int SegmentCount;
	}

	private const float NodeSize = 104f;

	private const float GraphMargin = 100f;

	private const float DetailWidth = 500f;

	private const float DetailHeight = 540f;

	private const float DetailCollapsedWidth = 250f;

	private const float DetailCollapsedHeight = 46f;

	private const float SearchFilterWidth = 420f;

	private const float SearchFilterHeight = 142f;

	private const float SearchFilterTabWidth = 150f;

	private const float SearchFilterTabHeight = 24f;

	private const float MinZoom = 0.45f;

	private const float MaxZoom = 1.3333334f;

	private const float PanSafeLeft = 420f;

	private const float PanSafeRight = 760f;

	private const float PanSafeTop = 190f;

	private const float PanSafeBottom = 120f;

	private static readonly int[] MainResearchLineTechIds = new int[10] { 1001, 1002, 1501, 1502, 1503, 1504, 1505, 1506, 1507, 1508 };

	private static readonly Color LockedColor = new Color(1f, 0.62f, 0.1f, 1f);

	private static readonly Color ReadyColor = new Color(0.2f, 0.82f, 0.36f, 1f);

	private static readonly Color CompleteColor = new Color(0.25f, 0.58f, 1f, 1f);

	private static readonly Color SelectedColor = new Color(1f, 0.95f, 0.55f, 1f);

	private static readonly Color NodeInnerColor = new Color(0.055f, 0.07f, 0.09f, 1f);

	private static readonly Color PanelColor = new Color(0.02f, 0.027f, 0.038f, 0.985f);

	private static readonly Color LineColor = new Color(0.52f, 0.58f, 0.66f, 0.52f);

	private static readonly Color ImplicitLineColor = new Color(0.74f, 0.56f, 0.86f, 0.42f);

	private static readonly Color PathLineColor = new Color(1f, 0.78f, 0.18f, 0.95f);

	private static readonly Color[] MatrixColors = (Color[])(object)new Color[6]
	{
		new Color(0.2f, 0.55f, 1f, 1f),
		new Color(0.95f, 0.25f, 0.25f, 1f),
		new Color(0.98f, 0.82f, 0.18f, 1f),
		new Color(0.68f, 0.34f, 0.9f, 1f),
		new Color(0.25f, 0.9f, 0.48f, 1f),
		new Color(0.92f, 0.94f, 1f, 1f)
	};

	private UITechTree _tree;

	private RectTransform _root;

	private RectTransform _viewport;

	private RectTransform _graphCanvas;

	private readonly RectTransform[] _pageGraphCanvas = (RectTransform[])(object)new RectTransform[2];

	private TechTreeEdgeGraphic _edgeGraphic;

	private readonly TechTreeEdgeGraphic[] _pageEdgeGraphics = new TechTreeEdgeGraphic[2];

	private RectTransform _detailPanel;

	private Text _detailEmptyPrompt;

	private Image _detailIcon;

	private Text _detailTitle;

	private Text _detailLevel;

	private Text _detailStatus;

	private Image _detailAccent;

	private Text _detailBody;

	private GameObject _detailProgressGroup;

	private Image _detailProgressFill;

	private Text _detailProgressText;

	private Text _detailProgressSpeedText;

	private RectTransform _unlockRow;

	private RectTransform _researchCostRow;

	private Text _unlockHeading;

	private Text _researchCostHeading;

	private Button _researchButton;

	private Text _researchButtonText;

	private Text _legend;

	private RectTransform _searchFilterContent;

	private RectTransform _searchFilterTab;

	private Text _searchFilterTabText;

	private bool _searchFilterExpanded;

	private InputField _searchInput;

	private Button _searchClearButton;

	private Text _searchStatus;

	private string _searchText = string.Empty;

	private Button _matrixFilterButton;

	private Text _matrixFilterText;

	private RectTransform _matrixFilterMenu;

	private Button _combatFilterButton;

	private Text _combatFilterText;

	private RectTransform _combatFilterMenu;

	private Button _infiniteOnlyButton;

	private Text _infiniteOnlyText;

	private int _matrixFilter = -1;

	private int _combatFilter;

	private bool _infiniteOnly;

	private readonly HashSet<int> _utilityCombatTechIds = new HashSet<int>();

	private bool _utilityCombatTechIdsBuilt;

	private Font _font;

	private Dictionary<int, NodeView> _nodes = new Dictionary<int, NodeView>();

	private List<EdgeView> _edges = new List<EdgeView>();

	private readonly Dictionary<int, NodeView>[] _pageNodes = new Dictionary<int, NodeView>[2]
	{
		new Dictionary<int, NodeView>(),
		new Dictionary<int, NodeView>()
	};

	private readonly List<EdgeView>[] _pageEdges = new List<EdgeView>[2]
	{
		new List<EdgeView>(),
		new List<EdgeView>()
	};

	private readonly Dictionary<int, List<int>>[] _pageInferredParents = new Dictionary<int, List<int>>[2]
	{
		new Dictionary<int, List<int>>(),
		new Dictionary<int, List<int>>()
	};

	private Dictionary<int, List<int>> _inferredParents = new Dictionary<int, List<int>>();

	private readonly bool[] _pageBuilt = new bool[2];

	private readonly Vector2[] _pageGraphSize = (Vector2[])(object)new Vector2[2]
	{
		new Vector2(1100f, 720f),
		new Vector2(1100f, 720f)
	};

	private readonly Vector4[] _pageVisibleBounds = (Vector4[])(object)new Vector4[2]
	{
		new Vector4(0f, 1100f, 0f, -720f),
		new Vector4(0f, 1100f, 0f, -720f)
	};

	private readonly bool[] _pageVisibleBoundsValid = new bool[2];

	private readonly Vector2[] _pagePan = (Vector2[])(object)new Vector2[2]
	{
		Vector2.zero,
		Vector2.zero
	};

	private readonly float[] _pageZoom = new float[2] { 0.72f, 0.72f };

	private readonly bool[] _pageViewInitialized = new bool[2];

	private readonly float[] _pageLastStateRefresh = new float[2] { -999f, -999f };

	private readonly HashSet<int> _selectedPath = new HashSet<int>();

	private readonly HashSet<long> _selectedEdges = new HashSet<long>();

	private readonly HashSet<long> _backboneEdges = new HashSet<long>();

	private int _builtPage = -1;

	private int _selectedTechId;

	private bool _visible;

	private float _zoom = 0.72f;

	private Vector2 _baseGraphSize = new Vector2(1100f, 720f);

	private float _nextStateRefreshTime;

	private bool _savedViewStatePending = true;

	private static int[] MatrixIds => TechProto.matrixIds;

	internal static TechTreeView ActiveInstance { get; private set; }

	internal bool IsVisible => _visible;

	internal void Initialize(UITechTree tree)
	{
		ActiveInstance = this;
		_tree = tree;
		_font = (((Object)(object)tree.tabButtonText0 != (Object)null) ? tree.tabButtonText0.font : Resources.GetBuiltinResource<Font>("Arial.ttf"));
		CreateRoot();
		Hide();
	}

	internal TechTreeSavedViewState CaptureSavedViewState()
	{
		//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)
		TechTreeSavedViewState techTreeSavedViewState = TechTreeSavedViewState.CreateDefault();
		techTreeSavedViewState.Page = (((Object)(object)_tree != (Object)null) ? Mathf.Clamp(_tree.page, 0, 1) : Mathf.Clamp(_builtPage, 0, 1));
		techTreeSavedViewState.MatrixFilter = _matrixFilter;
		techTreeSavedViewState.CombatFilter = _combatFilter;
		techTreeSavedViewState.InfiniteOnly = _infiniteOnly;
		for (int i = 0; i < 2; i++)
		{
			techTreeSavedViewState.Zoom[i] = _pageZoom[i];
			techTreeSavedViewState.Pan[i] = _pagePan[i];
		}
		return techTreeSavedViewState;
	}

	internal void MarkSavedViewStatePending()
	{
		_savedViewStatePending = true;
	}

	private void ApplySavedViewState()
	{
		//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)
		if (_savedViewStatePending)
		{
			TechTreeSavedViewState techTreeSavedViewState = Plugin.SavedViewState;
			if (techTreeSavedViewState == null)
			{
				techTreeSavedViewState = TechTreeSavedViewState.CreateDefault();
			}
			_matrixFilter = Mathf.Clamp(techTreeSavedViewState.MatrixFilter, -1, 5);
			_combatFilter = Mathf.Clamp(techTreeSavedViewState.CombatFilter, 0, 2);
			_infiniteOnly = techTreeSavedViewState.InfiniteOnly;
			for (int i = 0; i < 2; i++)
			{
				_pageZoom[i] = Mathf.Clamp(techTreeSavedViewState.Zoom[i], 0.45f, 1.3333334f);
				_pagePan[i] = techTreeSavedViewState.Pan[i];
			}
			if ((Object)(object)_tree != (Object)null)
			{
				_tree.page = Mathf.Clamp(techTreeSavedViewState.Page, 0, 1);
			}
			_savedViewStatePending = false;
		}
	}

	internal void Show()
	{
		if ((Object)(object)_root == (Object)null)
		{
			CreateRoot();
		}
		ApplySavedViewState();
		_visible = true;
		((Component)_root).gameObject.SetActive(true);
		RefreshFilterLabels();
		RefreshPage();
		HideVanillaBottomGlow();
	}

	private void HideVanillaBottomGlow()
	{
		if ((Object)(object)_tree == (Object)null)
		{
			return;
		}
		Transform val = ((Component)_tree).transform.Find("bottom-bar");
		if (!((Object)(object)val == (Object)null))
		{
			Image component = ((Component)val).GetComponent<Image>();
			if ((Object)(object)component != (Object)null)
			{
				((Behaviour)component).enabled = false;
			}
		}
	}

	internal void Hide()
	{
		_visible = false;
		SetSearchFilterExpanded(expanded: false);
		if ((Object)(object)_root != (Object)null)
		{
			((Component)_root).gameObject.SetActive(false);
		}
		RestoreVanillaGraphs();
	}

	private bool PointerOverQueuedTech()
	{
		if ((Object)(object)UIRoot.instance == (Object)null || (Object)(object)UIRoot.instance.uiGame == (Object)null || (Object)(object)UIRoot.instance.uiGame.techTree == (Object)null)
		{
			return false;
		}
		UIResearchQueue resQueueUI = UIRoot.instance.uiGame.techTree.resQueueUI;
		if ((Object)(object)resQueueUI == (Object)null || resQueueUI.nodes == null)
		{
			return false;
		}
		for (int i = 0; i < resQueueUI.nodes.Length; i++)
		{
			UIResearchQueueNode val = resQueueUI.nodes[i];
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val.trans == (Object)null) && ((Component)val).gameObject.activeInHierarchy && PointerInside(val.trans))
			{
				return true;
			}
		}
		return false;
	}

	private void LateUpdate()
	{
		if (!_visible || (Object)(object)_tree == (Object)null)
		{
			return;
		}
		if (Input.GetMouseButtonDown(1))
		{
			if (!PointerOverQueuedTech() && (Object)(object)UIRoot.instance != (Object)null && (Object)(object)UIRoot.instance.uiGame != (Object)null)
			{
				UIRoot.instance.uiGame.ShutTechTree();
			}
			return;
		}
		if ((Object)(object)_tree.graphGroup0 != (Object)null && ((Component)_tree.graphGroup0).gameObject.activeSelf)
		{
			((Component)_tree.graphGroup0).gameObject.SetActive(false);
		}
		if ((Object)(object)_tree.graphGroup1 != (Object)null && ((Component)_tree.graphGroup1).gameObject.activeSelf)
		{
			((Component)_tree.graphGroup1).gameObject.SetActive(false);
		}
		if (_builtPage != _tree.page)
		{
			RefreshPage();
		}
		UpdateNodeResearchWingHoverStates();
		UpdateDetailPanelPosition();
		UpdateSearchFilterFlyout();
		if (_selectedTechId != 0)
		{
			RefreshDetailProgress();
		}
		if (Time.unscaledTime >= _nextStateRefreshTime)
		{
			_nextStateRefreshTime = Time.unscaledTime + 1.5f;
			RefreshNodeStates();
			if (_selectedTechId != 0)
			{
				RefreshResearchButton();
			}
		}
	}

	internal void RefreshPage()
	{
		//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_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		if (_visible && !((Object)(object)_tree == (Object)null) && GameMain.history != null)
		{
			HideVanillaGraphs();
			int num = (_builtPage = Mathf.Clamp(_tree.page, 0, 1));
			RefreshFilterLabels();
			_selectedTechId = 0;
			_selectedPath.Clear();
			_selectedEdges.Clear();
			ActivatePageCache(num);
			if (!_pageBuilt[num])
			{
				BuildGraph(num);
				_pageBuilt[num] = true;
				_pageGraphSize[num] = _baseGraphSize;
				InitializePageView(num);
			}
			else
			{
				_baseGraphSize = _pageGraphSize[num];
				_zoom = _pageZoom[num];
				ApplyPageTransform(num);
			}
			if (Time.unscaledTime - _pageLastStateRefresh[num] >= 1f)
			{
				RefreshNodeStates();
			}
			ApplyFilters();
			RefreshEdges();
			RefreshSearchStatus();
			UpdateDetailPanelPosition();
			_nextStateRefreshTime = Time.unscaledTime + 1.5f;
			ClearDetails();
		}
	}

	private void ActivatePageCache(int page)
	{
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		for (int i = 0; i < _pageGraphCanvas.Length; i++)
		{
			if ((Object)(object)_pageGraphCanvas[i] != (Object)null)
			{
				((Component)_pageGraphCanvas[i]).gameObject.SetActive(i == page);
			}
		}
		_graphCanvas = _pageGraphCanvas[page];
		_edgeGraphic = _pageEdgeGraphics[page];
		_nodes = _pageNodes[page];
		_edges = _pageEdges[page];
		_inferredParents = _pageInferredParents[page];
		_baseGraphSize = _pageGraphSize[page];
	}

	private void CreateRoot()
	{
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0188: Unknown result type (might be due to invalid IL or missing references)
		//IL_019e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		Transform val = (((Object)(object)_tree.graphGroup0 != (Object)null && (Object)(object)((Transform)_tree.graphGroup0).parent != (Object)null) ? ((Transform)_tree.graphGroup0).parent : ((Component)_tree).transform);
		GameObject val2 = CreateUIObject("TechTreeUX", val);
		_root = val2.GetComponent<RectTransform>();
		Stretch(_root);
		((Transform)_root).localScale = Vector3.one;
		if ((Object)(object)_tree.graphGroup0 != (Object)null && (Object)(object)((Transform)_tree.graphGroup0).parent == (Object)(object)val)
		{
			int siblingIndex = ((Transform)_tree.graphGroup0).GetSiblingIndex();
			((Transform)_root).SetSiblingIndex(siblingIndex);
		}
		Image obj = val2.AddComponent<Image>();
		((Graphic)obj).color = new Color(0f, 0f, 0f, 0.001f);
		((Graphic)obj).raycastTarget = true;
		GameObject val3 = CreateUIObject("Viewport", (Transform)(object)_root);
		_viewport = val3.GetComponent<RectTransform>();
		Stretch(_viewport);
		Image obj2 = val3.AddComponent<Image>();
		((Graphic)obj2).color = new Color(0.012f, 0.017f, 0.025f, 0.82f);
		((Graphic)obj2).raycastTarget = true;
		val3.AddComponent<TechTreeInputCatcher>().Owner = this;
		for (int i = 0; i < 2; i++)
		{
			RectTransform component = CreateUIObject("GraphCanvas_" + i, (Transform)(object)_viewport).GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(0f, 1f);
			component.pivot = new Vector2(0f, 1f);
			component.anchoredPosition = Vector2.zero;
			((Component)component).gameObject.SetActive(false);
			_pageGraphCanvas[i] = component;
		}
		_graphCanvas = _pageGraphCanvas[0];
		_nodes = _pageNodes[0];
		_edges = _pageEdges[0];
		CreateDetailPanel();
		CreateSearchFilterFlyout();
		CreateSearchBox();
		CreateFilterBar();
		CreateLegend();
	}

	private void CreateSearchFilterFlyout()
	{
		//IL_003b: 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_0057: 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_008b: 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_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: 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_019b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a5: Expected O, but got Unknown
		GameObject val = CreateUIObject("SearchFilterContent", (Transform)(object)_root);
		_searchFilterContent = val.GetComponent<RectTransform>();
		RectTransform searchFilterContent = _searchFilterContent;
		RectTransform searchFilterContent2 = _searchFilterContent;
		Vector2 val2 = default(Vector2);
		((Vector2)(ref val2))..ctor(0.5f, 1f);
		searchFilterContent2.anchorMax = val2;
		searchFilterContent.anchorMin = val2;
		_searchFilterContent.pivot = new Vector2(0.5f, 1f);
		_searchFilterContent.sizeDelta = new Vector2(420f, 142f);
		_searchFilterContent.anchoredPosition = new Vector2(220f, -28f);
		Image obj = val.AddComponent<Image>();
		((Graphic)obj).color = new Color(0.015f, 0.022f, 0.032f, 0.94f);
		((Graphic)obj).raycastTarget = true;
		GameObject val3 = CreateUIObject("SearchFilterTab", (Transform)(object)_root);
		_searchFilterTab = val3.GetComponent<RectTransform>();
		RectTransform searchFilterTab = _searchFilterTab;
		RectTransform searchFilterTab2 = _searchFilterTab;
		((Vector2)(ref val2))..ctor(0.5f, 1f);
		searchFilterTab2.anchorMax = val2;
		searchFilterTab.anchorMin = val2;
		_searchFilterTab.pivot = new Vector2(0.5f, 1f);
		_searchFilterTab.sizeDelta = new Vector2(150f, 24f);
		_searchFilterTab.anchoredPosition = new Vector2(220f, -4f);
		Image val4 = val3.AddComponent<Image>();
		((Graphic)val4).color = new Color(0.045f, 0.06f, 0.078f, 0.98f);
		((Graphic)val4).raycastTarget = true;
		Button obj2 = val3.AddComponent<Button>();
		((Selectable)obj2).targetGraphic = (Graphic)(object)val4;
		((UnityEvent)obj2.onClick).AddListener(new UnityAction(ToggleSearchFilterFlyout));
		_searchFilterTabText = CreateText("Text", (Transform)(object)_searchFilterTab, 12, (TextAnchor)4);
		Stretch(((Graphic)_searchFilterTabText).rectTransform);
		_searchFilterTabText.fontStyle = (FontStyle)1;
		((Graphic)_searchFilterTabText).raycastTarget = false;
		SetSearchFilterExpanded(expanded: false);
	}

	private void ToggleSearchFilterFlyout()
	{
		SetSearchFilterExpanded(!_searchFilterExpanded);
	}

	private void SetSearchFilterExpanded(bool expanded)
	{
		_searchFilterExpanded = expanded;
		if ((Object)(object)_searchFilterContent != (Object)null)
		{
			((Component)_searchFilterContent).gameObject.SetActive(expanded);
		}
		if (!expanded)
		{
			if ((Object)(object)_matrixFilterMenu != (Object)null)
			{
				((Component)_matrixFilterMenu).gameObject.SetActive(false);
			}
			if ((Object)(object)_combatFilterMenu != (Object)null)
			{
				((Component)_combatFilterMenu).gameObject.SetActive(false);
			}
		}
		if ((Object)(object)_searchFilterTabText != (Object)null)
		{
			_searchFilterTabText.text = (expanded ? "Search / Filters ▲" : "Search / Filters ▼");
		}
	}

	private bool PointerInside(RectTransform rect)
	{
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)rect == (Object)null || !((Component)rect).gameObject.activeInHierarchy)
		{
			return false;
		}
		Canvas componentInParent = ((Component)rect).GetComponentInParent<Canvas>();
		Camera val = null;
		if ((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0)
		{
			val = componentInParent.worldCamera;
		}
		return RectTransformUtility.RectangleContainsScreenPoint(rect, Vector2.op_Implicit(Input.mousePosition), val);
	}

	private void UpdateNodeResearchWingHoverStates()
	{
		if (_nodes == null || _nodes.Count == 0)
		{
			return;
		}
		foreach (NodeView value in _nodes.Values)
		{
			if (value != null && !((Object)(object)value.Root == (Object)null) && value.Proto != null)
			{
				bool flag = PointerInside(value.Root);
				bool flag2 = value.ResearchWingOpen && (Object)(object)value.ResearchWingRect != (Object)null && PointerInside(value.ResearchWingRect);
				bool flag3 = _selectedTechId == ((Proto)value.Proto).ID || flag || flag2;
				bool flag4 = flag || flag2;
				if (value.Hovered != flag4 || value.ResearchWingOpen != flag3)
				{
					value.Hovered = flag4;
					value.ResearchWingOpen = flag3;
					RefreshNodeResearchWing(value);
				}
			}
		}
	}

	private void UpdateSearchFilterFlyout()
	{
		if ((Object)(object)_searchFilterTab == (Object)null || (Object)(object)_searchFilterContent == (Object)null)
		{
			return;
		}
		bool num = (Object)(object)_searchInput != (Object)null && _searchInput.isFocused;
		bool flag = PointerInside(_searchFilterTab);
		bool flag2 = _searchFilterExpanded && PointerInside(_searchFilterContent);
		bool flag3 = (Object)(object)_matrixFilterMenu != (Object)null && ((Component)_matrixFilterMenu).gameObject.activeSelf && PointerInside(_matrixFilterMenu);
		bool flag4 = (Object)(object)_combatFilterMenu != (Object)null && ((Component)_combatFilterMenu).gameObject.activeSelf && PointerInside(_combatFilterMenu);
		if (num || flag || flag2 || flag3 || flag4)
		{
			if (!_searchFilterExpanded)
			{
				SetSearchFilterExpanded(expanded: true);
			}
		}
		else if (_searchFilterExpanded)
		{
			SetSearchFilterExpanded(expanded: false);
		}
	}

	private void CreateSearchBox()
	{
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: 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_006f: 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_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_016b: 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_01ab: 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_0205: Unknown result type (might be due to invalid IL or missing references)
		//IL_0218: Unknown result type (might be due to invalid IL or missing references)
		//IL_022e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0244: 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_02a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ad: Expected O, but got Unknown
		//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_0330: Unknown result type (might be due to invalid IL or missing references)
		//IL_0337: Unknown result type (might be due to invalid IL or missing references)
		//IL_0349: Unknown result type (might be due to invalid IL or missing references)
		//IL_035e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0372: Unknown result type (might be due to invalid IL or missing references)
		//IL_0396: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = CreateUIObject("Search", (Transform)(object)_searchFilterContent);
		RectTransform component = val.GetComponent<RectTransform>();
		Vector2 val2 = default(Vector2);
		((Vector2)(ref val2))..ctor(0.5f, 1f);
		component.anchorMax = val2;
		component.anchorMin = val2;
		component.pivot = new Vector2(0.5f, 1f);
		component.sizeDelta = new Vector2(390f, 36f);
		component.anchoredPosition = new Vector2(0f, -6f);
		Image val3 = val.AddComponent<Image>();
		((Graphic)val3).color = new Color(0.035f, 0.048f, 0.064f, 0.98f);
		((Graphic)val3).raycastTarget = true;
		_searchInput = val.AddComponent<InputField>();
		((Selectable)_searchInput).targetGraphic = (Graphic)(object)val3;
		_searchInput.lineType = (LineType)0;
		_searchInput.contentType = (ContentType)0;
		_searchInput.characterLimit = 80;
		Text val4 = CreateText("Text", (Transform)(object)component, 15, (TextAnchor)3);
		RectTransform rectTransform = ((Graphic)val4).rectTransform;
		Stretch(rectTransform);
		rectTransform.offsetMin = new Vector2(12f, 3f);
		rectTransform.offsetMax = new Vector2(-42f, -3f);
		val4.supportRichText = false;
		((Graphic)val4).raycastTarget = false;
		_searchInput.textComponent = val4;
		Text val5 = CreateText("Placeholder", (Transform)(object)component, 15, (TextAnchor)3);
		RectTransform rectTransform2 = ((Graphic)val5).rectTransform;
		Stretch(rectTransform2);
		rectTransform2.offsetMin = new Vector2(12f, 3f);
		rectTransform2.offsetMax = new Vector2(-42f, -3f);
		val5.text = "Search technologies...";
		((Graphic)val5).color = new Color(0.58f, 0.66f, 0.74f, 0.78f);
		val5.fontStyle = (FontStyle)2;
		((Graphic)val5).raycastTarget = false;
		_searchInput.placeholder = (Graphic)(object)val5;
		GameObject val6 = CreateUIObject("Clear", (Transform)(object)component);
		RectTransform component2 = val6.GetComponent<RectTransform>();
		((Vector2)(ref val2))..ctor(1f, 0.5f);
		component2.anchorMax = val2;
		component2.anchorMin = val2;
		component2.pivot = new Vector2(1f, 0.5f);
		component2.sizeDelta = new Vector2(32f, 30f);
		component2.anchoredPosition = new Vector2(-3f, 0f);
		Image val7 = val6.AddComponent<Image>();
		((Graphic)val7).color = new Color(0.11f, 0.14f, 0.18f, 0.95f);
		_searchClearButton = val6.AddComponent<Button>();
		((Selectable)_searchClearButton).targetGraphic = (Graphic)(object)val7;
		((UnityEvent)_searchClearButton.onClick).AddListener(new UnityAction(ClearSearch));
		Text obj = CreateText("X", (Transform)(object)component2, 16, (TextAnchor)4);
		Stretch(((Graphic)obj).rectTransform);
		obj.text = "×";
		((Graphic)obj).raycastTarget = false;
		((Graphic)obj).color = new Color(0.8f, 0.86f, 0.92f, 1f);
		_searchStatus = CreateText("SearchStatus", (Transform)(object)_searchFilterContent, 12, (TextAnchor)1);
		RectTransform rectTransform3 = ((Graphic)_searchStatus).rectTransform;
		((Vector2)(ref val2))..ctor(0.5f, 1f);
		rectTransform3.anchorMax = val2;
		rectTransform3.anchorMin = val2;
		rectTransform3.pivot = new Vector2(0.5f, 1f);
		rectTransform3.sizeDelta = new Vector2(390f, 22f);
		rectTransform3.anchoredPosition = new Vector2(0f, -114f);
		((Graphic)_searchStatus).color = new Color(0.68f, 0.76f, 0.84f, 0.95f);
		_searchStatus.text = "";
		((UnityEvent<string>)(object)_searchInput.onValueChanged).AddListener((UnityAction<string>)OnSearchChanged);
	}

	private void CreateFilterBar()
	{
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: 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_006f: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Expected O, but got Unknown
		//IL_013f: 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_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: 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_01ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ec: Expected O, but got Unknown
		//IL_025b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0262: Unknown result type (might be due to invalid IL or missing references)
		//IL_0275: Unknown result type (might be due to invalid IL or missing references)
		//IL_028b: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_0300: Unknown result type (might be due to invalid IL or missing references)
		//IL_030a: Expected O, but got Unknown
		GameObject val = CreateUIObject("MatrixFilter", (Transform)(object)_searchFilterContent);
		RectTransform component = val.GetComponent<RectTransform>();
		Vector2 val2 = default(Vector2);
		((Vector2)(ref val2))..ctor(0.5f, 1f);
		component.anchorMax = val2;
		component.anchorMin = val2;
		component.pivot = new Vector2(0.5f, 1f);
		component.sizeDelta = new Vector2(190f, 30f);
		component.anchoredPosition = new Vector2(-102f, -46f);
		Image val3 = val.AddComponent<Image>();
		((Graphic)val3).color = new Color(0.045f, 0.06f, 0.078f, 0.96f);
		_matrixFilterButton = val.AddComponent<Button>();
		((Selectable)_matrixFilterButton).targetGraphic = (Graphic)(object)val3;
		((UnityEvent)_matrixFilterButton.onClick).AddListener(new UnityAction(ToggleMatrixFilterMenu));
		_matrixFilterText = CreateText("Text", (Transform)(object)component, 13, (TextAnchor)4);
		Stretch(((Graphic)_matrixFilterText).rectTransform);
		_matrixFilterText.fontStyle = (FontStyle)1;
		((Graphic)_matrixFilterText).raycastTarget = false;
		GameObject val4 = CreateUIObject("CombatFilter", (Transform)(object)_searchFilterContent);
		RectTransform component2 = val4.GetComponent<RectTransform>();
		((Vector2)(ref val2))..ctor(0.5f, 1f);
		component2.anchorMax = val2;
		component2.anchorMin = val2;
		component2.pivot = new Vector2(0.5f, 1f);
		component2.sizeDelta = new Vector2(190f, 30f);
		component2.anchoredPosition = new Vector2(102f, -46f);
		Image val5 = val4.AddComponent<Image>();
		((Graphic)val5).color = new Color(0.045f, 0.06f, 0.078f, 0.96f);
		_combatFilterButton = val4.AddComponent<Button>();
		((Selectable)_combatFilterButton).targetGraphic = (Graphic)(object)val5;
		((UnityEvent)_combatFilterButton.onClick).AddListener(new UnityAction(ToggleCombatFilterMenu));
		_combatFilterText = CreateText("Text", (Transform)(object)component2, 13, (TextAnchor)4);
		Stretch(((Graphic)_combatFilterText).rectTransform);
		_combatFilterText.fontStyle = (FontStyle)1;
		((Graphic)_combatFilterText).raycastTarget = false;
		GameObject val6 = CreateUIObject("InfiniteOnly", (Transform)(object)_searchFilterContent);
		RectTransform component3 = val6.GetComponent<RectTransform>();
		((Vector2)(ref val2))..ctor(0.5f, 1f);
		component3.anchorMax = val2;
		component3.anchorMin = val2;
		component3.pivot = new Vector2(0.5f, 1f);
		component3.sizeDelta = new Vector2(190f, 26f);
		component3.anchoredPosition = new Vector2(0f, -80f);
		Image val7 = val6.AddComponent<Image>();
		((Graphic)val7).color = new Color(0.045f, 0.06f, 0.078f, 0.96f);
		_infiniteOnlyButton = val6.AddComponent<Button>();
		((Selectable)_infiniteOnlyButton).targetGraphic = (Graphic)(object)val7;
		((UnityEvent)_infiniteOnlyButton.onClick).AddListener(new UnityAction(ToggleInfiniteOnly));
		_infiniteOnlyText = CreateText("Text", (Transform)(object)component3, 13, (TextAnchor)4);
		Stretch(((Graphic)_infiniteOnlyText).rectTransform);
		_infiniteOnlyText.fontStyle = (FontStyle)1;
		((Graphic)_infiniteOnlyText).raycastTarget = false;
		_matrixFilterMenu = CreateFilterMenu("MatrixFilterMenu", -102f, new string[7] { "All", "Blue", "≤ Red", "≤ Yellow", "≤ Purple", "≤ Green", "White" }, matrixMenu: true);
		_combatFilterMenu = CreateFilterMenu("CombatFilterMenu", 102f, new string[3] { "All", "Utility", "Hidden" }, matrixMenu: false);
		RefreshFilterLabels();
	}

	private RectTransform CreateFilterMenu(string name, float x, string[] labels, bool matrixMenu)
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: 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_0070: 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_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Unknown result type (might be due to invalid IL or missing references)
		//IL_01be: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c8: Expected O, but got Unknown
		//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ad: Expected O, but got Unknown
		GameObject val = CreateUIObject(name, (Transform)(object)_searchFilterContent);
		RectTransform component = val.GetComponent<RectTransform>();
		Vector2 val2 = default(Vector2);
		((Vector2)(ref val2))..ctor(0.5f, 1f);
		component.anchorMax = val2;
		component.anchorMin = val2;
		component.pivot = new Vector2(0.5f, 1f);
		component.sizeDelta = new Vector2(190f, (float)labels.Length * 26f + 4f);
		component.anchoredPosition = new Vector2(x, -78f);
		Image obj = val.AddComponent<Image>();
		((Graphic)obj).color = new Color(0.018f, 0.026f, 0.038f, 0.995f);
		((Graphic)obj).raycastTarget = true;
		for (int i = 0; i < labels.Length; i++)
		{
			int value = (matrixMenu ? (i - 1) : i);
			GameObject obj2 = CreateUIObject("Option_" + i, (Transform)(object)component);
			RectTransform component2 = obj2.GetComponent<RectTransform>();
			((Vector2)(ref val2))..ctor(0.5f, 1f);
			component2.anchorMax = val2;
			component2.anchorMin = val2;
			component2.pivot = new Vector2(0.5f, 1f);
			component2.sizeDelta = new Vector2(184f, 25f);
			component2.anchoredPosition = new Vector2(0f, -2f - (float)i * 26f);
			Image val3 = obj2.AddComponent<Image>();
			((Graphic)val3).color = new Color(0.05f, 0.066f, 0.086f, 0.99f);
			Button val4 = obj2.AddComponent<Button>();
			((Selectable)val4).targetGraphic = (Graphic)(object)val3;
			if (matrixMenu)
			{
				((UnityEvent)val4.onClick).AddListener((UnityAction)delegate
				{
					SetMatrixFilter(value);
				});
			}
			else
			{
				((UnityEvent)val4.onClick).AddListener((UnityAction)delegate
				{
					SetCombatFilter(value);
				});
			}
			Text obj3 = CreateText("Text", (Transform)(object)component2, 13, (TextAnchor)4);
			Stretch(((Graphic)obj3).rectTransform);
			obj3.text = labels[i];
			((Graphic)obj3).raycastTarget = false;
		}
		((Transform)component).SetAsLastSibling();
		val.SetActive(false);
		return component;
	}

	private void ToggleMatrixFilterMenu()
	{
		if (!((Object)(object)_matrixFilterMenu == (Object)null))
		{
			bool flag = !((Component)_matrixFilterMenu).gameObject.activeSelf;
			if ((Object)(object)_combatFilterMenu != (Object)null)
			{
				((Component)_combatFilterMenu).gameObject.SetActive(false);
			}
			((Component)_matrixFilterMenu).gameObject.SetActive(flag);
			if (flag)
			{
				((Transform)_matrixFilterMenu).SetAsLastSibling();
			}
		}
	}

	private void ToggleCombatFilterMenu()
	{
		if (!((Object)(object)_combatFilterMenu == (Object)null))
		{
			bool flag = !((Component)_combatFilterMenu).gameObject.activeSelf;
			if ((Object)(object)_matrixFilterMenu != (Object)null)
			{
				((Component)_matrixFilterMenu).gameObject.SetActive(false);
			}
			((Component)_combatFilterMenu).gameObject.SetActive(flag);
			if (flag)
			{
				((Transform)_combatFilterMenu).SetAsLastSibling();
			}
		}
	}

	private void ToggleInfiniteOnly()
	{
		if (_builtPage == 1)
		{
			_infiniteOnly = !_infiniteOnly;
			RefreshFilterLabels();
			ApplyFilters();
		}
	}

	private void SetMatrixFilter(int value)
	{
		_matrixFilter = Mathf.Clamp(value, -1, 5);
		if ((Object)(object)_matrixFilterMenu != (Object)null)
		{
			((Component)_matrixFilterMenu).gameObject.SetActive(false);
		}
		RefreshFilterLabels();
		ApplyFilters();
	}

	private void SetCombatFilter(int value)
	{
		_combatFilter = Mathf.Clamp(value, 0, 2);
		if ((Object)(object)_combatFilterMenu != (Object)null)
		{
			((Component)_combatFilterMenu).gameObject.SetActive(false);
		}
		RefreshFilterLabels();
		ApplyFilters();
	}

	private void RefreshFilterLabels()
	{
		//IL_017c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_matrixFilterText != (Object)null)
		{
			switch (_matrixFilter)
			{
			case 0:
				_matrixFilterText.text = "Matrix: Blue ▼";
				break;
			case 1:
				_matrixFilterText.text = "Matrix: ≤ Red ▼";
				break;
			case 2:
				_matrixFilterText.text = "Matrix: ≤ Yellow ▼";
				break;
			case 3:
				_matrixFilterText.text = "Matrix: ≤ Purple ▼";
				break;
			case 4:
				_matrixFilterText.text = "Matrix: ≤ Green ▼";
				break;
			case 5:
				_matrixFilterText.text = "Matrix: White ▼";
				break;
			default:
				_matrixFilterText.text = "Matrix: All ▼";
				break;
			}
		}
		if ((Object)(object)_combatFilterText != (Object)null)
		{
			switch (_combatFilter)
			{
			case 1:
				_combatFilterText.text = "Combat: Utility ▼";
				break;
			case 2:
				_combatFilterText.text = "Combat: Hidden ▼";
				break;
			default:
				_combatFilterText.text = "Combat: All ▼";
				break;
			}
		}
		bool flag = _builtPage == 1;
		if ((Object)(object)_infiniteOnlyButton != (Object)null)
		{
			((Selectable)_infiniteOnlyButton).interactable = flag;
		}
		if ((Object)(object)_infiniteOnlyText != (Object)null)
		{
			_infiniteOnlyText.text = (_infiniteOnly ? "Infinite only: ON" : "Infinite only: OFF");
			((Graphic)_infiniteOnlyText).color = (Color)(flag ? Color.white : new Color(0.45f, 0.48f, 0.52f, 1f));
		}
	}

	private void ApplyFilters()
	{
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		if (_builtPage < 0 || _nodes == null)
		{
			return;
		}
		if (_selectedTechId != 0 && (!_nodes.TryGetValue(_selectedTechId, out var value) || value == null || !NodePassesFilters(value.Proto)))
		{
			_selectedTechId = 0;
			_selectedPath.Clear();
			_selectedEdges.Clear();
			ClearDetails();
		}
		foreach (NodeView value2 in _nodes.Values)
		{
			if (value2 != null && !((Object)(object)value2.Root == (Object)null))
			{
				value2.Root.anchoredPosition = value2.OriginalPosition;
				((Component)value2.Root).gameObject.SetActive(NodePassesFilters(value2.Proto));
			}
		}
		if (_builtPage == 1 && _matrixFilter == 5)
		{
			CompactWhiteUpgradeFamilies();
		}
		else if (_combatFilter != 0)
		{
			CompactVisibleRows();
		}
		CacheVisibleBounds(_builtPage);
		RebuildEdgeGeometry();
		if (_matrixFilter >= 0 || _combatFilter != 0 || (_builtPage == 1 && _infiniteOnly))
		{
			CenterViewOnVisibleNodes(_builtPage);
		}
		RefreshNodeStates();
		RefreshEdges();
		RefreshSearchStatus();
	}

	private void CompactWhiteUpgradeFamilies()
	{
		//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
		if (_builtPage != 1 || _nodes == null)
		{
			return;
		}
		List<float> list = new List<float>();
		float num = float.MaxValue;
		foreach (NodeView value in _nodes.Values)
		{
			if (value != null && !((Object)(object)value.Root == (Object)null) && ((Component)value.Root).gameObject.activeSelf)
			{
				AddUniqueRow(list, value.OriginalPosition.y);
				num = Mathf.Min(num, value.OriginalPosition.x);
			}
		}
		if (list.Count == 0)
		{
			return;
		}
		list.Sort((float a, float b) => b.CompareTo(a));
		float num2 = Mathf.Max(GetTypicalRowGapForPage(1), 236f);
		float num3 = Mathf.Max(GetTypicalColumnGapForPage(1), 214f);
		int num4 = (list.Count + 1) / 2;
		int num5 = 1;
		for (int num6 = 0; num6 < list.Count; num6++)
		{
			int num7 = 0;
			foreach (NodeView value2 in _nodes.Values)
			{
				if (value2 != null && !((Object)(object)value2.Root == (Object)null) && ((Component)value2.Root).gameObject.activeSelf && Mathf.Abs(value2.OriginalPosition.y - list[num6]) < 0.1f)
				{
					num7++;
				}
			}
			if (num7 > num5)
			{
				num5 = num7;
			}
		}
		float num8 = (float)(num5 - 1) * num3 + 104f;
		float num9 = 284f;
		float num10 = num + num8 + num9;
		float num11 = list[0];
		for (int num12 = 0; num12 < list.Count; num12++)
		{
			float num13 = list[num12];
			List<NodeView> list2 = new List<NodeView>();
			foreach (NodeView value3 in _nodes.Values)
			{
				if (value3 != null && !((Object)(object)value3.Root == (Object)null) && ((Component)value3.Root).gameObject.activeSelf && Mathf.Abs(value3.OriginalPosition.y - num13) < 0.1f)
				{
					list2.Add(value3);
				}
			}
			list2.Sort((NodeView a, NodeView b) => a.OriginalPosition.x.CompareTo(b.OriginalPosition.x));
			int num14 = num12 / num4;
			int num15 = num12 % num4;
			float num16 = ((num14 == 0) ? num : num10);
			float num17 = num11 - (float)num15 * num2;
			for (int num18 = 0; num18 < list2.Count; num18++)
			{
				list2[num18].Root.anchoredPosition = new Vector2(num16 + (float)num18 * num3, num17);
			}
		}
	}

	private float GetTypicalRowGapForPage(int page)
	{
		if (page < 0 || page >= 2)
		{
			return 0f;
		}
		List<float> list = new List<float>();
		foreach (NodeView value in _pageNodes[page].Values)
		{
			if (value != null)
			{
				AddUniqueRow(list, value.OriginalPosition.y);
			}
		}
		if (list.Count < 2)
		{
			return 0f;
		}
		list.Sort((float a, float b) => b.CompareTo(a));
		return GetTypicalRowGap(list);
	}

	private float GetTypicalColumnGapForPage(int page)
	{
		if (page < 0 || page >= 2)
		{
			return 0f;
		}
		List<float> list = new List<float>();
		List<float> list2 = new List<float>();
		foreach (NodeView value in _pageNodes[page].Values)
		{
			if (value != null)
			{
				AddUniqueRow(list2, value.OriginalPosition.y);
			}
		}
		for (int i = 0; i < list2.Count; i++)
		{
			List<float> list3 = new List<float>();
			foreach (NodeView value2 in _pageNodes[page].Values)
			{
				if (value2 != null && Mathf.Abs(value2.OriginalPosition.y - list2[i]) < 0.1f)
				{
					list3.Add(value2.OriginalPosition.x);
				}
			}
			if (list3.Count < 2)
			{
				continue;
			}
			list3.Sort();
			for (int j = 0; j + 1 < list3.Count; j++)
			{
				float num = list3[j + 1] - list3[j];
				if (num > 105f)
				{
					list.Add(num);
				}
			}
		}
		if (list.Count == 0)
		{
			return 0f;
		}
		list.Sort();
		return list[list.Count / 2];
	}

	private void CompactVisibleRows()
	{
		//IL_022a: Unknown result type (might be due to invalid IL or missing references)
		List<float> list = new List<float>();
		List<float> list2 = new List<float>();
		foreach (NodeView value2 in _nodes.Values)
		{
			if (value2 != null && !((Object)(object)value2.Root == (Object)null))
			{
				AddUniqueRow(list, value2.OriginalPosition.y);
				if (((Component)value2.Root).gameObject.activeSelf)
				{
					AddUniqueRow(list2, value2.OriginalPosition.y);
				}
			}
		}
		if (list2.Count < 2 || list.Count < 2)
		{
			return;
		}
		list.Sort((float a, float b) => b.CompareTo(a));
		list2.Sort((float a, float b) => b.CompareTo(a));
		float typicalRowGap = GetTypicalRowGap(list);
		if (typicalRowGap < 1f)
		{
			return;
		}
		Dictionary<float, int> dictionary = new Dictionary<float, int>();
		for (int num = 0; num < list.Count; num++)
		{
			dictionary[list[num]] = num;
		}
		Dictionary<float, float> dictionary2 = new Dictionary<float, float>();
		float num2 = list2[0];
		float num3 = (dictionary2[num2] = num2);
		for (int num5 = 1; num5 < list2.Count; num5++)
		{
			float num6 = list2[num5];
			int num7 = FindRowIndex(list, num2);
			int num8 = FindRowIndex(list, num6);
			int num9 = Mathf.Max(0, num8 - num7 - 1);
			float num10 = num2 - num6;
			float num11 = ((num9 > 0) ? Mathf.Max(typicalRowGap, num10 - (float)num9 * typicalRowGap) : num10);
			num3 = (dictionary2[num6] = num3 - num11);
			num2 = num6;
		}
		foreach (NodeView value3 in _nodes.Values)
		{
			if (value3 != null && !((Object)(object)value3.Root == (Object)null) && ((Component)value3.Root).gameObject.activeSelf && TryGetRowValue(dictionary2, value3.OriginalPosition.y, out var value))
			{
				value3.Root.anchoredPosition = new Vector2(value3.OriginalPosition.x, value);
			}
		}
	}

	private static void AddUniqueRow(List<float> rows, float y)
	{
		for (int i = 0; i < rows.Count; i++)
		{
			if (Mathf.Abs(rows[i] - y) < 0.1f)
			{
				return;
			}
		}
		rows.Add(y);
	}

	private static int FindRowIndex(List<float> rows, float y)
	{
		for (int i = 0; i < rows.Count; i++)
		{
			if (Mathf.Abs(rows[i] - y) < 0.1f)
			{
				return i;
			}
		}
		return -1;
	}

	private static bool TryGetRowValue(Dictionary<float, float> values, float key, out float value)
	{
		foreach (KeyValuePair<float, float> value2 in values)
		{
			if (Mathf.Abs(value2.Key - key) < 0.1f)
			{
				value = value2.Value;
				return true;
			}
		}
		value = key;
		return false;
	}

	private static float GetTypicalRowGap(List<float> rows)
	{
		List<float> list = new List<float>();
		for (int i = 0; i + 1 < rows.Count; i++)
		{
			float num = rows[i] - rows[i + 1];
			if (num > 1f)
			{
				list.Add(num);
			}
		}
		if (list.Count == 0)
		{
			return 0f;
		}
		list.Sort();
		return list[list.Count / 2];
	}

	private void CacheVisibleBounds(int page)
	{
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: 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)
		if (page < 0 || page >= 2)
		{
			return;
		}
		bool flag = false;
		float num = float.MaxValue;
		float num2 = float.MinValue;
		float num3 = float.MinValue;
		float num4 = float.MaxValue;
		foreach (NodeView value in _pageNodes[page].Values)
		{
			if (value != null && !((Object)(object)value.Root == (Object)null) && ((Component)value.Root).gameObject.activeSelf)
			{
				Vector2 anchoredPosition = value.Root.anchoredPosition;
				num = Mathf.Min(num, anchoredPosition.x);
				num2 = Mathf.Max(num2, anchoredPosition.x + 104f);
				num3 = Mathf.Max(num3, anchoredPosition.y);
				num4 = Mathf.Min(num4, anchoredPosition.y - 104f);
				flag = true;
			}
		}
		if (!flag)
		{
			_pageVisibleBoundsValid[page] = false;
			return;
		}
		_pageVisibleBounds[page] = new Vector4(num, num2, num3, num4);
		_pageVisibleBoundsValid[page] = true;
	}

	private void CenterViewOnVisibleNodes(int page)
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: 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_0043: 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_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		if (page >= 0 && page < 2 && !((Object)(object)_viewport == (Object)null) && _pageVisibleBoundsValid[page])
		{
			Vector4 val = _pageVisibleBounds[page];
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor((val.x + val.y) * 0.5f, (val.z + val.w) * 0.5f);
			Rect rect = _viewport.rect;
			float num = ((Rect)(ref rect)).width * 0.5f;
			rect = _viewport.rect;
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(num, (0f - ((Rect)(ref rect)).height) * 0.5f);
			float num2 = _pageZoom[page];
			_pagePan[page] = val3 - val2 * num2;
			ApplyPageTransform(page);
		}
	}

	private void RebuildEdgeGeometry()
	{
		//IL_00ad: 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)
		if ((Object)(object)_edgeGraphic == (Object)null || _edges == null)
		{
			return;
		}
		List<EdgeView> list = new List<EdgeView>(_edges);
		List<EdgeView> list2 = new List<EdgeView>(list.Count);
		_edgeGraphic.ClearSegments();
		for (int i = 0; i < list.Count; i++)
		{
			EdgeView edgeView = list[i];
			if (_nodes.TryGetValue(edgeView.FromId, out var value) && _nodes.TryGetValue(edgeView.ToId, out var value2) && value != null && value2 != null && !((Object)(object)value.Root == (Object)null) && !((Object)(object)value2.Root == (Object)null))
			{
				EdgeView item = CreateEdge(edgeView.FromId, edgeView.ToId, value.Root.anchoredPosition, value2.Root.anchoredPosition, edgeView.Implicit, edgeView.Inferred);
				list2.Add(item);
			}
		}
		_edges.Clear();
		_edges.AddRange(list2);
		((Graphic)_edgeGraphic).SetVerticesDirty();
	}

	private bool NodePassesFilters(TechProto proto)
	{
		if (proto == null)
		{
			return false;
		}
		if (!PassesMatrixFilter(proto))
		{
			return false;
		}
		if (_builtPage == 1 && _infiniteOnly && !IsInfiniteUpgrade(proto))
		{
			return false;
		}
		if (_combatFilter == 0 || !IsCombatProto(proto))
		{
			return true;
		}
		if (_combatFilter == 2)
		{
			return false;
		}
		EnsureUtilityCombatTechIds();
		return _utilityCombatTechIds.Contains(((Proto)proto).ID);
	}

	private bool PassesMatrixFilter(TechProto proto)
	{
		if (_matrixFilter < 0)
		{
			return true;
		}
		int effectiveMatrixTier = GetEffectiveMatrixTier(((Proto)proto).ID, new HashSet<int>());
		if (_matrixFilter <= 4)
		{
			return effectiveMatrixTier <= _matrixFilter;
		}
		return effectiveMatrixTier == 5;
	}

	private static bool IsInfiniteUpgrade(TechProto proto)
	{
		if (proto == null || ((Proto)proto).ID <= 1999)
		{
			return false;
		}
		return proto.MaxLevel > 20;
	}

	private bool IsCombatProto(TechProto proto)
	{
		if (proto == null)
		{
			return false;
		}
		if (((Proto)proto).ID < 2000)
		{
			if (((Proto)proto).ID >= 1800)
			{
				return ((Proto)proto).ID < 1900;
			}
			return false;
		}
		if (proto.UnlockFunctions == null)
		{
			return false;
		}
		bool flag = false;
		bool flag2 = false;
		for (int i = 0; i < proto.UnlockFunctions.Length; i++)
		{
			int num = proto.UnlockFunctions[i];
			if (num >= 61 && num <= 86)
			{
				flag = true;
			}
			else if (num >= 1 && num <= 44)
			{
				flag2 = true;
			}
		}
		if (flag)
		{
			return !flag2;
		}
		return false;
	}

	private void EnsureUtilityCombatTechIds()
	{
		if (_utilityCombatTechIdsBuilt)
		{
			return;
		}
		_utilityCombatTechIdsBuilt = true;
		_utilityCombatTechIds.Clear();
		TechProto[] dataArray = ((ProtoSet<TechProto>)(object)LDB.techs).dataArray;
		if (dataArray == null)
		{
			return;
		}
		foreach (TechProto val in dataArray)
		{
			if (val != null && ((Proto)val).ID >= 1800 && ((Proto)val).ID < 1900 && UnlocksBattleBase(val))
			{
				CollectCombatAncestors(((Proto)val).ID, _utilityCombatTechIds);
			}
		}
	}

	private bool UnlocksBattleBase(TechProto proto)
	{
		if (proto == null || proto.unlockRecipeArray == null)
		{
			return false;
		}
		for (int i = 0; i < proto.unlockRecipeArray.Length; i++)
		{
			RecipeProto val = proto.unlockRecipeArray[i];
			if (val == null || val.Results == null)
			{
				continue;
			}
			for (int j = 0; j < val.Results.Length; j++)
			{
				ItemProto val2 = ((ProtoSet<ItemProto>)(object)LDB.items).Select(val.Results[j]);
				if (val2 != null && val2.prefabDesc != null && val2.prefabDesc.isBattleBase)
				{
					return true;
				}
			}
		}
		return false;
	}

	private void CollectCombatAncestors(int techId, HashSet<int> result)
	{
		if (result.Add(techId))
		{
			TechProto val = ((ProtoSet<TechProto>)(object)LDB.techs).Select(techId);
			if (val != null)
			{
				CollectCombatAncestorArray(val.PreTechs, result);
				CollectCombatAncestorArray(val.PreTechsImplicit, result);
			}
		}
	}

	private void CollectCombatAncestorArray(int[] ids, HashSet<int> result)
	{
		if (ids == null)
		{
			return;
		}
		for (int i = 0; i < ids.Length; i++)
		{
			TechProto val = ((ProtoSet<TechProto>)(object)LDB.techs).Select(ids[i]);
			if (val != null && IsCombatProto(val))
			{
				CollectCombatAncestors(((Proto)val).ID, result);
			}
		}
	}

	private void ClearSearch()
	{
		if ((Object)(object)_searchInput != (Object)null)
		{
			_searchInput.text = "";
			return;
		}
		_searchText = "";
		RefreshSearchStatus();
		RefreshNodeStates();
	}

	private void OnSearchChanged(string value)
	{
		_searchText = (string.IsNullOrEmpty(value) ? "" : value.Trim());
		RefreshSearchStatus();
		RefreshNodeStates();
	}

	private void RefreshSearchStatus()
	{
		if ((Object)(object)_searchStatus == (Object)null)
		{
			return;
		}
		if (string.IsNullOrEmpty(_searchText))
		{
			_searchStatus.text = "";
			return;
		}
		int num = 0;
		foreach (NodeView value in _nodes.Values)
		{
			if (value != null && NodePassesFilters(value.Proto) && NodeMatchesSearch(value))
			{
				num++;
			}
		}
		_searchStatus.text = ((num == 1) ? "1 match" : (num + " matches"));
	}

	private bool NodeMatchesSearch(NodeView node)
	{
		if (node == null || node.Proto == null)
		{
			return false;
		}
		if (string.IsNullOrEmpty(_searchText))
		{
			return true;
		}
		TechProto proto = node.Proto;
		if (ContainsSearch(((Proto)proto).name))
		{
			return true;
		}
		if (proto.unlockRecipeArray != null)
		{
			for (int i = 0; i < proto.unlockRecipeArray.Length; i++)
			{
				RecipeProto val = proto.unlockRecipeArray[i];
				if (val == null)
				{
					continue;
				}
				if (ContainsSearch(((Proto)val).name))
				{
					return true;
				}
				if (val.Results == null)
				{
					continue;
				}
				for (int j = 0; j < val.Results.Length; j++)
				{
					ItemProto val2 = ((ProtoSet<ItemProto>)(object)LDB.items).Select(val.Results[j]);
					if (val2 != null && ContainsSearch(((Proto)val2).name))
					{
						return true;
					}
				}
			}
		}
		return false;
	}

	private bool ContainsSearch(string value)
	{
		if (!string.IsNullOrEmpty(value))
		{
			return value.IndexOf(_searchText, StringComparison.OrdinalIgnoreCase) >= 0;
		}
		return false;
	}

	private void CreateDetailPanel()
	{
		//IL_002e: 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_0062: 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_00a7: 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_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: 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_01af: 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_01d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_021f: 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_0253: Unknown result type (might be due to invalid IL or missing references)
		//IL_0265: Unknown result type (might be due to invalid IL or missing references)
		//IL_0279: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_030d: Unknown result type (might be due to invalid IL or missing references)
		//IL_035a: 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_0384: 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_03ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_040e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0415: Unknown result type (might be due to invalid IL or missing references)
		//IL_0427: Unknown result type (might be due to invalid IL or missing references)
		//IL_043c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0450: Unknown result type (might be due to invalid IL or missing references)
		//IL_047c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0497: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c1: 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_04ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_0509: Unknown result type (might be due to invalid IL or missing references)
		//IL_0551: Unknown result type (might be due to invalid IL or missing references)
		//IL_0558: Unknown result type (might be due to invalid IL or missing references)
		//IL_056a: Unknown result type (might be due to invalid IL or missing references)
		//IL_057f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0593: Unknown result type (might be due to invalid IL or missing references)
		//IL_05b7: 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_061d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0634: 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)
		//IL_0668: Unknown result type (might be due to invalid IL or missing references)
		//IL_06aa: 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_06c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_06d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_06ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_0710: Unknown result type (might be due to invalid IL or missing references)
		//IL_076f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0776: Unknown result type (might be due to invalid IL or missing references)
		//IL_078d: Unknown result type (might be due to invalid IL or missing references)
		//IL_07a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_07c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0801: Unknown result type (might be due to invalid IL or missing references)
		//IL_0808: Unknown result type (might be due to invalid IL or missing references)
		//IL_081a: Unknown result type (might be due to invalid IL or missing references)
		//IL_082f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0844: Unknown result type (might be due to invalid IL or missing references)
		//IL_0876: Unknown result type (might be due to invalid IL or missing references)
		//IL_087d: Unknown result type (might be due to invalid IL or missing references)
		//IL_088f: Unknown result type (might be due to invalid IL or missing references)
		//IL_08a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_08ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_08d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0906: Unknown result type (might be due to invalid IL or missing references)
		//IL_091b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0930: Unknown result type (might be due to invalid IL or missing references)
		//IL_0945: Unknown result type (might be due to invalid IL or missing references)
		//IL_095a: Unknown result type (might be due to invalid IL or missing references)
		//IL_097e: Unknown result type (might be due to invalid IL or missing references)
		//IL_09ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_09c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_09d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_09e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_09ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a1e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a67: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a6e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a80: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a95: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a9f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ac3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b00: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b07: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b19: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b2e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b38: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b5c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ba2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bb7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bcc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0be0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c60: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c76: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c8c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ca2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0cb8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ce1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0d17: Unknown result type (might be due to invalid IL or missing references)
		//IL_0d21: Expected O, but got Unknown
		//IL_0d9e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0dbd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0df1: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = CreateUIObject("Details", (Transform)(object)_root);
		_detailPanel = val.GetComponent<RectTransform>();
		_detailPanel.anchorMin = new Vector2(1f, 1f);
		_detailPanel.anchorMax = new Vector2(1f, 1f);
		_detailPanel.pivot = new Vector2(1f, 1f);
		_detailPanel.sizeDelta = new Vector2(500f, 540f);
		UpdateDetailPanelPosition();
		Image obj = val.AddComponent<Image>();
		((Graphic)obj).color = new Color(0.025f, 0.033f, 0.045f, 0.985f);
		((Graphic)obj).raycastTarget = true;
		_detailAccent = CreateImage("Accent", (Transform)(object)_detailPanel, new Vector2(0f, 4f));
		RectTransform rectTransform = ((Graphic)_detailAccent).rectTransform;
		rectTransform.anchorMin = new Vector2(0f, 1f);
		rectTransform.anchorMax = new Vector2(1f, 1f);
		rectTransform.pivot = new Vector2(0.5f, 1f);
		rectTransform.offsetMin = new Vector2(0f, -4f);
		rectTransform.offsetMax = Vector2.zero;
		((Graphic)_detailAccent).color = SelectedColor;
		((Graphic)_detailAccent).raycastTarget = false;
		GameObject obj2 = CreateUIObject("Header", (Transform)(object)_detailPanel);
		RectTransform component = obj2.GetComponent<RectTransform>();
		component.anchorMin = new Vector2(0f, 1f);
		component.anchorMax = new Vector2(1f, 1f);
		component.pivot = new Vector2(0.5f, 1f);
		component.offsetMin = new Vector2(0f, -94f);
		component.offsetMax = new Vector2(0f, -4f);
		Image obj3 = obj2.AddComponent<Image>();
		((Graphic)obj3).color = new Color(0.045f, 0.058f, 0.075f, 0.96f);
		((Graphic)obj3).raycastTarget = false;
		_detailIcon = CreateImage("Icon", (Transform)(object)component, new Vector2(66f, 66f));
		RectTransform rectTransform2 = ((Graphic)_detailIcon).rectTransform;
		Vector2 val2 = default(Vector2);
		((Vector2)(ref val2))..ctor(0f, 1f);
		rectTransform2.anchorMax = val2;
		rectTransform2.anchorMin = val2;
		rectTransform2.pivot = new Vector2(0f, 1f);
		rectTransform2.anchoredPosition = new Vector2(18f, -13f);
		_detailIcon.preserveAspect = true;
		_detailTitle = CreateText("Title", (Transform)(object)component, 20, (TextAnchor)0);
		RectTransform rectTransform3 = ((Graphic)_detailTitle).rectTransform;
		rectTransform3.anchorMin = new Vector2(0f, 1f);
		rectTransform3.anchorMax = new Vector2(1f, 1f);
		rectTransform3.pivot = new Vector2(0f, 1f);
		rectTransform3.offsetMin = new Vector2(100f, -43f);
		rectTransform3.offsetMax = new Vector2(-18f, -12f);
		_detailTitle.fontStyle = (FontStyle)1;
		_detailTitle.horizontalOverflow = (HorizontalWrapMode)0;
		_detailLevel = CreateText("Level", (Transform)(object)component, 13, (TextAnchor)0);
		RectTransform rectTransform4 = ((Graphic)_detailLevel).rectTransform;
		rectTransform4.anchorMin = new Vector2(0f, 1f);
		rectTransform4.anchorMax = new Vector2(1f, 1f);
		rectTransform4.pivot = new Vector2(0f, 1f);
		rectTransform4.offsetMin = new Vector2(100f, -73f);
		rectTransform4.offsetMax = new Vector2(-145f, -49f);
		((Graphic)_detailLevel).color = new Color(0.72f, 0.82f, 0.93f, 1f);
		_detailStatus = CreateText("Status", (Transform)(object)component, 12, (TextAnchor)4);
		RectTransform rectTransform5 = ((Graphic)_detailStatus).rectTransform;
		((Vector2)(ref val2))..ctor(1f, 1f);
		rectTransform5.anchorMax = val2;
		rectTransform5.anchorMin = val2;
		rectTransform5.pivot = new Vector2(1f, 1f);
		rectTransform5.sizeDelta = new Vector2(128f, 25f);
		rectTransform5.anchoredPosition = new Vector2(-16f, -55f);
		_detailStatus.fontStyle = (FontStyle)1;
		Image obj4 = CreateImage("HeaderSeparator", (Transform)(object)_detailPanel, new Vector2(0f, 1f));
		RectTransform rectTransform6 = ((Graphic)obj4).rectTransform;
		rectTransform6.anchorMin = new Vector2(0f, 1f);
		rectTransform6.anchorMax = new Vector2(1f, 1f);
		rectTransform6.pivot = new Vector2(0.5f, 1f);
		rectTransform6.offsetMin = new Vector2(16f, -96f);
		rectTransform6.offsetMax = new Vector2(-16f, -95f);
		((Graphic)obj4).color = new Color(0.35f, 0.43f, 0.52f, 0.4f);
		((Graphic)obj4).raycastTarget = false;
		_unlockHeading = CreateText("UnlockHeading", (Transform)(object)_detailPanel, 12, (TextAnchor)0);
		RectTransform rectTransform7 = ((Graphic)_unlockHeading).rectTransform;
		((Vector2)(ref val2))..ctor(0f, 1f);
		rectTransform7.anchorMax = val2;
		rectTransform7.anchorMin = val2;
		rectTransform7.pivot = new Vector2(0f, 1f);
		rectTransform7.sizeDelta = new Vector2(185f, 20f);
		rectTransform7.anchoredPosition = new Vector2(18f, -106f);
		((Graphic)_unlockHeading).color = new Color(0.95f, 0.65f, 0.35f, 1f);
		_unlockHeading.fontStyle = (FontStyle)1;
		_unlockHeading.text = "UNLOCKS";
		_unlockRow = CreateUIObject("UnlockRow", (Transform)(object)_detailPanel).GetComponent<RectTransform>();
		RectTransform unlockRow = _unlockRow;
		RectTransform unlockRow2 = _unlockRow;
		((Vector2)(ref val2))..ctor(0f, 1f);
		unlockRow2.anchorMax = val2;
		unlockRow.anchorMin = val2;
		_unlockRow.pivot = new Vector2(0f, 1f);
		_unlockRow.sizeDelta = new Vector2(185f, 56f);
		_unlockRow.anchoredPosition = new Vector2(18f, -128f);
		_researchCostHeading = CreateText("ResearchCostHeading", (Transform)(object)_detailPanel, 12, (TextAnchor)0);
		RectTransform rectTransform8 = ((Graphic)_researchCostHeading).rectTransform;
		((Vector2)(ref val2))..ctor(0f, 1f);
		rectTransform8.anchorMax = val2;
		rectTransform8.anchorMin = val2;
		rectTransform8.pivot = new Vector2(0f, 1f);
		rectTransform8.sizeDelta = new Vector2(294f, 20f);
		rectTransform8.anchoredPosition = new Vector2(190f, -106f);
		((Graphic)_researchCostHeading).color = new Color(0.95f, 0.65f, 0.35f, 1f);
		_researchCostHeading.fontStyle = (FontStyle)1;
		_researchCostHeading.text = "RESEARCH CONSUMPTION";
		_researchCostRow = CreateUIObject("ResearchCostRow", (Transform)(object)_detailPanel).GetComponent<RectTransform>();
		RectTransform researchCostRow = _researchCostRow;
		RectTransform researchCostRow2 = _researchCostRow;
		((Vector2)(ref val2))..ctor(0f, 1f);
		researchCostRow2.anchorMax = val2;
		researchCostRow.anchorMin = val2;
		_researchCostRow.pivot = new Vector2(0f, 1f);
		_researchCostRow.sizeDelta = new Vector2(294f, 56f);
		_researchCostRow.anchoredPosition = new Vector2(190f, -128f);
		_detailProgressGroup = CreateUIObject("ResearchProgress", (Transform)(object)_detailPanel);
		RectTransform component2 = _detailProgressGroup.GetComponent<RectTransform>();
		((Vector2)(ref val2))..ctor(0f, 1f);
		component2.anchorMax = val2;
		component2.anchorMin = val2;
		component2.pivot = new Vector2(0f, 1f);
		component2.sizeDelta = new Vector2(464f, 58f);
		component2.anchoredPosition = new Vector2(18f, -192f);
		Text obj5 = CreateText("Heading", (Transform)(object)component2, 12, (TextAnchor)0);
		RectTransform rectTransform9 = ((Graphic)obj5).rectTransform;
		((Vector2)(ref val2))..ctor(0f, 1f);
		rectTransform9.anchorMax = val2;
		rectTransform9.anchorMin = val2;
		rectTransform9.pivot = new Vector2(0f, 1f);
		rectTransform9.sizeDelta = new Vector2(160f, 18f);
		rectTransform9.anchoredPosition = Vector2.zero;
		obj5.fontStyle = (FontStyle)1;
		((Graphic)obj5).color = new Color(0.95f, 0.65f, 0.35f, 1f);
		obj5.text = "RESEARCH PROGRESS";
		GameObject obj6 = CreateUIObject("BarBackground", (Transform)(object)component2);
		RectTransform component3 = obj6.GetComponent<RectTransform>();
		component3.anchorMin = new Vector2(0f, 1f);
		component3.anchorMax = new Vector2(1f, 1f);
		component3.pivot = new Vector2(0.5f, 1f);
		component3.offsetMin = new Vector2(0f, -31f);
		component3.offsetMax = new Vector2(0f, -22f);
		Image obj7 = obj6.AddComponent<Image>();
		((Graphic)obj7).color = new Color(0.06f, 0.09f, 0.11f, 1f);
		((Graphic)obj7).raycastTarget = false;
		GameObject val3 = CreateUIObject("Fill", (Transform)(object)component3);
		RectTransform component4 = val3.GetComponent<RectTransform>();
		component4.anchorMin = new Vector2(0f, 0f);
		component4.anchorMax = new Vector2(0f, 1f);
		component4.pivot = new Vector2(0f, 0.5f);
		component4.offsetMin = Vector2.zero;
		component4.offsetMax = Vector2.zero;
		_detailProgressFill = val3.AddComponent<Image>();
		((Graphic)_detailProgressFill).color = new Color(1f, 0.63f, 0.26f, 1f);
		((Graphic)_detailProgressFill).raycastTarget = false;
		_detailProgressSpeedText = CreateText("Speed", (Transform)(object)component2, 12, (TextAnchor)6);
		RectTransform rectTransform10 = ((Graphic)_detailProgressSpeedText).rectTransform;
		((Vector2)(ref val2))..ctor(0f, 0f);
		rectTransform10.anchorMax = val2;
		rectTransform10.anchorMin = val2;
		rectTransform10.pivot = new Vector2(0f, 0f);
		rectTransform10.sizeDelta = new Vector2(290f, 20f);
		rectTransform10.anchoredPosition = Vector2.zero;
		((Graphic)_detailProgressSpeedText).color = new Color(0.86f, 0.91f, 0.96f, 1f);
		_detailProgressText = CreateText("Hashes", (Transform)(object)component2, 12, (TextAnchor)8);
		RectTransform rectTransform11 = ((Graphic)_detailProgressText).rectTransform;
		((Vector2)(ref val2))..ctor(1f, 0f);
		rectTransform11.anchorMax = val2;
		rectTransform11.anchorMin = val2;
		rectTransform11.pivot = new Vector2(1f, 0f);
		rectTransform11.sizeDelta = new Vector2(180f, 20f);
		rectTransform11.anchoredPosition = Vector2.zero;
		((Graphic)_detailProgressText).color = new Color(1f, 0.63f, 0.26f, 1f);
		_detailProgressGroup.SetActive(false);
		_detailBody = CreateText("Body", (Transform)(object)_detailPanel, 14, (TextAnchor)0);
		RectTransform rectTransform12 = ((Graphic)_detailBody).rectTransform;
		rectTransform12.anchorMin = new Vector2(0f, 0f);
		rectTransform12.anchorMax = new Vector2(1f, 1f);
		rectTransform12.offsetMin = new Vector2(18f, 66f);
		rectTransform12.offsetMax = new Vector2(-18f, -258f);
		_detailBody.horizontalOverflow = (HorizontalWrapMode)0;
		_detailBody.verticalOverflow = (VerticalWrapMode)0;
		_detailBody.lineSpacing = 1f;
		_detailBody.resizeTextForBestFit = true;
		_detailBody.resizeTextMinSize = 11;
		_detailBody.resizeTextMaxSize = 14;
		GameObject val4 = CreateUIObject("ResearchButton", (Transform)(object)_detailPanel);
		RectTransform component5 = val4.GetComponent<RectTransform>();
		component5.anchorMin = new Vector2(0f, 0f);
		component5.anchorMax = new Vector2(1f, 0f);
		component5.pivot = new Vector2(0.5f, 0f);
		component5.offsetMin = new Vector2(18f, 14f);
		component5.offsetMax = new Vector2(-18f, 54f);
		Image val5 = val4.AddComponent<Image>();
		((Graphic)val5).color = new Color(0.12f, 0.38f, 0.56f, 1f);
		_researchButton = val4.AddComponent<Button>();
		((Selectable)_researchButton).targetGraphic = (Graphic)(object)val5;
		((UnityEvent)_researchButton.onClick).AddListener(new UnityAction(OnResearchButtonClick));
		_researchButtonText = CreateText("Text", (Transform)(object)component5, 15, (TextAnchor)4);
		Stretch(((Graphic)_researchButtonText).rectTransform);
		_researchButtonText.fontStyle = (FontStyle)1;
		((Graphic)_researchButtonText).raycastTarget = false;
		_detailEmptyPrompt = CreateText("EmptyPrompt", (Transform)(object)_detailPanel, 14, (TextAnchor)4);
		Stretch(((Graphic)_detailEmptyPrompt).rectTransform);
		((Graphic)_detailEmptyPrompt).rectTransform.offsetMin = new Vector2(10f, 5f);
		((Graphic)_detailEmptyPrompt).rectTransform.offsetMax = new Vector2(-10f, -5f);
		_detailEmptyPrompt.text = "Please select a technology";
		((Graphic)_detailEmptyPrompt).color = new Color(0.82f, 0.87f, 0.92f, 1f);
		((Graphic)_detailEmptyPrompt).raycastTarget = false;
		((Component)_detailEmptyPrompt).gameObject.SetActive(false);
	}

	private void CreateLegend()
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: 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)
		_legend = CreateText("Legend", (Transform)(object)_root, 13, (TextAnchor)0);
		RectTransform rectTransform = ((Graphic)_legend).rectTransform;
		rectTransform.anchorMin = new Vector2(0f, 0f);
		rectTransform.anchorMax = new Vector2(0f, 0f);
		rectTransform.pivot = new Vector2(0f, 0f);
		rectTransform.sizeDelta = new Vector2(1160f, 28f);
		rectTransform.anchoredPosition = new Vector2(152f, 10f);
		_legend.text = "Blue = complete   Green = researchable   Orange = prerequisite locked   •   Q+ = add this tech to the research queue   •   Search = highlight names   •   Wheel = zoom   •   Drag = pan";
		((Graphic)_legend).color = new Color(0.76f, 0.82f, 0.89f, 1f);
	}

	private void BuildGraph(int page)
	{
		//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_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_017e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0183: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b5: 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_021a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0250: Unknown result type (might be due to invalid IL or missing references)
		//IL_0322: 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_02bb: 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_02d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
		_nodes.Clear();
		_edges.Clear();
		_backboneEdges.Clear();
		if ((Object)(object)_edgeGraphic != (Object)null)
		{
			_edgeGraphic.ClearSegments();
		}
		_inferredParents.Clear();
		List<TechProto> list = new List<TechProto>();
		Dictionary<int, Vector2> dictionary = new Dictionary<int, Vector2>();
		float num = float.MaxValue;
		float num2 = float.MinValue;
		float num3 = float.MaxValue;
		float num4 = float.MinValue;
		TechProto[] dataArray = ((ProtoSet<TechProto>)(object)LDB.techs).dataArray;
		foreach (TechProto val in dataArray)
		{
			if (IsVisibleProto(val, page))
			{
				Vector2 squeezedPos = _tree.GetSqueezedPos(val.Position);
				list.Add(val);
				dictionary[((Proto)val).ID] = squeezedPos;
				num = Mathf.Min(num, squeezedPos.x);
				num2 = Mathf.Max(num2, squeezedPos.x);
				num3 = Mathf.Min(num3, squeezedPos.y);
				num4 = Mathf.Max(num4, squeezedPos.y);
			}
		}
		if (list.Count == 0)
		{
			_baseGraphSize = new Vector2(800f, 600f);
			_pageGraphSize[page] = _baseGraphSize;
			_graphCanvas.sizeDelta = _baseGraphSize;
			if (!_pageViewInitialized[page])
			{
				InitializePageView(page);
			}
			else
			{
				ApplyPageTransform(page);
			}
			return;
		}
		Dictionary<int, Vector2> dictionary2 = new Dictionary<int, Vector2>();
		Vector2 value = default(Vector2);
		for (int j = 0; j < list.Count; j++)
		{
			TechProto val2 = list[j];
			Vector2 val3 = dictionary[((Proto)val2).ID];
			((Vector2)(ref value))..ctor(val3.x - num + 100f, 0f - (num4 - val3.y + 100f));
			dictionary2[((Proto)val2).ID] = value;
		}
		float num5 = Mathf.Max(1100f, num2 - num + 200f + 104f);
		float num6 = Mathf.Max(720f, num4 - num3 + 200f + 104f);
		_baseGraphSize = new Vector2(num5, num6);
		_graphCanvas.sizeDelta = _baseGraphSize;
		if (page == 0)
		{
			BuildMainResearchBackbone(list);
		}
		BuildInferredResearchPrerequisites(list);
		for (int k = 0; k < list.Count; k++)
		{
			TechProto val4 = list[k];
			CreateNode(val4, dictionary2[((Proto)val4).ID]);
		}
		if ((Object)(object)_edgeGraphic == (Object)null)
		{
			GameObject val5 = CreateUIObject("EdgeLayer", (Transform)(object)_graphCanvas);
			val5.transform.SetAsFirstSibling();
			RectTransform component = val5.GetComponent<RectTransform>();
			Vector2 val6 = default(Vector2);
			((Vector2)(ref val6))..ctor(0f, 1f);
			component.anchorMax = val6;
			component.anchorMin = val6;
			component.pivot = new Vector2(0f, 1f);
			component.anchoredPosition = Vector2.zero;
			component.sizeDelta = _baseGraphSize;
			_edgeGraphic = val5.AddComponent<TechTreeEdgeGraphic>();
			((Graphic)_edgeGraphic).raycastTarget = false;
			_pageEdgeGraphics[page] = _edgeGraphic;
		}
		else
		{
			((Graphic)_edgeGraphic).rectTransform.sizeDelta = _baseGraphSize;
			((Component)_edgeGraphic).transform.SetAsFirstSibling();
		}
		for (int l = 0; l < list.Count; l++)
		{
			TechProto val7 = list[l];
			AddEdges(val7, val7.PreTechs, implicitEdge: false, dictionary2);
			AddEdges(val7, val7.PreTechsImplicit, implicitEdge: true, dictionary2);
			if (_inferredParents.TryGetValue(((Proto)val7).ID, out var value2) && value2 != null)
			{
				AddInferredEdges(val7, value2, dictionary2);
			}
		}
		_pageGraphSize[page] = _baseGraphSize;
		if (!_pageViewInitial