Decompiled source of Personify v1.0.0

Personify.dll

Decompiled 18 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using DooDesch.UI;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne.AvatarFramework;
using Il2CppScheduleOne.UI.MainMenu;
using Il2CppSystem.Collections.Generic;
using MelonLoader;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Personify;
using Personify.Editor;
using Personify.Editor.Widgets;
using S1API.Entities.Appearances.AccessoryFields;
using S1API.Entities.Appearances.BodyLayerFields;
using S1API.Entities.Appearances.CustomizationFields;
using S1API.Entities.Appearances.FaceLayerFields;
using S1API.Rendering;
using S1API.UI;
using SideHustle;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Core), "Personify", "1.0.0", "DooDesch", "https://github.com/DooDesch-Mods/ScheduleOne-Personify")]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: MelonOptionalDependencies(new string[] { "SideHustle" })]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Personify")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ee327a0afb36e6426dd5b66f26c80b8c034d4df1")]
[assembly: AssemblyProduct("Personify")]
[assembly: AssemblyTitle("Personify")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Personify
{
	public sealed class Core : MelonMod
	{
		public static Core Instance { get; private set; }

		public static Instance Log { get; private set; }

		public override void OnInitializeMelon()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			Instance = this;
			Log = ((MelonBase)this).LoggerInstance;
			try
			{
				API.Register(new GamemodeDescriptor
				{
					Id = "doodesch.personify",
					DisplayName = "Personify",
					Description = "Design and export custom NPC packs.",
					Author = "DooDesch",
					Support = (GamemodeSupport)0,
					Surface = (GamemodeSurface)0,
					OnLaunchSingleplayer = OnLaunch,
					OnExitToHub = OnExit
				});
				Log.Msg("Personify " + ((MelonBase)this).Info.Version + " registered with Side Hustle.");
			}
			catch (Exception ex)
			{
				Log.Warning("Side Hustle not available, Personify cannot register: " + ex.Message);
			}
		}

		private static void OnLaunch(LaunchContext ctx)
		{
			EditorUI.Open(ctx);
		}

		private static void OnExit(LaunchContext ctx)
		{
			EditorUI.Close();
		}

		public override void OnSceneWasUnloaded(int buildIndex, string sceneName)
		{
			if (sceneName == "Menu")
			{
				EditorUI.Close();
				Preview.Forget();
			}
		}

		public override void OnUpdate()
		{
			if (EditorUI.IsOpen)
			{
				EditorUI.Tick();
			}
		}
	}
}
namespace Personify.Editor
{
	public static class BackroomsPreset
	{
		public static readonly string[] Archetypes = new string[7] { "faceling", "wanderer_hollow", "smiler", "partygoer", "mimic_regular", "husk", "brute" };

		public static readonly string[] Biomes = new string[7] { "L0", "L1", "L2", "L3", "L4", "L6", "Lm2" };
	}
	public static class EditorUI
	{
		private enum FormMode
		{
			Basic,
			Advanced
		}

		private static LaunchContext _ctx;

		private static GameObject _canvasGO;

		private static GameObject _screen;

		private static NpcProject _project;

		private static NpcDraft _selected;

		private static Transform _railList;

		private static RectTransform _formContent;

		private static Text _titleText;

		private static bool _previewDirty;

		private static float _lastEdit;

		private const float RailW = 300f;

		private const float PanelW = 400f;

		private const float Gutter = 16f;

		private static FormMode _mode = FormMode.Basic;

		private static readonly Dictionary<string, bool> _modInstalled = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);

		private const float SliderLabelW = 84f;

		private const float SliderValueW = 38f;

		public static bool IsOpen => (Object)(object)_canvasGO != (Object)null;

		public static void Open(LaunchContext ctx)
		{
			_ctx = ctx;
			if ((Object)(object)_canvasGO == (Object)null)
			{
				BuildCanvas();
			}
			Preview.EnsureAvatar();
			ShowProjectSelect();
		}

		public static void Close()
		{
			try
			{
				Preview.ExitEditor();
			}
			catch
			{
			}
			try
			{
				Toast.Clear();
			}
			catch
			{
			}
			if ((Object)(object)_canvasGO != (Object)null)
			{
				Object.Destroy((Object)(object)_canvasGO);
				_canvasGO = null;
			}
			_screen = null;
			_project = null;
			_selected = null;
			_railList = null;
			_formContent = null;
			_titleText = null;
			_previewDirty = false;
		}

		public static void Tick()
		{
			try
			{
				Toast.Tick();
			}
			catch
			{
			}
			if (_previewDirty && Time.time - _lastEdit > 0.12f)
			{
				_previewDirty = false;
				if (_project != null && _selected != null)
				{
					Preview.Apply(_project, _selected);
				}
			}
		}

		private static void BuildCanvas()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			_canvasGO = new GameObject("Personify_EditorCanvas");
			Object.DontDestroyOnLoad((Object)(object)_canvasGO);
			Canvas obj = _canvasGO.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = 30000;
			_canvasGO.AddComponent<GraphicRaycaster>();
			Toast.Init(_canvasGO.transform);
		}

		private static void ClearScreen()
		{
			if ((Object)(object)_screen != (Object)null)
			{
				Object.Destroy((Object)(object)_screen);
				_screen = null;
			}
		}

		private static void MarkDirty()
		{
			_previewDirty = true;
			_lastEdit = Time.time;
		}

		private static void ShowProjectSelect()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: 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_0107: 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_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: 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_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: 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_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_0395: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_0429: Unknown result type (might be due to invalid IL or missing references)
			//IL_043d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0482: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_050b: Unknown result type (might be due to invalid IL or missing references)
			//IL_053b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0550: Unknown result type (might be due to invalid IL or missing references)
			//IL_0565: Unknown result type (might be due to invalid IL or missing references)
			//IL_057a: Unknown result type (might be due to invalid IL or missing references)
			//IL_058e: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ca: Unknown result type (might be due to invalid IL or missing references)
			ClearScreen();
			_screen = UIFactory.Panel("ProjectSelect", _canvasGO.transform, Theme.BgBase, (Vector2?)null, (Vector2?)null, true);
			float num = Mathf.Min(720f, (float)Screen.height * 0.84f);
			GameObject val = UIFactory.Panel("Card", _screen.transform, Theme.BgPanel, (Vector2?)null, (Vector2?)null, false);
			Image component = val.GetComponent<Image>();
			if ((Object)(object)component != (Object)null)
			{
				component.sprite = Theme.RoundedSprite();
				component.type = (Type)1;
			}
			RectTransform component2 = val.GetComponent<RectTransform>();
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.5f, 0.5f);
			component2.anchorMax = val2;
			component2.anchorMin = val2;
			component2.pivot = new Vector2(0.5f, 0.5f);
			component2.sizeDelta = new Vector2(640f, num);
			Outline obj = val.AddComponent<Outline>();
			((Shadow)obj).effectColor = Theme.HairlineStrong;
			((Shadow)obj).effectDistance = new Vector2(1f, -1f);
			Text obj2 = UIFactory.Text("Title", "Personify", val.transform, 28, (TextAnchor)1, (FontStyle)1);
			((Graphic)obj2).color = Theme.TextPrimary;
			((Graphic)obj2).raycastTarget = false;
			RectTransform rectTransform = ((Graphic)obj2).rectTransform;
			rectTransform.anchorMin = new Vector2(0f, 1f);
			rectTransform.anchorMax = new Vector2(1f, 1f);
			rectTransform.pivot = new Vector2(0.5f, 1f);
			rectTransform.offsetMin = new Vector2(16f, -70f);
			rectTransform.offsetMax = new Vector2(-16f, -26f);
			Text obj3 = UIFactory.Text("Sub", "Design and export custom NPC packs.", val.transform, 14, (TextAnchor)1, (FontStyle)0);
			((Graphic)obj3).color = Theme.TextMuted;
			((Graphic)obj3).raycastTarget = false;
			RectTransform rectTransform2 = ((Graphic)obj3).rectTransform;
			rectTransform2.anchorMin = new Vector2(0f, 1f);
			rectTransform2.anchorMax = new Vector2(1f, 1f);
			rectTransform2.pivot = new Vector2(0.5f, 1f);
			rectTransform2.offsetMin = new Vector2(16f, -98f);
			rectTransform2.offsetMax = new Vector2(-16f, -74f);
			ValueTuple<GameObject, Button, Text> valueTuple = UIFactory.ButtonWithLabel("New", "New pack", val.transform, Theme.Accent, 210f, 48f);
			GameObject item = valueTuple.Item1;
			Button item2 = valueTuple.Item2;
			RectTransform component3 = item.GetComponent<RectTransform>();
			((Vector2)(ref val2))..ctor(0.5f, 1f);
			component3.anchorMax = val2;
			component3.anchorMin = val2;
			component3.pivot = new Vector2(0.5f, 1f);
			component3.anchoredPosition = new Vector2(0f, -116f);
			component3.sizeDelta = new Vector2(210f, 48f);
			((UnityEvent)item2.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				CreateProjectFlow();
			}));
			ValueTuple<GameObject, Button, Text> valueTuple2 = UIFactory.ButtonWithLabel("Exit", "Exit to hub", val.transform, Theme.Button, 150f, 36f);
			GameObject item3 = valueTuple2.Item1;
			Button item4 = valueTuple2.Item2;
			RectTransform component4 = item3.GetComponent<RectTransform>();
			((Vector2)(ref val2))..ctor(1f, 1f);
			component4.anchorMax = val2;
			component4.anchorMin = val2;
			component4.pivot = new Vector2(1f, 1f);
			component4.anchoredPosition = new Vector2(-16f, -20f);
			component4.sizeDelta = new Vector2(130f, 36f);
			((UnityEvent)item4.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				ExitToHub();
			}));
			RectTransform component5 = Components.Divider(val.transform).GetComponent<RectTransform>();
			component5.anchorMin = new Vector2(0f, 1f);
			component5.anchorMax = new Vector2(1f, 1f);
			component5.pivot = new Vector2(0.5f, 1f);
			component5.offsetMin = new Vector2(16f, -179f);
			component5.offsetMax = new Vector2(-16f, -178f);
			List<string> list = ProjectStore.List();
			Text obj4 = UIFactory.Text("YP", "Your packs (" + list.Count + ")", val.transform, 15, (TextAnchor)0, (FontStyle)1);
			((Graphic)obj4).color = Theme.TextPrimary;
			((Graphic)obj4).raycastTarget = false;
			RectTransform rectTransform3 = ((Graphic)obj4).rectTransform;
			rectTransform3.anchorMin = new Vector2(0f, 1f);
			rectTransform3.anchorMax = new Vector2(1f, 1f);
			rectTransform3.pivot = new Vector2(0.5f, 1f);
			rectTransform3.offsetMin = new Vector2(16f, -206f);
			rectTransform3.offsetMax = new Vector2(-16f, -186f);
			GameObject obj5 = UIFactory.Panel("List", val.transform, Theme.Clear, (Vector2?)null, (Vector2?)null, false);
			RectTransform component6 = obj5.GetComponent<RectTransform>();
			component6.anchorMin = new Vector2(0f, 0f);
			component6.anchorMax = new Vector2(1f, 1f);
			component6.pivot = new Vector2(0.5f, 1f);
			component6.offsetMin = new Vector2(16f, 20f);
			component6.offsetMax = new Vector2(-16f, -214f);
			ScrollRect val4 = default(ScrollRect);
			RectTransform val3 = Components.ScrollList(obj5.transform, ref val4, 8f);
			if (list.Count == 0)
			{
				Text obj6 = UIFactory.Text("empty", "No packs yet. Click \"New pack\" to start.", (Transform)(object)val3, 13, (TextAnchor)0, (FontStyle)0);
				((Graphic)obj6).color = Theme.TextMuted;
				((Component)obj6).gameObject.AddComponent<LayoutElement>().minHeight = 40f;
			}
			foreach (string item5 in list)
			{
				AddProjectRow((Transform)(object)val3, item5);
			}
			Interactions.PolishButtons(val.transform, true);
		}

		private static void AddProjectRow(Transform content, string folder)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: 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_011b: 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_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: 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_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			string display = ProjectStore.DisplayName(folder);
			int num = ProjectStore.NpcCount(folder);
			GameObject val = UIFactory.Panel("row_" + folder, content, Theme.BgElevated, (Vector2?)null, (Vector2?)null, false);
			Image component = val.GetComponent<Image>();
			if ((Object)(object)component != (Object)null)
			{
				component.sprite = Theme.RoundedSprite();
				component.type = (Type)1;
			}
			val.AddComponent<LayoutElement>().minHeight = 54f;
			Button obj = val.AddComponent<Button>();
			((Selectable)obj).targetGraphic = (Graphic)(object)component;
			((UnityEvent)obj.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				OpenProject(folder);
			}));
			Text obj2 = UIFactory.Text("t", display, val.transform, 14, (TextAnchor)3, (FontStyle)1);
			((Graphic)obj2).color = Theme.TextPrimary;
			((Graphic)obj2).raycastTarget = false;
			RectTransform rectTransform = ((Graphic)obj2).rectTransform;
			rectTransform.anchorMin = new Vector2(0f, 0f);
			rectTransform.anchorMax = new Vector2(1f, 1f);
			rectTransform.offsetMin = new Vector2(14f, 20f);
			rectTransform.offsetMax = new Vector2(-120f, -6f);
			Text obj3 = UIFactory.Text("s", num + " NPC(s)", val.transform, 11, (TextAnchor)6, (FontStyle)0);
			((Graphic)obj3).color = Theme.TextMuted;
			((Graphic)obj3).raycastTarget = false;
			RectTransform rectTransform2 = ((Graphic)obj3).rectTransform;
			rectTransform2.anchorMin = new Vector2(0f, 0f);
			rectTransform2.anchorMax = new Vector2(1f, 1f);
			rectTransform2.offsetMin = new Vector2(14f, 6f);
			rectTransform2.offsetMax = new Vector2(-120f, -28f);
			ValueTuple<GameObject, Button, Text> valueTuple = UIFactory.ButtonWithLabel("del", "Delete", val.transform, Theme.Button, 90f, 32f);
			GameObject item = valueTuple.Item1;
			Button item2 = valueTuple.Item2;
			RectTransform component2 = item.GetComponent<RectTransform>();
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(1f, 0.5f);
			component2.anchorMax = val2;
			component2.anchorMin = val2;
			component2.pivot = new Vector2(1f, 0.5f);
			component2.anchoredPosition = new Vector2(-12f, 0f);
			component2.sizeDelta = new Vector2(90f, 32f);
			((UnityEvent)item2.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				Components.ConfirmDialog(_canvasGO.transform, "Delete pack?", "Permanently delete \"" + display + "\" and all its NPCs?", "Delete", (Action)delegate
				{
					ProjectStore.Delete(folder);
					ShowProjectSelect();
				});
			}));
		}

		private static void CreateProjectFlow()
		{
			Components.PromptDialog(_canvasGO.transform, "New NPC pack", "Give your pack a name.", "My NPC Pack", "Create", (Func<string, string>)delegate(string name)
			{
				if (string.IsNullOrWhiteSpace(name))
				{
					return "Enter a name.";
				}
				if (ProjectStore.Exists(name))
				{
					return "A pack with that name already exists.";
				}
				_project = ProjectStore.Create(name);
				if (_project.Npcs.Count > 0)
				{
					_project.Npcs[0].Appearance = Preview.SeedFromMenu();
				}
				ProjectStore.Save(_project);
				_selected = ((_project.Npcs.Count > 0) ? _project.Npcs[0] : null);
				ShowEditor();
				return (string)null;
			});
		}

		private static void OpenProject(string folder)
		{
			_project = ProjectStore.Load(folder);
			if (_project == null)
			{
				Toast.Show("Failed to open pack.", (Severity)3);
				return;
			}
			_selected = ((_project.Npcs.Count > 0) ? _project.Npcs[0] : null);
			ShowEditor();
		}

		private static void ShowEditor()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			ClearScreen();
			_screen = UIFactory.Panel("Editor", _canvasGO.transform, Theme.Clear, (Vector2?)null, (Vector2?)null, true);
			BuildLeftRail();
			BuildRightPanel();
			BuildBottomBar();
			RefreshRail();
			RefreshForm();
			MarkDirty();
		}

		private static void BuildLeftRail()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_0087: 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_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_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_0332: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = UIFactory.Panel("Rail", _screen.transform, Theme.BgPanel, (Vector2?)null, (Vector2?)null, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 0f);
			component.anchorMax = new Vector2(0f, 1f);
			component.pivot = new Vector2(0f, 0.5f);
			component.sizeDelta = new Vector2(300f, 0f);
			component.anchoredPosition = Vector2.zero;
			_titleText = UIFactory.Text("pack", _project?.Name ?? "Pack", val.transform, 16, (TextAnchor)0, (FontStyle)1);
			((Graphic)_titleText).color = Theme.TextPrimary;
			((Graphic)_titleText).raycastTarget = false;
			RectTransform rectTransform = ((Graphic)_titleText).rectTransform;
			rectTransform.anchorMin = new Vector2(0f, 1f);
			rectTransform.anchorMax = new Vector2(1f, 1f);
			rectTransform.pivot = new Vector2(0.5f, 1f);
			rectTransform.offsetMin = new Vector2(16f, -50f);
			rectTransform.offsetMax = new Vector2(-16f, -18f);
			ValueTuple<GameObject, Button, Text> valueTuple = UIFactory.ButtonWithLabel("add", "+ Add NPC", val.transform, Theme.Accent, 0f, 38f);
			GameObject item = valueTuple.Item1;
			Button item2 = valueTuple.Item2;
			RectTransform component2 = item.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0f, 1f);
			component2.anchorMax = new Vector2(1f, 1f);
			component2.pivot = new Vector2(0.5f, 1f);
			component2.offsetMin = new Vector2(16f, -96f);
			component2.offsetMax = new Vector2(-16f, -58f);
			((UnityEvent)item2.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				AddNpc();
			}));
			GameObject obj = UIFactory.Panel("npcs", val.transform, Theme.Clear, (Vector2?)null, (Vector2?)null, false);
			RectTransform component3 = obj.GetComponent<RectTransform>();
			component3.anchorMin = new Vector2(0f, 0f);
			component3.anchorMax = new Vector2(1f, 1f);
			component3.pivot = new Vector2(0.5f, 1f);
			component3.offsetMin = new Vector2(16f, 150f);
			component3.offsetMax = new Vector2(-16f, -104f);
			ScrollRect val2 = default(ScrollRect);
			_railList = (Transform)(object)Components.ScrollList(obj.transform, ref val2, 6f);
			BuildRailButton(val, "Save", -1, 0, Theme.Button, delegate
			{
				if (ProjectStore.Save(_project))
				{
					Toast.Show("Saved.", (Severity)1);
				}
			});
			BuildRailButton(val, "Export", -1, 1, Theme.Accent, delegate
			{
				ExportFlow();
			});
			BuildRailButton(val, "Packs", -1, 2, Theme.Button, delegate
			{
				ProjectStore.Save(_project);
				ShowProjectSelect();
			});
			BuildRailButton(val, "Exit", -1, 3, Theme.Button, delegate
			{
				ProjectStore.Save(_project);
				ExitToHub();
			});
			Interactions.PolishButtons(val.transform, true);
		}

		private static void BuildRailButton(GameObject rail, string label, int _, int index, Color color, Action onClick)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_0093: 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)
			ValueTuple<GameObject, Button, Text> valueTuple = UIFactory.ButtonWithLabel("b_" + label, label, rail.transform, color, 0f, 34f);
			GameObject item = valueTuple.Item1;
			Button item2 = valueTuple.Item2;
			RectTransform component = item.GetComponent<RectTransform>();
			float num = 129f;
			int num2 = index % 2;
			int num3 = index / 2;
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0f, 0f);
			component.anchorMax = val;
			component.anchorMin = val;
			component.pivot = new Vector2(0f, 0f);
			component.sizeDelta = new Vector2(num, 34f);
			component.anchoredPosition = new Vector2(16f + (float)num2 * (num + 10f), (float)(18 + (1 - num3) * 42));
			((UnityEvent)item2.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				onClick();
			}));
		}

		private static void BuildRightPanel()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = UIFactory.Panel("Form", _screen.transform, Theme.BgPanel, (Vector2?)null, (Vector2?)null, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(1f, 0f);
			component.anchorMax = new Vector2(1f, 1f);
			component.pivot = new Vector2(1f, 0.5f);
			component.sizeDelta = new Vector2(400f, 0f);
			component.anchoredPosition = Vector2.zero;
			GameObject obj = UIFactory.Panel("scroll", val.transform, Theme.Clear, (Vector2?)null, (Vector2?)null, false);
			RectTransform component2 = obj.GetComponent<RectTransform>();
			component2.anchorMin = Vector2.zero;
			component2.anchorMax = Vector2.one;
			component2.offsetMin = new Vector2(6f, 6f);
			component2.offsetMax = new Vector2(-6f, -6f);
			ScrollRect val2 = default(ScrollRect);
			_formContent = Components.ScrollList(obj.transform, ref val2, 6f);
		}

		private static void BuildBottomBar()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_0089: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = UIFactory.Panel("BottomBar", _screen.transform, Theme.WithAlpha(Theme.BgElevated, 0.9f), (Vector2?)null, (Vector2?)null, false);
			Image component = val.GetComponent<Image>();
			if ((Object)(object)component != (Object)null)
			{
				component.sprite = Theme.RoundedSprite();
				component.type = (Type)1;
			}
			RectTransform component2 = val.GetComponent<RectTransform>();
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.5f, 0f);
			component2.anchorMax = val2;
			component2.anchorMin = val2;
			component2.pivot = new Vector2(0.5f, 0f);
			component2.sizeDelta = new Vector2(430f, 46f);
			component2.anchoredPosition = new Vector2(-50f, 20f);
			GameObject obj = UIFactory.ButtonRow("row", val.transform, 8f, (TextAnchor)4);
			RectTransform component3 = obj.GetComponent<RectTransform>();
			component3.anchorMin = Vector2.zero;
			component3.anchorMax = Vector2.one;
			component3.offsetMin = new Vector2(8f, 6f);
			component3.offsetMax = new Vector2(-8f, -6f);
			BarButton(obj.transform, "< Rotate", delegate
			{
				Preview.RotateAvatar(-25f);
			});
			BarButton(obj.transform, "Rotate >", delegate
			{
				Preview.RotateAvatar(25f);
			});
			BarButton(obj.transform, "Zoom +", delegate
			{
				Preview.ZoomCamera(1f);
			});
			BarButton(obj.transform, "Zoom -", delegate
			{
				Preview.ZoomCamera(-1f);
			});
			BarButton(obj.transform, "Base human", delegate
			{
				if (_selected != null)
				{
					_selected.Appearance = Preview.SeedFromMenu();
					RefreshForm();
					MarkDirty();
				}
			});
			Interactions.PolishButtons(val.transform, true);
		}

		private static void BarButton(Transform parent, string label, Action onClick)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			var (val, val2, val3) = UIFactory.ButtonWithLabel("bb_" + label, label, parent, Theme.Button, 78f, 34f);
			if ((Object)(object)val3 != (Object)null)
			{
				val3.fontSize = 11;
			}
			LayoutElement obj = val.AddComponent<LayoutElement>();
			obj.flexibleWidth = 1f;
			obj.minHeight = 34f;
			((UnityEvent)val2.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				onClick();
			}));
		}

		private static void RefreshRail()
		{
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_railList == (Object)null)
			{
				return;
			}
			UIFactory.ClearChildren(_railList);
			if (_project?.Npcs == null)
			{
				return;
			}
			foreach (NpcDraft npc in _project.Npcs)
			{
				NpcDraft captured = npc;
				bool flag = npc == _selected;
				var (val, val2, val3) = UIFactory.ButtonWithLabel("npc_" + npc.Id, npc.Name + "  (" + Ids.Make(_project.Name, npc.Name) + ")", _railList, flag ? Theme.Accent : Theme.Button, 0f, 40f);
				if ((Object)(object)val3 != (Object)null)
				{
					val3.fontSize = 14;
					val3.alignment = (TextAnchor)3;
					((Graphic)val3).rectTransform.offsetMin = new Vector2(10f, 0f);
				}
				val.AddComponent<LayoutElement>().minHeight = 40f;
				((UnityEvent)val2.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
				{
					_selected = captured;
					RefreshRail();
					RefreshForm();
					MarkDirty();
				}));
			}
			Interactions.PolishButtons(_railList, true);
		}

		private static void AddNpc()
		{
			if (_project != null)
			{
				NpcDraft npcDraft = new NpcDraft
				{
					Name = "NPC " + (_project.Npcs.Count + 1),
					Appearance = Preview.SeedFromMenu()
				};
				_project.Npcs.Add(npcDraft);
				_selected = npcDraft;
				RefreshRail();
				RefreshForm();
				MarkDirty();
			}
		}

		private static void RemoveSelected()
		{
			if (_project != null && _selected != null)
			{
				_project.Npcs.Remove(_selected);
				_selected = ((_project.Npcs.Count > 0) ? _project.Npcs[0] : null);
				RefreshRail();
				RefreshForm();
				MarkDirty();
			}
		}

		private static void RefreshForm()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_formContent == (Object)null)
			{
				return;
			}
			UIFactory.ClearChildren((Transform)(object)_formContent);
			if (_selected == null)
			{
				Text obj = UIFactory.Text("none", "No NPC selected. Click \"+ Add NPC\".", (Transform)(object)_formContent, 13, (TextAnchor)0, (FontStyle)0);
				((Graphic)obj).color = Theme.TextMuted;
				((Component)obj).gameObject.AddComponent<LayoutElement>().minHeight = 40f;
				return;
			}
			NpcDraft selected = _selected;
			NpcDraft npcDraft = selected;
			if (npcDraft.Appearance == null)
			{
				AppearanceDraft appearanceDraft = (npcDraft.Appearance = new AppearanceDraft());
			}
			ModeToggle();
			if (_mode == FormMode.Basic)
			{
				BuildBasicForm(selected);
			}
			else
			{
				BuildAdvancedForm(selected);
			}
			Interactions.PolishButtons((Transform)(object)_formContent, true);
		}

		private static void ModeToggle()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("mode");
			val.transform.SetParent((Transform)(object)_formContent, false);
			val.AddComponent<RectTransform>();
			LayoutElement obj = val.AddComponent<LayoutElement>();
			obj.minHeight = 34f;
			obj.preferredHeight = 34f;
			obj.flexibleWidth = 1f;
			Button[] array = default(Button[]);
			StretchFill(Components.Segmented(val.transform, new string[2] { "Character", "Advanced" }, (_mode != FormMode.Basic) ? 1 : 0, (Action<int>)delegate(int i)
			{
				_mode = ((i != 0) ? FormMode.Advanced : FormMode.Basic);
				RefreshForm();
			}, ref array, false, 6f, (Texture2D[])null).GetComponent<RectTransform>());
		}

		private static void BuildAdvancedForm(NpcDraft n)
		{
			AppearanceDraft a = n.Appearance;
			Components.SectionHeader((Transform)(object)_formContent, "Identity");
			TextRow("Name", n.Name, delegate(string v)
			{
				n.Name = v;
				RefreshForm();
			}, refreshRailOnEdit: true);
			IdCaption(n);
			RemoveRow();
			Components.SectionHeader((Transform)(object)_formContent, "Body");
			GenderRow(a);
			SliderRow("Height", 0.7f, 1.3f, a.Height, delegate(float v)
			{
				a.Height = v;
			});
			SliderRow("Weight", 0f, 1f, a.Weight, delegate(float v)
			{
				a.Weight = v;
			});
			ColorRow("Skin colour", a.SkinColor, delegate(string v)
			{
				a.SkinColor = v;
			});
			Components.SectionHeader((Transform)(object)_formContent, "Hair");
			ColorRow("Hair colour", a.HairColor, delegate(string v)
			{
				a.HairColor = v;
			});
			PickerRow("Hair style", a.HairPath, "Choose a hair style", PathCatalog.HairStyles(), allowNone: true, delegate(string v)
			{
				a.HairPath = v;
			});
			Components.SectionHeader((Transform)(object)_formContent, "Eyes");
			ColorRow("Eyeball tint", a.EyeBallTint, delegate(string v)
			{
				a.EyeBallTint = v;
			});
			SliderRow("Pupil", 0f, 1f, a.PupilDilation, delegate(float v)
			{
				a.PupilDilation = v;
			});
			SliderRow("L. eyelid", 0f, 1f, a.LeftEyeTop, delegate(float v)
			{
				a.LeftEyeTop = v;
				a.LeftEyeBottom = v;
			});
			SliderRow("R. eyelid", 0f, 1f, a.RightEyeTop, delegate(float v)
			{
				a.RightEyeTop = v;
				a.RightEyeBottom = v;
			});
			Components.SectionHeader((Transform)(object)_formContent, "Eyebrows");
			SliderRow("Scale", 0f, 2f, a.EyebrowScale, delegate(float v)
			{
				a.EyebrowScale = v;
			});
			SliderRow("Thickness", 0f, 2f, a.EyebrowThickness, delegate(float v)
			{
				a.EyebrowThickness = v;
			});
			SliderRow("Height", 0f, 1f, a.EyebrowRestingHeight, delegate(float v)
			{
				a.EyebrowRestingHeight = v;
			});
			SliderRow("Angle", 0f, 1f, a.EyebrowRestingAngle, delegate(float v)
			{
				a.EyebrowRestingAngle = v;
			});
			LayerSection("Face layers", a.FaceLayers, PathCatalog.FaceLayers(), "face layer");
			LayerSection("Body layers", a.BodyLayers, PathCatalog.BodyLayers(), "body layer");
			LayerSection("Accessories", a.Accessories, PathCatalog.Accessories(), "accessory", allowCustomImport: false);
			Components.SectionHeader((Transform)(object)_formContent, "Behaviour (S1API, optional)");
			ToggleRow("Enable behaviour", n.Behavior.Enabled, delegate(bool v)
			{
				n.Behavior.Enabled = v;
				RefreshForm();
			});
			if (n.Behavior.Enabled)
			{
				SliderRow("Aggression", 0f, 1f, n.Behavior.Aggression, delegate(float v)
				{
					n.Behavior.Aggression = v;
				});
				SliderRow("Max health", 1f, 500f, n.Behavior.MaxHealth, delegate(float v)
				{
					n.Behavior.MaxHealth = v;
				});
				SliderRow("Scale", 0.5f, 2f, n.Behavior.Scale, delegate(float v)
				{
					n.Behavior.Scale = v;
				});
				ConversationRow("Conversation", n.Behavior.Conversation, delegate(string v)
				{
					n.Behavior.Conversation = v;
				});
			}
			BackroomsSection(n);
		}

		private static void BuildBasicForm(NpcDraft n)
		{
			//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
			AppearanceDraft a = n.Appearance;
			Components.SectionHeader((Transform)(object)_formContent, "Identity");
			TextRow("Name", n.Name, delegate(string v)
			{
				n.Name = v;
				RefreshForm();
			}, refreshRailOnEdit: true);
			IdCaption(n);
			RemoveRow();
			Components.SectionHeader((Transform)(object)_formContent, "Body");
			GenderRow(a);
			SliderRow("Weight", 0f, 1f, a.Weight, delegate(float v)
			{
				a.Weight = v;
			});
			ColorRow("Skin", a.SkinColor, delegate(string v)
			{
				a.SkinColor = v;
			});
			Components.SectionHeader((Transform)(object)_formContent, "Hair");
			PickerRow("Style", a.HairPath, "Choose a hair style", PathCatalog.HairStyles(), allowNone: true, delegate(string v)
			{
				a.HairPath = v;
			});
			ColorRow("Colour", a.HairColor, delegate(string v)
			{
				a.HairColor = v;
			});
			Components.SectionHeader((Transform)(object)_formContent, "Face");
			SlotRow("Mouth", a.FaceLayers, PathCatalog.Mouths(), withTint: false);
			SlotRow("Facial hair", a.FaceLayers, PathCatalog.FacialHairStyles(), withTint: false);
			SlotRow("Facial details", a.FaceLayers, PathCatalog.FacialDetails(), withTint: false);
			Components.SectionHeader((Transform)(object)_formContent, "Eyes");
			ColorRow("Eye colour", a.EyeBallTint, delegate(string v)
			{
				a.EyeBallTint = v;
			});
			SliderRow("Pupil", 0f, 1f, a.PupilDilation, delegate(float v)
			{
				a.PupilDilation = v;
			});
			SliderRow("Upper lid", 0f, 1f, a.LeftEyeTop, delegate(float v)
			{
				a.LeftEyeTop = v;
				a.RightEyeTop = v;
			});
			SliderRow("Lower lid", 0f, 1f, a.LeftEyeBottom, delegate(float v)
			{
				a.LeftEyeBottom = v;
				a.RightEyeBottom = v;
			});
			Components.SectionHeader((Transform)(object)_formContent, "Eyebrows");
			SliderRow("Scale", 0f, 2f, a.EyebrowScale, delegate(float v)
			{
				a.EyebrowScale = v;
			});
			SliderRow("Thickness", 0f, 2f, a.EyebrowThickness, delegate(float v)
			{
				a.EyebrowThickness = v;
			});
			SliderRow("Height", 0f, 1f, a.EyebrowRestingHeight, delegate(float v)
			{
				a.EyebrowRestingHeight = v;
			});
			SliderRow("Angle", 0f, 1f, a.EyebrowRestingAngle, delegate(float v)
			{
				a.EyebrowRestingAngle = v;
			});
			Components.SectionHeader((Transform)(object)_formContent, "Clothing");
			SlotRow("Top", a.BodyLayers, PathCatalog.Tops());
			SlotRow("Bottom", a.BodyLayers, PathCatalog.Bottoms());
			Components.SectionHeader((Transform)(object)_formContent, "Accessories");
			SlotRow("Shoes", a.Accessories, PathCatalog.Shoes());
			SlotRow("Headwear", a.Accessories, PathCatalog.Headwear());
			SlotRow("Eyewear", a.Accessories, PathCatalog.Eyewear());
			Components.SectionHeader((Transform)(object)_formContent, "Tattoos");
			TattooSection(a);
			Text obj = UIFactory.Text("hint", "Advanced tab: stacked/extra layers, custom PNG layers, per-layer visibility, tint, Backrooms binding & full behaviour.", (Transform)(object)_formContent, 11, (TextAnchor)0, (FontStyle)0);
			((Graphic)obj).color = Theme.TextMuted;
			((Graphic)obj).raycastTarget = false;
			obj.horizontalOverflow = (HorizontalWrapMode)0;
			((Component)obj).gameObject.AddComponent<LayoutElement>().minHeight = 44f;
		}

		private static void TattooSection(AppearanceDraft a)
		{
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: 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)
			List<PathOption> options = PathCatalog.Tattoos();
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			foreach (PathOption item in options)
			{
				hashSet.Add(item.Path);
			}
			ShowTattooRows(a.FaceLayers, hashSet);
			ShowTattooRows(a.BodyLayers, hashSet);
			var (val, val2, _) = UIFactory.ButtonWithLabel("addtat", "+ Add tattoo", (Transform)(object)_formContent, Theme.Accent, 0f, 30f);
			val.AddComponent<LayoutElement>().minHeight = 30f;
			((UnityEvent)val2.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				OptionPicker.Show(_canvasGO.transform, "Choose tattoo", options, null, allowNone: false, delegate(string chosen)
				{
					if (!string.IsNullOrEmpty(chosen))
					{
						List<LayerDraft> list = ((chosen.IndexOf("/Face/", StringComparison.OrdinalIgnoreCase) >= 0) ? a.FaceLayers : a.BodyLayers);
						if (!HasPath(list, chosen))
						{
							list.Add(new LayerDraft
							{
								Path = chosen,
								Tint = "#FFFFFF"
							});
						}
						RefreshForm();
						MarkDirty();
					}
				});
			}));
			if (!InkorporatedInstalled())
			{
				return;
			}
			List<InkTattoo> ink = InkorporatedCatalog.All();
			bool flag = ink.Count > 0;
			var (val3, val4, val5) = UIFactory.ButtonWithLabel("addink", flag ? "+ Add Inkorporated tattoo" : "Inkorporated: no tattoo packs found", (Transform)(object)_formContent, flag ? Theme.Button : Theme.BgElevated, 0f, 30f);
			if ((Object)(object)val5 != (Object)null)
			{
				val5.fontSize = 11;
			}
			val3.AddComponent<LayoutElement>().minHeight = 30f;
			if (!flag)
			{
				return;
			}
			((UnityEvent)val4.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				List<PathOption> list = new List<PathOption>();
				foreach (InkTattoo item2 in ink)
				{
					list.Add(new PathOption(item2.Pack, item2.Name, item2.PngPath));
				}
				OptionPicker.Show(_canvasGO.transform, "Inkorporated tattoos", list, null, allowNone: false, delegate(string chosen)
				{
					InkTattoo inkTattoo = InkorporatedCatalog.ByPng(chosen);
					if (inkTattoo != null && _project != null)
					{
						string text = ProjectStore.ImportSource(_project, inkTattoo.PngPath);
						if (text == null)
						{
							Toast.Show("Import failed.", (Severity)3);
						}
						else
						{
							(inkTattoo.IsFace ? a.FaceLayers : a.BodyLayers).Add(new LayerDraft
							{
								Source = text,
								Tint = "#FFFFFF"
							});
							RefreshForm();
							MarkDirty();
						}
					}
				});
			}));
		}

		private static void ShowTattooRows(List<LayerDraft> list, HashSet<string> tattooPaths)
		{
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < list.Count; i++)
			{
				LayerDraft layerDraft = list[i];
				if (layerDraft == null)
				{
					continue;
				}
				bool num = !string.IsNullOrEmpty(layerDraft.Path) && tattooPaths.Contains(layerDraft.Path);
				bool flag = !string.IsNullOrWhiteSpace(layerDraft.Source);
				if (num || flag)
				{
					string text = (flag ? Path.GetFileNameWithoutExtension(layerDraft.Source) : PathCatalog.DisplayName(layerDraft.Path));
					LayerDraft cap = layerDraft;
					var (val, val2, val3) = UIFactory.ButtonWithLabel("tat", "✕  " + text, (Transform)(object)_formContent, Theme.Button, 0f, 28f);
					if ((Object)(object)val3 != (Object)null)
					{
						val3.fontSize = 11;
						val3.alignment = (TextAnchor)3;
						((Graphic)val3).rectTransform.offsetMin = new Vector2(10f, 0f);
					}
					val.AddComponent<LayoutElement>().minHeight = 28f;
					((UnityEvent)val2.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
					{
						list.Remove(cap);
						RefreshForm();
						MarkDirty();
					}));
				}
			}
		}

		private static bool HasPath(List<LayerDraft> list, string path)
		{
			if (list == null)
			{
				return false;
			}
			foreach (LayerDraft item in list)
			{
				if (item != null && string.Equals(item.Path, path, StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
			}
			return false;
		}

		private static void BackroomsSection(NpcDraft n)
		{
			if (!BackroomsInstalled())
			{
				return;
			}
			Components.SectionHeader((Transform)(object)_formContent, "Backrooms binding (optional)");
			ToggleRow("Enable Backrooms", n.Backrooms.Enabled, delegate(bool v)
			{
				n.Backrooms.Enabled = v;
				RefreshForm();
			});
			if (n.Backrooms.Enabled)
			{
				ArchetypeRow(n.Backrooms);
				StepperRow("Tier min", 0, 5, n.Backrooms.TierMin, delegate(int v)
				{
					n.Backrooms.TierMin = v;
				});
				StepperRow("Tier max", 0, 5, n.Backrooms.TierMax, delegate(int v)
				{
					n.Backrooms.TierMax = v;
				});
				ToggleRow("Hostile", n.Backrooms.Hostile, delegate(bool v)
				{
					n.Backrooms.Hostile = v;
				});
				ToggleRow("Ambient spawn", n.Backrooms.Ambient, delegate(bool v)
				{
					n.Backrooms.Ambient = v;
				});
				SliderRow("Spawn weight", 0f, 30f, n.Backrooms.Weight, delegate(float v)
				{
					n.Backrooms.Weight = v;
				});
				StepperRow("Max alive", 1, 8, n.Backrooms.MaxAlive, delegate(int v)
				{
					n.Backrooms.MaxAlive = v;
				});
				TextRow("Biomes (csv, e.g. L0,L1)", n.Backrooms.Biomes, delegate(string v)
				{
					n.Backrooms.Biomes = v;
				});
			}
		}

		private static bool BackroomsInstalled()
		{
			return ModInstalled("Backrooms");
		}

		private static bool InkorporatedInstalled()
		{
			return ModInstalled("Inkorporated");
		}

		private static bool ModInstalled(string modName)
		{
			if (_modInstalled.TryGetValue(modName, out var value))
			{
				return value;
			}
			bool flag = false;
			try
			{
				if (typeof(MelonBase).GetProperty("RegisteredMelons", BindingFlags.Static | BindingFlags.Public)?.GetValue(null) is IEnumerable enumerable)
				{
					foreach (object item in enumerable)
					{
						object obj = item?.GetType().GetProperty("Info")?.GetValue(item);
						if (string.Equals(obj?.GetType().GetProperty("Name")?.GetValue(obj) as string, modName, StringComparison.OrdinalIgnoreCase))
						{
							flag = true;
							break;
						}
					}
				}
			}
			catch
			{
			}
			_modInstalled[modName] = flag;
			return flag;
		}

		private static void SlotRow(string label, List<LayerDraft> list, List<PathOption> options, bool withTint = true)
		{
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Expected O, but got Unknown
			//IL_0311: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			HashSet<string> paths = new HashSet<string>(options.Select((PathOption o) => o.Path), StringComparer.OrdinalIgnoreCase);
			LayerDraft layerDraft = null;
			foreach (LayerDraft item in list)
			{
				if (item != null && !string.IsNullOrEmpty(item.Path) && paths.Contains(item.Path))
				{
					layerDraft = item;
					break;
				}
			}
			string text = ((layerDraft != null) ? PathCatalog.DisplayName(layerDraft.Path) : "(None)");
			GameObject val = new GameObject("slot");
			val.transform.SetParent((Transform)(object)_formContent, false);
			val.AddComponent<RectTransform>();
			LayoutElement obj = val.AddComponent<LayoutElement>();
			obj.minHeight = 32f;
			obj.preferredHeight = 32f;
			obj.flexibleWidth = 1f;
			HorizontalLayoutGroup obj2 = val.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj2).spacing = 8f;
			((LayoutGroup)obj2).childAlignment = (TextAnchor)3;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false;
			Text obj3 = UIFactory.Text("l", label, val.transform, 13, (TextAnchor)3, (FontStyle)0);
			((Graphic)obj3).color = Theme.TextPrimary;
			((Graphic)obj3).raycastTarget = false;
			obj3.horizontalOverflow = (HorizontalWrapMode)1;
			LayoutElement obj4 = ((Component)obj3).gameObject.AddComponent<LayoutElement>();
			obj4.minWidth = 84f;
			obj4.preferredWidth = 84f;
			obj4.flexibleWidth = 0f;
			var (val2, val3, val4) = UIFactory.ButtonWithLabel("pick", text + "   ▾", val.transform, Theme.SurfaceInput, 0f, 30f);
			if ((Object)(object)val4 != (Object)null)
			{
				val4.fontSize = 13;
				val4.alignment = (TextAnchor)3;
				((Graphic)val4).rectTransform.offsetMin = new Vector2(10f, 0f);
				((Graphic)val4).color = ((layerDraft != null) ? Theme.TextPrimary : Theme.TextMuted);
			}
			LayoutElement obj5 = val2.AddComponent<LayoutElement>();
			obj5.flexibleWidth = 1f;
			obj5.minHeight = 30f;
			string keepTint = layerDraft?.Tint ?? "#FFFFFF";
			string currentPath = layerDraft?.Path ?? "";
			((UnityEvent)val3.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				OptionPicker.Show(_canvasGO.transform, "Choose " + label, options, currentPath, allowNone: true, delegate(string chosen)
				{
					list.RemoveAll((LayerDraft x) => x != null && !string.IsNullOrEmpty(x.Path) && paths.Contains(x.Path));
					if (!string.IsNullOrEmpty(chosen))
					{
						list.Add(new LayerDraft
						{
							Path = chosen,
							Tint = keepTint
						});
					}
					RefreshForm();
					MarkDirty();
				});
			}));
			if (!withTint || layerDraft == null)
			{
				return;
			}
			GameObject val5 = new GameObject("sw");
			val5.transform.SetParent(val.transform, false);
			Image swImg = val5.AddComponent<Image>();
			swImg.sprite = Theme.RoundedSprite();
			swImg.type = (Type)1;
			((Graphic)swImg).color = Preview.Hex(layerDraft.Tint, Color.white);
			Button obj6 = val5.AddComponent<Button>();
			((Selectable)obj6).targetGraphic = (Graphic)(object)swImg;
			LayoutElement obj7 = val5.AddComponent<LayoutElement>();
			obj7.minWidth = 26f;
			obj7.preferredWidth = 26f;
			LayerDraft cap = layerDraft;
			((UnityEvent)obj6.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				ColorPicker.Show(_canvasGO.transform, label + " colour", cap.Tint, delegate(string hx)
				{
					//IL_0013: Unknown result type (might be due to invalid IL or missing references)
					//IL_0018: Unknown result type (might be due to invalid IL or missing references)
					cap.Tint = hx;
					((Graphic)swImg).color = Preview.Hex(hx, Color.white);
					MarkDirty();
				});
			}));
		}

		private static void SliderRow(string label, float min, float max, float value, Action<float> set, bool whole = false)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("sliderRow");
			val.transform.SetParent((Transform)(object)_formContent, false);
			val.AddComponent<RectTransform>();
			LayoutElement obj = val.AddComponent<LayoutElement>();
			obj.minHeight = 28f;
			obj.preferredHeight = 28f;
			obj.flexibleWidth = 1f;
			HorizontalLayoutGroup obj2 = val.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj2).spacing = 8f;
			((LayoutGroup)obj2).childAlignment = (TextAnchor)3;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false;
			Text obj3 = UIFactory.Text("l", label, val.transform, 13, (TextAnchor)3, (FontStyle)0);
			((Graphic)obj3).color = Theme.TextPrimary;
			((Graphic)obj3).raycastTarget = false;
			obj3.horizontalOverflow = (HorizontalWrapMode)1;
			LayoutElement obj4 = ((Component)obj3).gameObject.AddComponent<LayoutElement>();
			obj4.minWidth = 84f;
			obj4.preferredWidth = 84f;
			obj4.flexibleWidth = 0f;
			Text valText = UIFactory.Text("v", Fmt(value, whole), val.transform, 11, (TextAnchor)5, (FontStyle)0);
			((Graphic)valText).color = Theme.TextMuted;
			((Graphic)valText).raycastTarget = false;
			LayoutElement obj5 = ((Component)valText).gameObject.AddComponent<LayoutElement>();
			obj5.minWidth = 38f;
			obj5.preferredWidth = 38f;
			obj5.flexibleWidth = 0f;
			((Component)SliderStyle.Compact(Components.Slider(val.transform, min, max, value, (Action<float>)delegate(float v)
			{
				set(v);
				valText.text = Fmt(v, whole);
				MarkDirty();
			}, 0f))).transform.SetSiblingIndex(1);
		}

		private static string Fmt(float v, bool whole)
		{
			if (!whole)
			{
				return v.ToString("0.00");
			}
			return Mathf.RoundToInt(v).ToString();
		}

		private static void TextRow(string label, string value, Action<string> set, bool refreshRailOnEdit = false)
		{
			Transform val = default(Transform);
			Components.FormRow((Transform)(object)_formContent, label, (string)null, ref val, true, 50f);
			StretchFill(((Component)Components.TextInput(val, value, (Action<string>)delegate(string s)
			{
				set(s);
				if (refreshRailOnEdit)
				{
					RefreshRail();
				}
				MarkDirty();
			}, (string)null, 0, false)).GetComponent<RectTransform>());
		}

		private static void ToggleRow(string label, bool value, Action<bool> set)
		{
			//IL_004d: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			Transform val = default(Transform);
			Components.FormRow((Transform)(object)_formContent, label, (string)null, ref val, false, 30f);
			RectTransform component = ((Component)Components.Toggle(val, value, (Action<bool>)delegate(bool v)
			{
				set(v);
				MarkDirty();
			})).GetComponent<RectTransform>();
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0f, 0.5f);
			component.anchorMax = val2;
			component.anchorMin = val2;
			component.pivot = new Vector2(0f, 0.5f);
			component.anchoredPosition = Vector2.zero;
		}

		private static void StepperRow(string label, int min, int max, int value, Action<int> set)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			Transform val = default(Transform);
			Components.FormRow((Transform)(object)_formContent, label, (string)null, ref val, false, 30f);
			GameObject val2 = new GameObject("stepper");
			val2.transform.SetParent(val, false);
			StretchFill(val2.AddComponent<RectTransform>());
			HorizontalLayoutGroup obj = val2.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 6f;
			((LayoutGroup)obj).childAlignment = (TextAnchor)3;
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = true;
			int current = Mathf.Clamp(value, min, max);
			var (val3, minusBtn, val4) = UIFactory.ButtonWithLabel("minus", "-", val2.transform, Theme.Button, 28f, 28f);
			if ((Object)(object)val4 != (Object)null)
			{
				val4.fontSize = 14;
			}
			val3.AddComponent<LayoutElement>().minWidth = 28f;
			Text valText = UIFactory.Text("v", current.ToString(), val2.transform, 14, (TextAnchor)4, (FontStyle)1);
			((Graphic)valText).color = Theme.TextPrimary;
			((Graphic)valText).raycastTarget = false;
			LayoutElement obj2 = ((Component)valText).gameObject.AddComponent<LayoutElement>();
			obj2.minWidth = 36f;
			obj2.preferredWidth = 36f;
			var (val5, plusBtn, val6) = UIFactory.ButtonWithLabel("plus", "+", val2.transform, Theme.Button, 28f, 28f);
			if ((Object)(object)val6 != (Object)null)
			{
				val6.fontSize = 14;
			}
			val5.AddComponent<LayoutElement>().minWidth = 28f;
			((Selectable)minusBtn).interactable = current > min;
			((Selectable)plusBtn).interactable = current < max;
			((UnityEvent)minusBtn.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				Apply(current - 1);
			}));
			((UnityEvent)plusBtn.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				Apply(current + 1);
			}));
			void Apply(int v)
			{
				current = Mathf.Clamp(v, min, max);
				valText.text = current.ToString();
				((Selectable)minusBtn).interactable = current > min;
				((Selectable)plusBtn).interactable = current < max;
				set(current);
				MarkDirty();
			}
		}

		private static void GenderRow(AppearanceDraft a)
		{
			string[] array = new string[2] { "Male", "Female" };
			int num = ((a.Gender >= 0.5f) ? 1 : 0);
			Transform val = default(Transform);
			Components.FormRow((Transform)(object)_formContent, "Gender", (string)null, ref val, false, 30f);
			Button[] array2 = default(Button[]);
			StretchFill(Components.Segmented(val, array, num, (Action<int>)delegate(int i)
			{
				a.Gender = ((i == 0) ? 0f : 1f);
				MarkDirty();
			}, ref array2, false, 6f, (Texture2D[])null).GetComponent<RectTransform>());
		}

		private static void ConversationRow(string label, string current, Action<string> set)
		{
			string[] values = new string[3] { "none", "customer", "dealer" };
			string[] array = new string[3] { "None", "Customer", "Dealer" };
			int num = Array.IndexOf(values, (current ?? "none").ToLowerInvariant());
			if (num < 0)
			{
				num = 0;
			}
			Transform val = default(Transform);
			Components.FormRow((Transform)(object)_formContent, label, (string)null, ref val, false, 30f);
			Button[] array2 = default(Button[]);
			StretchFill(Components.Segmented(val, array, num, (Action<int>)delegate(int i)
			{
				set(values[i]);
				MarkDirty();
			}, ref array2, false, 6f, (Texture2D[])null).GetComponent<RectTransform>());
		}

		private static void ColorRow(string label, string hex, Action<string> set)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0059: 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_00a3: Expected O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			//IL_0114: 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_017a: Unknown result type (might be due to invalid IL or missing references)
			Transform val = default(Transform);
			Components.FormRow((Transform)(object)_formContent, label, (string)null, ref val, false, 30f);
			GameObject val2 = new GameObject("colorwrap");
			val2.transform.SetParent(val, false);
			StretchFill(val2.AddComponent<RectTransform>());
			Image val3 = val2.AddComponent<Image>();
			((Graphic)val3).color = Theme.SurfaceInput;
			val3.sprite = Theme.RoundedSprite();
			val3.type = (Type)1;
			Button obj = val2.AddComponent<Button>();
			((Selectable)obj).targetGraphic = (Graphic)(object)val3;
			HorizontalLayoutGroup obj2 = val2.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj2).spacing = 8f;
			((LayoutGroup)obj2).padding = new RectOffset(6, 10, 3, 3);
			((LayoutGroup)obj2).childAlignment = (TextAnchor)3;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = true;
			GameObject val4 = new GameObject("swatch");
			val4.transform.SetParent(val2.transform, false);
			Image swImg = val4.AddComponent<Image>();
			swImg.sprite = Theme.RoundedSprite();
			swImg.type = (Type)1;
			((Graphic)swImg).color = Preview.Hex(hex, Color.white);
			((Graphic)swImg).raycastTarget = false;
			LayoutElement obj3 = val4.AddComponent<LayoutElement>();
			obj3.minWidth = 24f;
			obj3.preferredWidth = 24f;
			Text hexText = UIFactory.Text("hex", (hex ?? "#FFFFFF").ToUpperInvariant(), val2.transform, 13, (TextAnchor)3, (FontStyle)0);
			((Graphic)hexText).color = Theme.TextPrimary;
			((Graphic)hexText).raycastTarget = false;
			LayoutElement obj4 = ((Component)hexText).gameObject.AddComponent<LayoutElement>();
			obj4.flexibleWidth = 1f;
			obj4.minWidth = 0f;
			obj4.preferredWidth = 0f;
			string currentHex = hex;
			((UnityEvent)obj.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				ColorPicker.Show(_canvasGO.transform, label, currentHex, delegate(string newHex)
				{
					//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)
					currentHex = newHex;
					set(newHex);
					((Graphic)swImg).color = Preview.Hex(newHex, Color.white);
					hexText.text = newHex.ToUpperInvariant();
					MarkDirty();
				});
			}));
		}

		private static void PickerRow(string label, string currentPath, string pickerTitle, List<PathOption> options, bool allowNone, Action<string> set)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: 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_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: 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)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			Transform val = default(Transform);
			Components.FormRow((Transform)(object)_formContent, label, (string)null, ref val, false, 30f);
			GameObject val2 = new GameObject("pick");
			val2.transform.SetParent(val, false);
			StretchFill(val2.AddComponent<RectTransform>());
			Image val3 = val2.AddComponent<Image>();
			((Graphic)val3).color = Theme.SurfaceInput;
			val3.sprite = Theme.RoundedSprite();
			val3.type = (Type)1;
			Button obj = val2.AddComponent<Button>();
			((Selectable)obj).targetGraphic = (Graphic)(object)val3;
			bool flag = !string.IsNullOrEmpty(currentPath);
			Text obj2 = UIFactory.Text("t", flag ? PathCatalog.DisplayName(currentPath) : "(None)", val2.transform, 13, (TextAnchor)3, (FontStyle)0);
			((Graphic)obj2).color = (flag ? Theme.TextPrimary : Theme.TextMuted);
			((Graphic)obj2).raycastTarget = false;
			RectTransform rectTransform = ((Graphic)obj2).rectTransform;
			rectTransform.anchorMin = Vector2.zero;
			rectTransform.anchorMax = Vector2.one;
			rectTransform.offsetMin = new Vector2(10f, 0f);
			rectTransform.offsetMax = new Vector2(-26f, 0f);
			Text obj3 = UIFactory.Text("chev", "▾", val2.transform, 11, (TextAnchor)5, (FontStyle)0);
			((Graphic)obj3).color = Theme.TextMuted;
			((Graphic)obj3).raycastTarget = false;
			RectTransform rectTransform2 = ((Graphic)obj3).rectTransform;
			rectTransform2.anchorMin = new Vector2(1f, 0f);
			rectTransform2.anchorMax = Vector2.one;
			rectTransform2.pivot = new Vector2(1f, 0.5f);
			rectTransform2.offsetMin = new Vector2(-22f, 0f);
			rectTransform2.offsetMax = new Vector2(-8f, 0f);
			((UnityEvent)obj.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				OptionPicker.Show(_canvasGO.transform, pickerTitle, options, currentPath, allowNone, delegate(string chosen)
				{
					set(chosen ?? "");
					RefreshForm();
					MarkDirty();
				});
			}));
		}

		private static void StretchFill(RectTransform rt)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			rt.anchorMin = Vector2.zero;
			rt.anchorMax = Vector2.one;
			rt.offsetMin = Vector2.zero;
			rt.offsetMax = Vector2.zero;
		}

		private static void IdCaption(NpcDraft n)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			string text = ((_project != null) ? Ids.Make(_project.Name, n.Name) : Ids.Normalize(n.Name));
			Text obj = UIFactory.Text("idcap", "id: " + text, (Transform)(object)_formContent, 11, (TextAnchor)0, (FontStyle)0);
			((Graphic)obj).color = Theme.TextMuted;
			((Graphic)obj).raycastTarget = false;
			((Component)obj).gameObject.AddComponent<LayoutElement>().minHeight = 18f;
		}

		private static void RemoveRow()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			var (val, val2, _) = UIFactory.ButtonWithLabel("rm", "Remove this NPC", (Transform)(object)_formContent, Theme.Button, 0f, 32f);
			val.AddComponent<LayoutElement>().minHeight = 32f;
			((UnityEvent)val2.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				Components.ConfirmDialog(_canvasGO.transform, "Remove NPC?", "Remove \"" + _selected?.Name + "\" from this pack?", "Remove", (Action)delegate
				{
					RemoveSelected();
				});
			}));
		}

		private static void ArchetypeRow(BackroomsDraft b)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: 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)
			Text obj = UIFactory.Text("archlbl", "Archetype (which Backrooms brain)", (Transform)(object)_formContent, 14, (TextAnchor)6, (FontStyle)0);
			((Graphic)obj).color = Theme.TextPrimary;
			((Graphic)obj).raycastTarget = false;
			((Component)obj).gameObject.AddComponent<LayoutElement>().minHeight = 22f;
			GameObject val = new GameObject("arch");
			val.transform.SetParent((Transform)(object)_formContent, false);
			val.AddComponent<RectTransform>();
			GridLayoutGroup obj2 = val.AddComponent<GridLayoutGroup>();
			obj2.cellSize = new Vector2(170f, 30f);
			obj2.spacing = new Vector2(6f, 6f);
			obj2.constraint = (Constraint)1;
			obj2.constraintCount = 2;
			int num = Mathf.CeilToInt((float)BackroomsPreset.Archetypes.Length / 2f);
			LayoutElement obj3 = val.AddComponent<LayoutElement>();
			obj3.minHeight = num * 36;
			obj3.preferredHeight = num * 36;
			List<Button> buttons = new List<Button>();
			for (int i = 0; i < BackroomsPreset.Archetypes.Length; i++)
			{
				string arch = BackroomsPreset.Archetypes[i];
				ValueTuple<GameObject, Button, Text> valueTuple = UIFactory.ButtonWithLabel("a_" + arch, arch, val.transform, (arch == b.Archetype) ? Theme.Accent : Theme.Button, 0f, 30f);
				Button item = valueTuple.Item2;
				Text item2 = valueTuple.Item3;
				if ((Object)(object)item2 != (Object)null)
				{
					item2.fontSize = 11;
				}
				buttons.Add(item);
				((UnityEvent)item.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
				{
					//IL_0056: Unknown result type (might be due to invalid IL or missing references)
					//IL_004f: Unknown result type (might be due to invalid IL or missing references)
					b.Archetype = arch;
					for (int j = 0; j < buttons.Count; j++)
					{
						Image component = ((Component)buttons[j]).GetComponent<Image>();
						if ((Object)(object)component != (Object)null)
						{
							((Graphic)component).color = ((BackroomsPreset.Archetypes[j] == arch) ? Theme.Accent : Theme.Button);
						}
					}
				}));
			}
			Interactions.PolishButtons(val.transform, true);
		}

		private static void LayerSection(string title, List<LayerDraft> list, List<PathOption> catalog, string kindLabel, bool allowCustomImport = true)
		{
			//IL_009e: 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)
			Components.SectionHeader((Transform)(object)_formContent, title + " (" + (list?.Count ?? 0) + ")");
			if (list != null)
			{
				for (int i = 0; i < list.Count; i++)
				{
					LayerRow(list, list[i]);
				}
			}
			var (val, val2, _) = UIFactory.ButtonWithLabel("addlyr", "+ Add " + kindLabel, (Transform)(object)_formContent, Theme.Accent, 0f, 32f);
			val.AddComponent<LayoutElement>().minHeight = 32f;
			((UnityEvent)val2.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				OptionPicker.Show(_canvasGO.transform, "Choose " + kindLabel, catalog, null, allowNone: false, delegate(string chosen)
				{
					if (!string.IsNullOrEmpty(chosen) && list != null)
					{
						list.Add(new LayerDraft
						{
							Path = chosen,
							Tint = "#FFFFFF"
						});
						RefreshForm();
						MarkDirty();
					}
				});
			}));
			if (allowCustomImport)
			{
				var (val3, val4, val5) = UIFactory.ButtonWithLabel("implyr", "Import custom PNG...", (Transform)(object)_formContent, Theme.Button, 0f, 28f);
				if ((Object)(object)val5 != (Object)null)
				{
					val5.fontSize = 11;
				}
				val3.AddComponent<LayoutElement>().minHeight = 28f;
				((UnityEvent)val4.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
				{
					ImportLayerFlow(list, kindLabel);
				}));
			}
		}

		private static void LayerRow(List<LayerDraft> list, LayerDraft l)
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: 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_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Expected O, but got Unknown
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Expected O, but got Unknown
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f9: 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_0423: Unknown result type (might be due to invalid IL or missing references)
			//IL_0437: Unknown result type (might be due to invalid IL or missing references)
			string text = ((!string.IsNullOrWhiteSpace(l.Source)) ? ("PNG " + Path.GetFileName(l.Source)) : PathCatalog.DisplayName(l.Path));
			LayerDraft captured = l;
			GameObject val = UIFactory.Panel("lyr", (Transform)(object)_formContent, Theme.BgElevated, (Vector2?)null, (Vector2?)null, false);
			Image component = val.GetComponent<Image>();
			if ((Object)(object)component != (Object)null)
			{
				component.sprite = Theme.RoundedSprite();
				component.type = (Type)1;
			}
			val.AddComponent<LayoutElement>().minHeight = 36f;
			(GameObject, Button, Text) tuple = UIFactory.ButtonWithLabel("eye", "", val.transform, Theme.Button, 26f, 26f);
			GameObject item = tuple.Item1;
			Button item2 = tuple.Item2;
			Text eyeTxt = tuple.Item3;
			RectTransform component2 = item.GetComponent<RectTransform>();
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0f, 0.5f);
			component2.anchorMax = val2;
			component2.anchorMin = val2;
			component2.pivot = new Vector2(0f, 0.5f);
			component2.anchoredPosition = new Vector2(8f, 0f);
			component2.sizeDelta = new Vector2(26f, 26f);
			GameObject val3 = new GameObject("i");
			val3.transform.SetParent(item.transform, false);
			Image eyeImg = val3.AddComponent<Image>();
			((Graphic)eyeImg).raycastTarget = false;
			eyeImg.preserveAspect = true;
			RectTransform component3 = val3.GetComponent<RectTransform>();
			((Vector2)(ref val2))..ctor(0.5f, 0.5f);
			component3.anchorMax = val2;
			component3.anchorMin = val2;
			component3.pivot = new Vector2(0.5f, 0.5f);
			component3.sizeDelta = new Vector2(16f, 16f);
			GameObject val4 = new GameObject("swatch");
			val4.transform.SetParent(val.transform, false);
			Image swImg = val4.AddComponent<Image>();
			swImg.sprite = Theme.RoundedSprite();
			swImg.type = (Type)1;
			((Graphic)swImg).color = Preview.Hex(l.Tint, Color.white);
			Button obj = val4.AddComponent<Button>();
			((Selectable)obj).targetGraphic = (Graphic)(object)swImg;
			RectTransform component4 = val4.GetComponent<RectTransform>();
			component4.anchorMin = new Vector2(0f, 0.5f);
			component4.anchorMax = new Vector2(0f, 0.5f);
			component4.pivot = new Vector2(0f, 0.5f);
			component4.anchoredPosition = new Vector2(42f, 0f);
			component4.sizeDelta = new Vector2(24f, 24f);
			((UnityEvent)obj.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				ColorPicker.Show(_canvasGO.transform, "Layer tint", l.Tint, delegate(string newHex)
				{
					//IL_0013: Unknown result type (might be due to invalid IL or missing references)
					//IL_0018: Unknown result type (might be due to invalid IL or missing references)
					l.Tint = newHex;
					((Graphic)swImg).color = Preview.Hex(newHex, Color.white);
					MarkDirty();
				});
			}));
			Text t = UIFactory.Text("t", text, val.transform, 13, (TextAnchor)3, (FontStyle)0);
			((Graphic)t).raycastTarget = false;
			RectTransform rectTransform = ((Graphic)t).rectTransform;
			rectTransform.anchorMin = new Vector2(0f, 0f);
			rectTransform.anchorMax = new Vector2(1f, 1f);
			rectTransform.offsetMin = new Vector2(74f, 0f);
			rectTransform.offsetMax = new Vector2(-38f, 0f);
			var (val5, val6, val7) = UIFactory.ButtonWithLabel("rm", "✕", val.transform, Theme.Button, 26f, 26f);
			if ((Object)(object)val7 != (Object)null)
			{
				val7.fontSize = 13;
			}
			RectTransform component5 = val5.GetComponent<RectTransform>();
			component5.anchorMin = new Vector2(1f, 0.5f);
			component5.anchorMax = new Vector2(1f, 0.5f);
			component5.pivot = new Vector2(1f, 0.5f);
			component5.anchoredPosition = new Vector2(-8f, 0f);
			component5.sizeDelta = new Vector2(26f, 26f);
			((UnityEvent)val6.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				list.Remove(captured);
				RefreshForm();
				MarkDirty();
			}));
			RenderEye();
			((UnityEvent)item2.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
			{
				captured.Visible = !captured.Visible;
				RenderEye();
				MarkDirty();
			}));
			void RenderEye()
			{
				//IL_005a: 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_0110: Unknown result type (might be due to invalid IL or missing references)
				//IL_0109: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
				Sprite sprite = Icons.GetSprite(captured.Visible ? "eye" : "eye_off");
				if ((Object)(object)sprite != (Object)null)
				{
					((Behaviour)eyeImg).enabled = true;
					eyeImg.sprite = sprite;
					((Graphic)eyeImg).color = (captured.Visible ? Theme.TextPrimary : Theme.TextMuted);
					if ((Object)(object)eyeTxt != (Object)null)
					{
						eyeTxt.text = "";
					}
				}
				else if ((Object)(object)eyeTxt != (Object)null)
				{
					((Behaviour)eyeImg).enabled = false;
					eyeTxt.text = (captured.Visible ? "◉" : "○");
					eyeTxt.fontSize = 13;
					((Graphic)eyeTxt).color = (captured.Visible ? Theme.TextPrimary : Theme.TextMuted);
				}
				((Graphic)t).color = (captured.Visible ? Theme.TextPrimary : Theme.TextDisabled);
			}
		}

		private static void ImportLayerFlow(List<LayerDraft> list, string kindLabel)
		{
			string text = "Put a PNG in:\n" + Paths.Import + "\nthen enter its filename.";
			Components.PromptDialog(_canvasGO.transform, "Import PNG " + kindLabel, text, "grin.png", "Import", (Func<string, string>)delegate(string fileName)
			{
				if (string.IsNullOrWhiteSpace(fileName))
				{
					return "Enter a filename.";
				}
				string text2 = Path.Combine(Paths.Import, fileName.Trim());
				if (!File.Exists(text2))
				{
					return "Not found in the Import folder.";
				}
				string text3 = ProjectStore.ImportSource(_project, text2);
				if (text3 == null)
				{
					return "Import failed.";
				}
				list.Add(new LayerDraft
				{
					Source = text3,
					Tint = "#FFFFFF"
				});
				RefreshForm();
				MarkDirty();
				return (string)null;
			});
		}

		private static void ExportFlow()
		{
			ProjectStore.Save(_project);
			string text = Exporter.Validate(_project);
			if (text != null)
			{
				Toast.Show(text, (Severity)2);
				return;
			}
			ExportResult exportResult = Exporter.Export(_project);
			Toast.Show(exportResult.Message, (Severity)(exportResult.Ok ? 1 : 3));
			if (exportResult.Ok && !string.IsNullOrEmpty(exportResult.ExportDir))
			{
				RevealInExplorer(exportResult.ExportDir);
			}
		}

		private static void RevealInExplorer(string dir)
		{
			try
			{
				string text = null;
				try
				{
					string text2 = Path.Combine(dir, "manifest.json");
					if (File.Exists(text2))
					{
						text = text2;
					}
					else
					{
						string[] files = Directory.GetFiles(dir);
						if (files.Length != 0)
						{
							text = files[0];
						}
					}
				}
				catch
				{
				}
				ProcessStartInfo processStartInfo = new ProcessStartInfo
				{
					UseShellExecute = true
				};
				if (text != null)
				{
					processStartInfo.FileName = "explorer.exe";
					processStartInfo.Arguments = "/select,\"" + text + "\"";
				}
				else
				{
					processStartInfo.FileName = dir;
				}
				Process.Start(processStartInfo);
			}
			catch
			{
			}
		}

		private static void ExitToHub()
		{
			if (_ctx != null)
			{
				try
				{
					_ctx.ReturnToHub();
					return;
				}
				catch
				{
				}
			}
			Close();
		}
	}
	public sealed class ExportResult
	{
		public bool Ok;

		public string Message;

		public string ExportDir;
	}
	public static class Exporter
	{
		private sealed class PkManifest
		{
			public string name;

			public string author;

			public List<PkNpc> npcs = new List<PkNpc>();
		}

		private sealed class PkNpc
		{
			public string id;

			public string name;

			public PkAppear appearance;

			public PkBehav behavior;

			public Dictionary<string, object> extensions;
		}

		private sealed class PkEye
		{
			public float top;

			public float bottom;
		}

		private sealed class PkLayer
		{
			public string path;

			public string file;

			public string kind;

			public string tint;

			public string color;
		}

		private sealed class PkBehav
		{
			public float aggression;

			public float maxHealth;

			public float scale;

			public string conversation;
		}

		private sealed class PkAppear
		{
			public float gender;

			public float height;

			public float weight;

			public string skinColor;

			public string hairPath;

			public string hairColor;

			public float eyebrowScale;

			public float eyebrowThickness;

			public float eyebrowRestingHeight;

			public float eyebrowRestingAngle;

			public string leftEyeLidColor;

			public string rightEyeLidColor;

			public PkEye leftEye;

			public PkEye rightEye;

			public string eyeballMaterial;

			public string eyeBallTint;

			public float pupilDilation;

			public List<PkLayer> faceLayers;

			public List<PkLayer> bodyLayers;

			public List<PkLayer> accessories;
		}

		private sealed class TsManifest
		{
			public string name;

			public string version_number;

			public string website_url;

			public string description;

			public string[] dependencies;
		}

		private static readonly JsonSerializerSettings JsonSettings = new JsonSerializerSettings
		{
			Formatting = (Formatting)1,
			NullValueHandling = (NullValueHandling)1
		};

		public static string Validate(NpcProject project)
		{
			if (project == null)
			{
				return "No project.";
			}
			if (string.IsNullOrWhiteSpace(project.Name))
			{
				return "The pack needs a name.";
			}
			if (project.Npcs == null || project.Npcs.Count == 0)
			{
				return "Add at least one NPC.";
			}
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			foreach (NpcDraft npc in project.Npcs)
			{
				if (string.IsNullOrWhiteSpace(npc.Name))
				{
					return "Every NPC needs a name.";
				}
				string text = Ids.Make(project.Name, npc.Name);
				if (!hashSet.Add(text))
				{
					return "Two NPCs would get the same id '" + text + "' - give them unique names.";
				}
			}
			return null;
		}

		public static ExportResult Export(NpcProject project)
		{
			string text = Validate(project);
			if (text != null)
			{
				return new ExportResult
				{
					Ok = false,
					Message = text
				};
			}
			try
			{
				string text2 = Paths.Sanitize(project.Name);
				string text3 = Paths.ExportDir(project.Name);
				string text4 = Path.Combine(text3, "Personnel", "Packs", text2);
				Directory.CreateDirectory(text3);
				EmptyDirectory(text3);
				Directory.CreateDirectory(text4);
				PkManifest pkManifest = BuildPackManifest(project, text4);
				File.WriteAllText(Path.Combine(text4, "manifest.json"), JsonConvert.SerializeObject((object)pkManifest, JsonSettings));
				WriteThunderstoreManifest(project, text3);
				WriteReadme(project, text3, text2);
				WriteLicense(project, text3);
				CopyIconIfAny(project, text3);
				Instance log = Core.Log;
				if (log != null)
				{
					log.Msg($"[export] wrote pack '{text2}' ({project.Npcs.Count} NPC) -> {text3}");
				}
				return new ExportResult
				{
					Ok = true,
					ExportDir = text3,
					Message = $"Exported {project.Npcs.Count} NPC(s). Copy the 'Personnel/Packs/{text2}' folder into UserData/Personnel/Packs to test."
				};
			}
			catch (Exception ex)
			{
				Instance log2 = Core.Log;
				if (log2 != null)
				{
					log2.Warning("[export] failed: " + ex.Message);
				}
				return new ExportResult
				{
					Ok = false,
					Message = "Export failed: " + ex.Message
				};
			}
		}

		private static void EmptyDirectory(string dir)
		{
			try
			{
				string[] files = Directory.GetFiles(dir);
				foreach (string path in files)
				{
					try
					{
						File.Delete(path);
					}
					catch
					{
					}
				}
				files = Directory.GetDirectories(dir);
				foreach (string path2 in files)
				{
					try
					{
						Directory.Delete(path2, recursive: true);
					}
					catch
					{
					}
				}
			}
			catch
			{
			}
		}

		private static PkManifest BuildPackManifest(NpcProject project, string packDir)
		{
			PkManifest pkManifest = new PkManifest
			{
				name = project.Name,
				author = project.Author
			};
			HashSet<string> usedFiles = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			foreach (NpcDraft npc in project.Npcs)
			{
				AppearanceDraft appearanceDraft = npc.Appearance ?? new AppearanceDraft();
				PkAppear appearance = new PkAppear
				{
					gender = appearanceDraft.Gender,
					height = appearanceDraft.Height,
					weight = appearanceDraft.Weight,
					skinColor = appearanceDraft.SkinColor,
					hairPath = appearanceDraft.HairPath,
					hairColor = appearanceDraft.HairColor,
					eyebrowScale = appearanceDraft.EyebrowScale,
					eyebrowThickness = appearanceDraft.EyebrowThickness,
					eyebrowRestingHeight = appearanceDraft.EyebrowRestingHeight,
					eyebrowRestingAngle = appearanceDraft.EyebrowRestingAngle,
					leftEyeLidColor = appearanceDraft.LeftEyeLidColor,
					rightEyeLidColor = appearanceDraft.RightEyeLidColor,
					leftEye = new PkEye
					{
						top = appearanceDraft.LeftEyeTop,
						bottom = appearanceDraft.LeftEyeBottom
					},
					rightEye = new PkEye
					{
						top = appearanceDraft.RightEyeTop,
						bottom = appearanceDraft.RightEyeBottom
					},
					eyeballMaterial = appearanceDraft.EyeballMaterial,
					eyeBallTint = appearanceDraft.EyeBallTint,
					pupilDilation = appearanceDraft.PupilDilation,
					faceLayers = ExportLayers(project, appearanceDraft.FaceLayers, "face", packDir, usedFiles),
					bodyLayers = ExportLayers(project, appearanceDraft.BodyLayers, "body", packDir, usedFiles),
					accessories = ExportAccessories(appearanceDraft.Accessories)
				};
				PkNpc pkNpc = new PkNpc
				{
					id = Ids.Make(project.Name, npc.Name),
					name = npc.Name,
					appearance = appearance
				};
				if (npc.Behavior != null && npc.Behavior.Enabled)
				{
					pkNpc.behavior = new PkBehav
					{
						aggression = npc.Behavior.Aggression,
						maxHealth = npc.Behavior.MaxHealth,
						scale = npc.Behavior.Scale,
						conversation = npc.Behavior.Conversation
					};
				}
				if (npc.Backrooms != null && npc.Backrooms.Enabled)
				{
					BackroomsDraft backrooms = npc.Backrooms;
					pkNpc.extensions = new Dictionary<string, object> { ["backrooms"] = new Dictionary<string, object>
					{
						["archetype"] = backrooms.Archetype,
						["tierMin"] = backrooms.TierMin,
						["tierMax"] = backrooms.TierMax,
						["biomes"] = ParseBiomes(backrooms.Biomes),
						["weight"] = backrooms.Weight,
						["maxAlive"] = backrooms.MaxAlive,
						["hostile"] = backrooms.Hostile,
						["ambient"] = backrooms.Ambient,
						["spawnCooldown"] = backrooms.SpawnCooldown
					} };
				}
				pkManifest.npcs.Add(pkNpc);
			}
			return pkManifest;
		}

		private static List<PkLayer> ExportLayers(NpcProject project, List<LayerDraft> layers, string kind, string packDir, HashSet<string> usedFiles)
		{
			List<PkLayer> list = new List<PkLayer>();
			if (layers == null)
			{
				return list;
			}
			foreach (LayerDraft layer in layers)
			{
				if (layer == null || !layer.Visible)
				{
					continue;
				}
				if (!string.IsNullOrWhiteSpace(layer.Source))
				{
					string text = CopySource(project, layer.Source, packDir, usedFiles);
					if (text != null)
					{
						list.Add(new PkLayer
						{
							file = text,
							kind = kind,
							tint = layer.Tint
						});
					}
				}
				else if (!string.IsNullOrWhiteSpace(layer.Path))
				{
					list.Add(new PkLayer
					{
						path = layer.Path,
						tint = layer.Tint
					});
				}
			}
			return list;
		}

		private static List<PkLayer> ExportAccessories(List<LayerDraft> layers)
		{
			List<PkLayer> list = new List<PkLayer>();
			if (layers == null)
			{
				return list;
			}
			foreach (LayerDraft layer in layers)
			{
				if (layer != null && layer.Visible && !string.IsNullOrWhiteSpace(layer.Path))
				{
					list.Add(new PkLayer
					{
						path = layer.Path,
						color = layer.Tint
					});
				}
			}
			return list;
		}

		private static string CopySource(NpcProject project, string source, string packDir, HashSet<string> usedFiles)
		{
			try
			{
				string text = ProjectStore.ResolveRelative(project, source);
				if (text == null || !File.Exists(text))
				{
					return null;
				}
				string text2 = Path.GetFileName(text);
				int num = 1;
				while (!usedFiles.Add(text2))
				{
					text2 = Path.GetFileNameWithoutExtension(text) + "_" + num++ + Path.GetExtension(text);
				}
				File.Copy(text, Path.Combine(packDir, text2), overwrite: true);
				return text2;
			}
			catch (Exception ex)
			{
				Instance log = Core.Log;
				if (log != null)
				{
					log.Warning("[export] copy source failed: " + ex.Message);
				}
				return null;
			}
		}

		private static List<string> ParseBiomes(string csv)
		{
			List<string> list = new List<string>();
			if (string.IsNullOrWhiteSpace(csv))
			{
				return list;
			}
			string[] array = csv.Split(',');
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length > 0)
				{
					list.Add(text);
				}
			}
			return list;
		}

		private static void WriteThunderstoreManifest(NpcProject project, string exportRoot)
		{
			TsManifest tsManifest = new TsManifest();
			tsManifest.name = Paths.Sanitize(project.Name).Replace(' ', '_');
			tsManifest.version_number = NormalizeVersion(project.ModVersion);
			tsManifest.website_url = project.WebsiteUrl ?? "";
			tsManifest.description = Truncate(string.IsNullOrWhiteSpace(project.Description) ? "Custom NPCs for Schedule I, made with the Personify editor." : project.Description, 250);
			tsManifest.dependencies = new string[1] { "DooDesch-Personnel-" + PersonnelVersion() };
			TsManifest tsManifest2 = tsManifest;
			File.WriteAllText(Path.Combine(exportRoot, "manifest.json"), JsonConvert.SerializeObject((object)tsManifest2, JsonSettings));
		}

		private static void WriteReadme(NpcProject project, string exportRoot, string packName)
		{
			string contents = $"# {project.Name}\n\n{(string.IsNullOrWhiteSpace(project.Description) ? "Custom NPCs for Schedule I, made with the Personify editor." : project.Description)}\n\nMade with the **Personify** editor. Contains {project.Npcs.Count} NPC definition(s).\n\n## Install\nRequires the **Personnel** mod. Merge the `Personnel/Packs/{packName}` folder from this package into\n`UserData/Personnel/Packs/`. NPC-consuming mods (e.g. Backrooms) pick the definitions up automatically.\n\n## NPCs\n{NpcList(project)}\n\n## Note\nThunderstore requires a 256x256 `icon.png` in this folder before upload - add one if you plan to publish.\n";
			File.WriteAllText(Path.Combine(exportRoot, "README.md"), contents);
		}

		private static string NpcList(NpcProject project)
		{
			StringBuilder stringBuilder = new StringBuilder();
			foreach (NpcDraft npc in project.Npcs)
			{
				stringBuilder.AppendLine($"- **{npc.Name}** (`{npc.Id}`)" + ((npc.Backrooms != null && npc.Backrooms.Enabled) ? (" - Backrooms: " + npc.Backrooms.Archetype) : ""));
			}
			return stringBuilder.ToString();
		}

		private static void WriteLicense(NpcProject project, string exportRoot)
		{
			string text = (string.IsNullOrWhiteSpace(project.License) ? "All rights reserved" : project.License);
			File.WriteAllText(Path.Combine(exportRoot, "LICENSE"), text + Environment.NewLine);
		}

		private static void CopyIconIfAny(NpcProject project, string exportRoot)
		{
			try
			{
				if (!string.IsNullOrWhiteSpace(project.IconSource))
				{
					string text = ProjectStore.ResolveRelative(project, project.IconSource);
					if (text != null && File.Exists(text))
					{
						File.Copy(text, Path.Combine(exportRoot, "icon.png"), overwrite: true);
					}
				}
			}
			catch (Exception ex)
			{
				Instance log = Core.Log;
				if (log != null)
				{
					log.Warning("[export] icon copy failed: " + ex.Message);
				}
			}
		}

		private static string PersonnelVersion()
		{
			try
			{
				if (typeof(MelonBase).GetProperty("RegisteredMelons", BindingFlags.Static | BindingFlags.Public)?.GetValue(null) is IEnumerable enumerable)
				{
					foreach (object item in enumerable)
					{
						object obj = item?.GetType().GetProperty("Info")?.GetValue(item);
						if (obj?.GetType().GetProperty("Name")?.GetValue(obj) as string == "Personnel")
						{
							return (obj.GetType().GetProperty("Version")?.GetValue(obj) as string) ?? "1.0.0";
						}
					}
				}
			}
			catch
			{
			}
			return "1.0.0";
		}

		private static string NormalizeVersion(string v)
		{
			if (string.IsNullOrWhiteSpace(v))
			{
				return "1.0.0";
			}
			string[] array = v.Split('.');
			if (array.Length >= 3)
			{
				return v;
			}
			return string.Concat(v, string.Concat(Enumerable.Repeat(".0", 3 - array.Length)));
		}

		private static string Truncate(string s, int max)
		{
			if (!string.IsNullOrEmpty(s) && s.Length > max)
			{
				return s.Substring(0, max);
			}
			return s;
		}
	}
	public static class Icons
	{
		private static readonly Dictionary<string, Texture2D> _tex = new Dictionary<string, Texture2D>();

		private static readonly Dictionary<string, Sprite> _sprites = new Dictionary<string, Sprite>();

		public static Sprite GetSprite(string name)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			if (_sprites.TryGetValue(name, out var value))
			{
				return value;
			}
			Texture2D texture = GetTexture(name);
			Sprite val = (((Object)(object)texture != (Object)null) ? Sprite.Create(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), new Vector2(0.5f, 0.5f), 100f) : null);
			if ((Object)(object)val != (Object)null)
			{
				((Object)val).hideFlags = (HideFlags)32;
			}
			_sprites[name] = val;
			return val;
		}

		private static Texture2D GetTexture(string name)
		{
			if (_tex.TryGetValue(name, out var value))
			{
				return value;
			}
			Texture2D val = null;
			try
			{
				Assembly executingAssembly = Assembly.GetExecutingAssembly();
				string text = "Personify.Assets.Icons." + name + ".png";
				using Stream stream = executingAssembly.GetManifestResourceStream(text);
				if (stream != null)
				{
					byte[] array = new byte[stream.Length];
					stream.Read(array, 0, array.Length);
					val = TextureUtils.LoadTextureFromBytes(array, (FilterMode)1, (TextureWrapMode)1);
					if ((Object)(object)val != (Object)null)
					{
						((Texture)val).filterMode = (FilterMode)1;
						((Object)val).hideFlags = (HideFlags)32;
					}
				}
				else
				{
					Instance log = Core.Log;
					if (log != null)
					{
						log.Warning("[icon] missing resource: " + text);
					}
				}
			}
			catch (Exception ex)
			{
				Instance log2 = Core.Log;
				if (log2 != null)
				{
					log2.Warning("[icon] '" + na