Decompiled source of CustomClanUIFixes v0.5.1

mt2_custom_clan_ui_fixes.Plugin.dll

Decompiled an hour ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using I2.Loc;
using Microsoft.CodeAnalysis;
using ShinyShoe;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("mt2_custom_clan_ui_fixes.Plugin")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.5.1.0")]
[assembly: AssemblyInformationalVersion("0.5.1+250937ca4bdc7f184b06d1ae3baf4d2959f5fc35")]
[assembly: AssemblyProduct("mt2_custom_clan_ui_fixes.Plugin")]
[assembly: AssemblyTitle("mt2_custom_clan_ui_fixes.Plugin")]
[assembly: AssemblyVersion("0.5.1.0")]
[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.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[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 mt2_custom_clan_ui_fixes.Plugin
{
	[HarmonyPatch]
	public static class CardFilterSearch
	{
		public static bool Enabled = true;

		public static bool Verbose = false;

		public static bool DumpTree = false;

		public static bool AlsoInside = false;

		public static float MinOverlap = 0.25f;

		public static int Levels = 1;

		private static readonly FieldInfo? FCampo = AccessTools.Field(typeof(SearchFilterUI), "inputField");

		private static readonly FieldInfo? FBoton = AccessTools.Field(typeof(SearchFilterUI), "clearButton");

		private static readonly HashSet<string> Dibujan = new HashSet<string> { "Image", "RawImage" };

		private static bool volcado;

		private static bool avisado;

		private static int apagados;

		[HarmonyPatch(typeof(SearchFilterUI), "SetUp")]
		[HarmonyPostfix]
		private static void TrasMontar(SearchFilterUI __instance)
		{
			if (!Enabled || (Object)(object)__instance == (Object)null)
			{
				return;
			}
			try
			{
				VigiaBusqueda vigiaBusqueda = ((Component)__instance).GetComponent<VigiaBusqueda>();
				if ((Object)(object)vigiaBusqueda == (Object)null)
				{
					vigiaBusqueda = ((Component)__instance).gameObject.AddComponent<VigiaBusqueda>();
				}
				vigiaBusqueda.ui = __instance;
				if (((Behaviour)__instance).isActiveAndEnabled)
				{
					vigiaBusqueda.Arrancar();
				}
			}
			catch (Exception ex)
			{
				Log("no se pudo colgar el vigilante del panel: " + ex.Message, aviso: true);
			}
		}

		internal static IEnumerator AjustarUnosFrames(SearchFilterUI ui)
		{
			for (int i = 1; i <= 20; i++)
			{
				yield return null;
				if ((Object)(object)ui == (Object)null)
				{
					break;
				}
				if (i <= 3 || i == 10 || i == 20)
				{
					Ajustar(ui, i == 20);
				}
			}
		}

		private static void Ajustar(SearchFilterUI ui, bool ultima)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: 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)
			try
			{
				object? obj = FCampo?.GetValue(ui);
				Component val = (Component)((obj is Component) ? obj : null);
				if (val == null || (Object)(object)val == (Object)null)
				{
					return;
				}
				Transform transform = val.transform;
				RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				if (val2 == null)
				{
					return;
				}
				Transform val3 = ((Component)ui).transform;
				for (int i = 0; i < Levels; i++)
				{
					if (!((Object)(object)val3.parent != (Object)null))
					{
						break;
					}
					val3 = val3.parent;
				}
				Rect caja = Caja(val3, val2);
				if (((Rect)(ref caja)).height <= 1f)
				{
					return;
				}
				if (DumpTree && !volcado)
				{
					volcado = true;
					Volcar(val3, val2);
				}
				object? obj2 = FBoton?.GetValue(ui);
				object? obj3 = ((obj2 is Component) ? obj2 : null);
				Transform val4 = ((obj3 != null) ? ((Component)obj3).transform : null);
				int num = 0;
				foreach (Transform item in Descendientes(val3))
				{
					if ((Object)(object)item == (Object)null || (Object)(object)item == (Object)(object)val2)
					{
						continue;
					}
					RectTransform val5 = (RectTransform)(object)((item is RectTransform) ? item : null);
					if (val5 == null || !((Component)item).gameObject.activeInHierarchy || (!AlsoInside && EsDescendiente(item, ((Component)ui).transform)) || ((Object)(object)val4 != (Object)null && EsDescendiente(item, val4)) || EsAscendiente(item, (Transform)(object)val2))
					{
						continue;
					}
					Rect otra = Caja(val3, val5);
					if (!Cruza(caja, otra))
					{
						continue;
					}
					Component[] components = ((Component)item).GetComponents<Component>();
					foreach (Component val6 in components)
					{
						if (!((Object)(object)val6 == (Object)null) && Dibujan.Contains(((object)val6).GetType().Name))
						{
							Behaviour val7 = (Behaviour)(object)((val6 is Behaviour) ? val6 : null);
							if (val7 != null && val7.enabled)
							{
								val7.enabled = false;
								num++;
								apagados++;
								Log("adorno sobre la caja de busqueda: \"" + Ruta(item, val3) + "\"" + $" {((Rect)(ref otra)).width:0}x{((Rect)(ref otra)).height:0} ({((object)val6).GetType().Name}) -> apagado" + $" [caja {((Rect)(ref caja)).width:0}x{((Rect)(ref caja)).height:0}]");
							}
						}
					}
				}
				if (apagados == 0 && ultima && !avisado)
				{
					avisado = true;
					Log("no se ha encontrado nada que tape la caja de busqueda" + (AlsoInside ? "." : ": solo se ha mirado FUERA del SearchFilterUI. Prueba [CardFilter] AlsoInside = true, o sube Levels."));
				}
			}
			catch (Exception ex)
			{
				Log("fallo despejando la caja de busqueda: " + ex.Message, aviso: true);
			}
		}

		private static bool Cruza(Rect caja, Rect otra)
		{
			if (((Rect)(ref otra)).height > ((Rect)(ref caja)).height * 2f)
			{
				return false;
			}
			float num = Mathf.Min(((Rect)(ref caja)).yMax, ((Rect)(ref otra)).yMax) - Mathf.Max(((Rect)(ref caja)).yMin, ((Rect)(ref otra)).yMin);
			float num2 = Mathf.Min(((Rect)(ref caja)).xMax, ((Rect)(ref otra)).xMax) - Mathf.Max(((Rect)(ref caja)).xMin, ((Rect)(ref otra)).xMin);
			if (num <= 0f || num2 <= 0f)
			{
				return false;
			}
			if (num >= ((Rect)(ref caja)).height * MinOverlap)
			{
				if (!(num2 >= ((Rect)(ref caja)).width * 0.3f))
				{
					return num2 >= ((Rect)(ref otra)).width * 0.5f;
				}
				return true;
			}
			return false;
		}

		private static Rect Caja(Transform referencia, RectTransform t)
		{
			//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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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)
			Vector3[] array = (Vector3[])(object)new Vector3[4];
			t.GetWorldCorners(array);
			Vector3 val = referencia.InverseTransformPoint(array[0]);
			Vector3 val2 = referencia.InverseTransformPoint(array[2]);
			return Rect.MinMaxRect(Mathf.Min(val.x, val2.x), Mathf.Min(val.y, val2.y), Mathf.Max(val.x, val2.x), Mathf.Max(val.y, val2.y));
		}

		private static IEnumerable<Transform> Descendientes(Transform raiz)
		{
			foreach (Transform item in raiz)
			{
				Transform h = item;
				yield return h;
				foreach (Transform item2 in Descendientes(h))
				{
					yield return item2;
				}
			}
		}

		private static bool EsDescendiente(Transform t, Transform raiz)
		{
			Transform val = t;
			while ((Object)(object)val != (Object)null)
			{
				if ((Object)(object)val == (Object)(object)raiz)
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}

		private static bool EsAscendiente(Transform t, Transform hijo)
		{
			Transform val = hijo;
			while ((Object)(object)val != (Object)null)
			{
				if ((Object)(object)val == (Object)(object)t)
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}

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

		private static void Volcar(Transform raiz, RectTransform campo)
		{
			try
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append("arbol del panel de filtros desde \"").Append(((Object)raiz).name).Append("\":\n");
				Rama(stringBuilder, raiz, raiz, campo, 0);
				Plugin.Logger.LogInfo((object)("[CardFilter] " + stringBuilder));
			}
			catch (Exception ex)
			{
				Log("no se pudo volcar el arbol: " + ex.Message, aviso: true);
			}
		}

		private static void Rama(StringBuilder sb, Transform t, Transform raiz, RectTransform campo, int nivel)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Expected O, but got Unknown
			if (nivel > 8)
			{
				return;
			}
			sb.Append(' ', nivel * 2).Append(((Object)(object)t == (Object)(object)campo) ? "* " : "- ").Append(((Object)t).name);
			RectTransform val = (RectTransform)(object)((t is RectTransform) ? t : null);
			if (val != null)
			{
				Rect rect = val.rect;
				object arg = ((Rect)(ref rect)).width;
				rect = val.rect;
				sb.Append($" {arg:0}x{((Rect)(ref rect)).height:0}");
			}
			if (!((Component)t).gameObject.activeSelf)
			{
				sb.Append(" (apagado)");
			}
			List<string> list = new List<string>();
			Component[] components = ((Component)t).GetComponents<Component>();
			foreach (Component val2 in components)
			{
				if ((Object)(object)val2 != (Object)null)
				{
					list.Add(((object)val2).GetType().Name);
				}
			}
			if (list.Count > 0)
			{
				sb.Append("  [").Append(string.Join(", ", list)).Append(']');
			}
			sb.Append('\n');
			foreach (Transform item in t)
			{
				Transform t2 = item;
				Rama(sb, t2, raiz, campo, nivel + 1);
			}
		}

		private static void Log(string mensaje, bool aviso = false)
		{
			if (aviso)
			{
				Plugin.Logger.LogWarning((object)("[CardFilter] " + mensaje));
			}
			else if (Verbose)
			{
				Plugin.Logger.LogInfo((object)("[CardFilter] " + mensaje));
			}
		}
	}
	internal sealed class VigiaBusqueda : MonoBehaviour
	{
		internal SearchFilterUI? ui;

		private void OnEnable()
		{
			Arrancar();
		}

		internal void Arrancar()
		{
			if (!((Object)(object)ui == (Object)null) && CardFilterSearch.Enabled && ((Behaviour)this).isActiveAndEnabled)
			{
				((MonoBehaviour)this).StartCoroutine(CardFilterSearch.AjustarUnosFrames(ui));
			}
		}
	}
	[DataContract]
	public sealed class CardUsageEntry
	{
		[DataMember(Name = "cardId")]
		public string? CardId;

		[DataMember(Name = "mode")]
		public string? Mode;

		[DataMember(Name = "direct")]
		public long Direct;

		[DataMember(Name = "automatic")]
		public long Automatic;
	}
	[DataContract]
	public sealed class CardUsageFile
	{
		[DataMember(Name = "version")]
		public int Version;

		[DataMember(Name = "startedUtc")]
		public string? StartedUtc;

		[DataMember(Name = "entries")]
		public List<CardUsageEntry>? Entries;
	}
	public sealed class CardUsageStore
	{
		private readonly Dictionary<(string Card, string Mode), (long Direct, long Automatic)> counts = new Dictionary<(string, string), (long, long)>();

		private readonly string path;

		private DateTime? lastWrite;

		public string StartedUtc { get; private set; }

		private CardUsageStore(string file)
		{
			path = file;
			StartedUtc = DateTime.UtcNow.ToString("O");
		}

		public static CardUsageStore Open(string file)
		{
			CardUsageStore cardUsageStore = new CardUsageStore(file);
			if (!File.Exists(file))
			{
				return cardUsageStore;
			}
			cardUsageStore.lastWrite = File.GetLastWriteTimeUtc(file);
			string s;
			using (StreamReader streamReader = new StreamReader(file, Encoding.UTF8, detectEncodingFromByteOrderMarks: true))
			{
				s = streamReader.ReadToEnd();
			}
			using MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(s));
			if (!(new DataContractJsonSerializer(typeof(CardUsageFile)).ReadObject(stream) is CardUsageFile { Version: 1, Entries: not null } cardUsageFile) || !DateTimeOffset.TryParse(cardUsageFile.StartedUtc, out var _))
			{
				throw new InvalidDataException("Unsupported or incomplete card usage file.");
			}
			cardUsageStore.StartedUtc = cardUsageFile.StartedUtc;
			foreach (CardUsageEntry entry in cardUsageFile.Entries)
			{
				if (entry == null || string.IsNullOrWhiteSpace(entry.CardId) || string.IsNullOrWhiteSpace(entry.Mode) || entry.Direct < 0 || entry.Automatic < 0 || cardUsageStore.counts.ContainsKey((entry.CardId, entry.Mode)))
				{
					throw new InvalidDataException("Invalid or duplicate card usage entry.");
				}
				cardUsageStore.counts[(entry.CardId, entry.Mode)] = (entry.Direct, entry.Automatic);
			}
			cardUsageStore.CheckUnchanged();
			return cardUsageStore;
		}

		private void CheckUnchanged()
		{
			if ((File.Exists(path) ? new DateTime?(File.GetLastWriteTimeUtc(path)) : ((DateTime?)null)) != lastWrite)
			{
				throw new IOException("Card usage file changed externally; refusing overwrite.");
			}
		}

		public (long Direct, long Automatic) Get(string card, string? mode = null)
		{
			long num = 0L;
			long num2 = 0L;
			checked
			{
				foreach (KeyValuePair<(string, string), (long, long)> count in counts)
				{
					if (count.Key.Item1 == card && (mode == null || count.Key.Item2 == mode))
					{
						num += count.Value.Item1;
						num2 += count.Value.Item2;
					}
				}
				return (Direct: num, Automatic: num2);
			}
		}

		public List<CardUsageEntry> Snapshot()
		{
			return counts.Select<KeyValuePair<(string, string), (long, long)>, CardUsageEntry>((KeyValuePair<(string Card, string Mode), (long Direct, long Automatic)> c) => new CardUsageEntry
			{
				CardId = c.Key.Card,
				Mode = c.Key.Mode,
				Direct = c.Value.Direct,
				Automatic = c.Value.Automatic
			}).ToList();
		}

		public void Record(string card, string mode, bool direct)
		{
			if (string.IsNullOrWhiteSpace(card) || string.IsNullOrWhiteSpace(mode))
			{
				throw new ArgumentException("Missing card ID or mode.");
			}
			(string, string) key = (card, mode);
			(long, long) value;
			bool flag = counts.TryGetValue(key, out value);
			counts[key] = checked(direct ? (value.Item1 + 1, value.Item2) : (value.Item1, value.Item2 + 1));
			try
			{
				Save();
			}
			catch
			{
				if (flag)
				{
					counts[key] = value;
				}
				else
				{
					counts.Remove(key);
				}
				throw;
			}
		}

		private void Save()
		{
			CheckUnchanged();
			CardUsageFile graph = new CardUsageFile
			{
				Version = 1,
				StartedUtc = StartedUtc,
				Entries = (from c in counts.OrderBy<KeyValuePair<(string, string), (long, long)>, string>((KeyValuePair<(string Card, string Mode), (long Direct, long Automatic)> c) => c.Key.Card, StringComparer.Ordinal).ThenBy<KeyValuePair<(string, string), (long, long)>, string>((KeyValuePair<(string Card, string Mode), (long Direct, long Automatic)> c) => c.Key.Mode, StringComparer.Ordinal)
					select new CardUsageEntry
					{
						CardId = c.Key.Card,
						Mode = c.Key.Mode,
						Direct = c.Value.Direct,
						Automatic = c.Value.Automatic
					}).ToList()
			};
			Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(path)));
			string sourceFileName = path + "." + Guid.NewGuid().ToString("N") + ".tmp";
			try
			{
				using (FileStream fileStream = new FileStream(sourceFileName, FileMode.CreateNew, FileAccess.Write, FileShare.None))
				{
					byte[] preamble = Encoding.UTF8.GetPreamble();
					fileStream.Write(preamble, 0, preamble.Length);
					new DataContractJsonSerializer(typeof(CardUsageFile)).WriteObject(fileStream, graph);
					fileStream.Flush(flushToDisk: true);
				}
				CheckUnchanged();
				if (File.Exists(path))
				{
					File.Replace(sourceFileName, path, path + ".bak");
				}
				else
				{
					File.Move(sourceFileName, path);
				}
				lastWrite = File.GetLastWriteTimeUtc(path);
			}
			finally
			{
				if (File.Exists(sourceFileName))
				{
					File.Delete(sourceFileName);
				}
			}
		}
	}
	internal static class CardUsageText
	{
		private static readonly Dictionary<string, string[]> ExtraTerms = new Dictionary<string, string[]>
		{
			["en"] = new string[11]
			{
				"Pending allies", "All allies completed", "All combinations", "Without a win", "Next allies", "Card plays", "Direct", "Automatic", "Counts start when tracking is installed. Replays are excluded; actual plays before undo or restart remain counted.", "Normal mode",
				"Clans"
			},
			["es"] = new string[11]
			{
				"Aliados pendientes", "Todos los aliados completados", "Todas las combinaciones", "Sin victoria", "Siguientes aliados", "Cartas jugadas", "Directas", "Automáticas", "El recuento empieza al instalar el seguimiento. Excluye replays; las jugadas reales antes de deshacer o reiniciar siguen contadas.", "Modo normal",
				"Clanes"
			},
			["fr"] = new string[11]
			{
				"Alliés restants", "Tous les alliés terminés", "Toutes les combinaisons", "Sans victoire", "Alliés suivants", "Cartes jouées", "Directes", "Automatiques", "Le comptage commence à l’installation. Les replays sont exclus ; les actions jouées avant annulation ou redémarrage restent comptées.", "Mode normal",
				"Clans"
			},
			["de"] = new string[11]
			{
				"Fehlende Verbündete", "Alle Verbündeten abgeschlossen", "Alle Kombinationen", "Ohne Sieg", "Nächste Verbündete", "Gespielte Karten", "Direkt", "Automatisch", "Zählung ab Installation. Replays sind ausgeschlossen; tatsächliche Spiele vor Rücknahme oder Neustart bleiben gezählt.", "Normaler Modus",
				"Clans"
			},
			["it"] = new string[11]
			{
				"Alleati mancanti", "Tutti gli alleati completati", "Tutte le combinazioni", "Senza vittoria", "Alleati successivi", "Carte giocate", "Dirette", "Automatiche", "Il conteggio inizia all’installazione. Esclude i replay; le giocate prima di annullare o riavviare restano contate.", "Modalità normale",
				"Clan"
			},
			["pt"] = new string[11]
			{
				"Aliados pendentes", "Todos os aliados completos", "Todas as combinações", "Sem vitória", "Próximos aliados", "Cartas jogadas", "Diretas", "Automáticas", "Contagem a partir da instalação. Replays excluídos; jogadas antes de desfazer ou reiniciar continuam contadas.", "Modo normal",
				"Clãs"
			},
			["pl"] = new string[11]
			{
				"Pozostali sojusznicy", "Wszyscy sojusznicy ukończeni", "Wszystkie kombinacje", "Bez zwycięstwa", "Następni sojusznicy", "Zagrane karty", "Bezpośrednie", "Automatyczne", "Liczenie od instalacji. Powtórki są wykluczone; zagrania przed cofnięciem lub restartem pozostają policzone.", "Tryb normalny",
				"Klany"
			},
			["ru"] = new string[11]
			{
				"Оставшиеся союзники", "Все союзники пройдены", "Все сочетания", "Без победы", "Следующие союзники", "Сыгранные карты", "Прямые", "Автоматические", "Подсчёт с момента установки. Повторы исключены; реальные действия до отмены или перезапуска сохраняются.", "Обычный режим",
				"Кланы"
			},
			["ja"] = new string[11]
			{
				"未達成の同盟", "すべての同盟を達成", "すべての組み合わせ", "勝利なし", "次の同盟", "カード使用回数", "直接", "自動", "導入後から集計します。リプレイを除外し、取り消しや再起動前の実際の使用は残ります。", "通常モード",
				"クラン"
			},
			["ko"] = new string[11]
			{
				"남은 동맹", "모든 동맹 완료", "모든 조합", "승리 없음", "다음 동맹", "카드 사용 횟수", "직접", "자동", "설치 후 집계합니다. 리플레이는 제외하며 취소나 재시작 전 실제 사용은 유지합니다.", "일반 모드",
				"클랜"
			},
			["zh"] = new string[11]
			{
				"待完成盟友", "所有盟友已完成", "所有组合", "无胜利", "下一组盟友", "卡牌使用次数", "直接", "自动", "从安装时开始计数。排除重放;撤销或重启前的实际使用仍计入。", "普通模式",
				"氏族"
			},
			["zh-hant"] = new string[11]
			{
				"待完成盟友", "所有盟友已完成", "所有組合", "無勝利", "下一組盟友", "卡牌使用次數", "直接", "自動", "從安裝時開始計數。排除重播;撤銷或重啟前的實際使用仍計入。", "普通模式",
				"氏族"
			}
		};

		internal static string Extra(string key)
		{
			int num = Array.IndexOf(new string[11]
			{
				"Pending", "Complete", "All", "Missing", "Next", "Plays", "Direct", "Automatic", "UsageNote", "Normal",
				"Clans"
			}, key);
			string text = (LocalizationManager.CurrentLanguageCode ?? "en").ToLowerInvariant().Replace('_', '-');
			text = ((text.StartsWith("zh-tw") || text.StartsWith("zh-hk") || text.StartsWith("zh-hant")) ? "zh-hant" : text.Split('-')[0]);
			string[] value;
			return (string)((object[])(ExtraTerms.TryGetValue(text, out value) ? ((object)value) : ((object)ExtraTerms["en"])))[num];
		}
	}
	[HarmonyPatch]
	public static class CardUsageTracker
	{
		public static bool Enabled = true;

		internal static readonly string SavePath = Path.Combine(Paths.ConfigPath, "CustomClanUIFixes", "card-usage.json");

		private static CardUsageStore? store;

		private static bool unavailable;

		internal static CardUsageStore? Store
		{
			get
			{
				if (!Enabled || unavailable)
				{
					return null;
				}
				try
				{
					return store ?? (store = CardUsageStore.Open(SavePath));
				}
				catch (Exception ex)
				{
					unavailable = true;
					Plugin.Logger.LogWarning((object)("[CardUsage] File preserved; tracking unavailable: " + ex));
					return null;
				}
			}
		}

		[HarmonyPatch(typeof(CardManager), "OnCardPlayed")]
		[HarmonyPostfix]
		private static void WrapPlay(ref IEnumerator __result, CardState playCard, bool fromDirectPlay, SaveManager ___saveManager, AllGameManagers ___allGameManagers)
		{
			if (Enabled)
			{
				__result = Track(__result, playCard, fromDirectPlay, ___saveManager, ___allGameManagers);
			}
		}

		private static IEnumerator Track(IEnumerator original, CardState card, bool direct, SaveManager save, AllGameManagers managers)
		{
			bool started = false;
			try
			{
				while (original.MoveNext())
				{
					if (!started)
					{
						started = true;
						Count(card, direct, save, managers);
					}
					yield return original.Current;
				}
				if (!started)
				{
					Count(card, direct, save, managers);
				}
			}
			finally
			{
				(original as IDisposable)?.Dispose();
			}
		}

		private static void Count(CardState card, bool direct, SaveManager save, AllGameManagers managers)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between Unknown and I4
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Invalid comparison between Unknown and I4
			//IL_003c: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				ReplayManager val = ((managers != null) ? managers.GetReplayManager() : null);
				if (card != null && !card.IsAnyAbility() && !((Object)(object)save == (Object)null) && !save.PreviewMode && (int)save.GetRunType() != -1 && (int)save.GetRunType() != 4 && (int)save.UndoMode == 0 && !((Object)(object)val == (Object)null) && !val.IsPlayingBackAReplay())
				{
					Store?.Record(card.GetCardDataID(), ((object)save.GetRunType()/*cast due to .constrained prefix*/).ToString(), direct);
				}
			}
			catch (Exception ex)
			{
				unavailable = true;
				Plugin.Logger.LogWarning((object)("[CardUsage] Tracking stopped; existing file preserved: " + ex));
			}
		}

		[HarmonyPatch(typeof(CardTooltipContainer), "AddTooltipsForCardState")]
		[HarmonyPostfix]
		private static void AddUsage(CardTooltipContainer __instance, CardState cardState)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			if (!Enabled || cardState == null || cardState.IsAnyAbility())
			{
				return;
			}
			checked
			{
				try
				{
					CardUsageStore cardUsageStore = Store;
					if (cardUsageStore != null)
					{
						(long, long) tuple = cardUsageStore.Get(cardState.GetCardDataID());
						(long, long) tuple2 = cardUsageStore.Get(cardState.GetCardDataID(), ((object)(RunType)1/*cast due to .constrained prefix*/).ToString());
						(long, long) tuple3 = cardUsageStore.Get(cardState.GetCardDataID(), ((object)(RunType)6/*cast due to .constrained prefix*/).ToString());
						string text = CardUsageText.Extra("Direct") + ": " + tuple.Item1 + "\n" + CardUsageText.Extra("Automatic") + ": " + tuple.Item2 + "\n" + CardUsageText.Extra("Normal") + ": " + (tuple2.Item1 + tuple2.Item2) + "\nSoul Savior: " + (tuple3.Item1 + tuple3.Item2) + "\n\n" + CardUsageText.Extra("UsageNote");
						((TooltipContainer)__instance).ShowTooltip(new TooltipContent(CardUsageText.Extra("Plays") + ": " + (tuple.Item1 + tuple.Item2), text, (TooltipDesignType)3, "CustomClanUIFixes.CardUsage", false, false), true, false);
					}
				}
				catch (Exception ex)
				{
					Plugin.Logger.LogWarning((object)("[CardUsage] Tooltip unavailable: " + ex.Message));
				}
			}
		}
	}
	[HarmonyPatch]
	public static class LogbookArtifactsPaging
	{
		public static bool Enabled = true;

		public static int ColumnsPerPage = 0;

		public static bool Balance = true;

		public static float WidthBudget = 0f;

		public static int RetryFrames = 10;

		public static bool Verbose = true;

		private static readonly FieldInfo? FColecciones = AccessTools.Field(typeof(CompendiumSectionBlessings), "collectionUIs");

		private static readonly FieldInfo? FPantalla = AccessTools.Field(typeof(CompendiumSection), "compendiumScreen");

		private static readonly MethodInfo? MRefrescarFlechas = AccessTools.Method(typeof(CompendiumScreen), "RefreshPageTurnZones", (Type[])null, (Type[])null);

		private static readonly List<List<int>> paginas = new List<List<int>>();

		private static int pagina;

		private static readonly List<float> anchos = new List<float>();

		private static readonly List<float> previas = new List<float>();

		private static bool medidasEstables;

		private static bool zonaTrazada;

		private static bool contenedorTrazado;

		private static int ultimoTotal = -1;

		private static int ultimasPaginas = -1;

		private static int ultimaPagina = -1;

		[HarmonyPatch(typeof(CompendiumSectionBlessings), "InitializeImpl")]
		[HarmonyPostfix]
		private static void TrasInicializar(CompendiumSectionBlessings __instance)
		{
			anchos.Clear();
			previas.Clear();
			medidasEstables = false;
			paginas.Clear();
			pagina = 0;
			Lanzar(__instance);
		}

		[HarmonyPatch(typeof(CompendiumSection), "Open")]
		[HarmonyPostfix]
		private static void TrasAbrir(CompendiumSection __instance)
		{
			CompendiumSectionBlessings val = (CompendiumSectionBlessings)(object)((__instance is CompendiumSectionBlessings) ? __instance : null);
			if (val != null)
			{
				pagina = 0;
				Lanzar(val);
			}
		}

		[HarmonyPatch(typeof(CompendiumSection), "CanTurnPage")]
		[HarmonyPrefix]
		private static bool AntesDePoderPasar(CompendiumSection __instance, TurnDir dir, ref bool __result)
		{
			//IL_0016: 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_0019: Expected I4, but got Unknown
			if (!Enabled || !(__instance is CompendiumSectionBlessings))
			{
				return true;
			}
			int num = pagina + dir;
			__result = paginas.Count > 1 && num >= 0 && num < paginas.Count;
			return false;
		}

		[HarmonyPatch(typeof(CompendiumSection), "TurnPage")]
		[HarmonyPrefix]
		private static bool AntesDePasar(CompendiumSection __instance, int dir)
		{
			if (Enabled)
			{
				CompendiumSectionBlessings val = (CompendiumSectionBlessings)(object)((__instance is CompendiumSectionBlessings) ? __instance : null);
				if (val != null)
				{
					if (paginas.Count <= 1)
					{
						return false;
					}
					int num = Mathf.Clamp(pagina + dir, 0, paginas.Count - 1);
					if (num != pagina)
					{
						pagina = num;
						Pintar(val);
					}
					return false;
				}
			}
			return true;
		}

		private static void Lanzar(CompendiumSectionBlessings seccion)
		{
			if (!Enabled || (Object)(object)seccion == (Object)null)
			{
				return;
			}
			Repartir(seccion);
			if (!((Behaviour)seccion).isActiveAndEnabled)
			{
				return;
			}
			try
			{
				((MonoBehaviour)seccion).StartCoroutine(RepartirUnosFrames(seccion));
			}
			catch (Exception ex)
			{
				Log("no se pudo encolar el reintento: " + ex.Message, aviso: true);
			}
		}

		private static IEnumerator RepartirUnosFrames(CompendiumSectionBlessings seccion)
		{
			for (int i = 0; i < Mathf.Max(1, RetryFrames); i++)
			{
				yield return null;
				if ((Object)(object)seccion == (Object)null || !((Behaviour)seccion).isActiveAndEnabled)
				{
					break;
				}
				Repartir(seccion);
			}
		}

		private static void Repartir(CompendiumSectionBlessings seccion)
		{
			try
			{
				List<RectTransform> list = Columnas(seccion);
				if (list.Count == 0)
				{
					return;
				}
				Transform parent = ((Transform)list[0]).parent;
				RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
				if (val == null)
				{
					return;
				}
				if (!medidasEstables || anchos.Count != list.Count)
				{
					bool flag = true;
					foreach (RectTransform item in list)
					{
						if (!((Component)item).gameObject.activeSelf)
						{
							((Component)item).gameObject.SetActive(true);
							flag = false;
						}
					}
					if (!flag || !Medir(list))
					{
						return;
					}
				}
				TrazarContenedor(val);
				float num = AnchoUtil(val) - PaddingHorizontal((Transform)(object)val);
				if (!(num <= 1f))
				{
					List<List<int>> collection = ((ColumnsPerPage > 0) ? PorNumeroFijo(list.Count, ColumnsPerPage) : (Balance ? Equilibrado(num) : Llenando(num)));
					paginas.Clear();
					paginas.AddRange(collection);
					pagina = Mathf.Clamp(pagina, 0, paginas.Count - 1);
					Pintar(seccion);
				}
			}
			catch (Exception ex)
			{
				Log("fallo repartiendo la pagina: " + ex, aviso: true);
			}
		}

		private static List<List<int>> Equilibrado(float presupuesto)
		{
			int count = Llenando(presupuesto).Count;
			if (count <= 1)
			{
				return Llenando(presupuesto);
			}
			float num = 0f;
			foreach (float ancho in anchos)
			{
				num = Mathf.Max(num, ancho);
			}
			float num2 = num;
			float num3 = presupuesto;
			for (int i = 0; i < 30; i++)
			{
				if (!(num3 - num2 > 0.5f))
				{
					break;
				}
				float num4 = (num2 + num3) / 2f;
				if (Llenando(num4).Count <= count)
				{
					num3 = num4;
				}
				else
				{
					num2 = num4;
				}
			}
			return Llenando(num3);
		}

		private static List<List<int>> Llenando(float capacidad)
		{
			List<List<int>> list = new List<List<int>>();
			List<int> list2 = new List<int>();
			float num = 0f;
			for (int i = 0; i < anchos.Count; i++)
			{
				if (list2.Count > 0 && num + anchos[i] > capacidad + 0.5f)
				{
					list.Add(list2);
					list2 = new List<int>();
					num = 0f;
				}
				list2.Add(i);
				num += anchos[i];
			}
			if (list2.Count > 0)
			{
				list.Add(list2);
			}
			return list;
		}

		private static List<List<int>> PorNumeroFijo(int total, int porPagina)
		{
			List<List<int>> list = new List<List<int>>();
			List<int> list2 = new List<int>();
			for (int i = 0; i < total; i++)
			{
				if (list2.Count >= porPagina)
				{
					list.Add(list2);
					list2 = new List<int>();
				}
				list2.Add(i);
			}
			if (list2.Count > 0)
			{
				list.Add(list2);
			}
			return list;
		}

		private static bool Medir(List<RectTransform> columnas)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			List<float> list = new List<float>(columnas.Count);
			List<float> list2 = new List<float>(columnas.Count);
			List<float> list3 = new List<float>(columnas.Count);
			for (int i = 0; i < columnas.Count; i++)
			{
				float num = ((i + 1 < columnas.Count) ? Mathf.Abs(((Transform)columnas[i + 1]).localPosition.x - ((Transform)columnas[i]).localPosition.x) : 0f);
				Rect rect = columnas[i].rect;
				float num2 = Mathf.Max(0f, ((Rect)(ref rect)).width);
				list2.Add(num2);
				list3.Add(num);
				float num3 = Mathf.Max(num2, num);
				if (num3 <= 1f && i > 0)
				{
					num3 = list[i - 1];
				}
				list.Add(num3);
			}
			float num4 = 0f;
			foreach (float item in list)
			{
				num4 += item;
			}
			if (num4 <= 1f)
			{
				previas.Clear();
				return false;
			}
			bool flag = previas.Count == list.Count;
			if (flag)
			{
				for (int j = 0; j < list.Count; j++)
				{
					if (Mathf.Abs(previas[j] - list[j]) > 0.5f)
					{
						flag = false;
						break;
					}
				}
			}
			previas.Clear();
			previas.AddRange(list);
			if (!flag)
			{
				return false;
			}
			anchos.Clear();
			anchos.AddRange(list);
			medidasEstables = true;
			StringBuilder stringBuilder = new StringBuilder();
			StringBuilder stringBuilder2 = new StringBuilder();
			for (int k = 0; k < list.Count; k++)
			{
				stringBuilder.Append((k == 0) ? "" : " ").Append($"{list[k]:0}");
				stringBuilder2.Append((k == 0) ? "" : " ").Append($"{list2[k]:0}/{list3[k]:0}");
			}
			Log($"medidas confirmadas: {list.Count} columnas, {num4:0} px en total, " + $"ocupacion [{stringBuilder}]");
			Log($"rect/paso por columna: [{stringBuilder2}]");
			return true;
		}

		private static void Pintar(CompendiumSectionBlessings seccion)
		{
			List<RectTransform> list = Columnas(seccion);
			if (list.Count == 0 || paginas.Count == 0)
			{
				return;
			}
			List<int> list2 = paginas[Mathf.Clamp(pagina, 0, paginas.Count - 1)];
			for (int i = 0; i < list.Count; i++)
			{
				bool flag = paginas.Count <= 1 || list2.Contains(i);
				if (((Component)list[i]).gameObject.activeSelf != flag)
				{
					((Component)list[i]).gameObject.SetActive(flag);
				}
			}
			RefrescarFlechas(seccion);
			if (list.Count == ultimoTotal && paginas.Count == ultimasPaginas && pagina == ultimaPagina)
			{
				return;
			}
			ultimoTotal = list.Count;
			ultimasPaginas = paginas.Count;
			ultimaPagina = pagina;
			StringBuilder stringBuilder = new StringBuilder();
			foreach (List<int> pagina in paginas)
			{
				float num = 0f;
				foreach (int item in pagina)
				{
					if (item < anchos.Count)
					{
						num += anchos[item];
					}
				}
				stringBuilder.Append((stringBuilder.Length == 0) ? "" : " + ").Append($"{pagina.Count} ({num:0} px)");
			}
			Log($"{list.Count} columnas en {paginas.Count} pagina(s) [{stringBuilder}], " + $"mostrando la {LogbookArtifactsPaging.pagina + 1} con {list2.Count}");
		}

		private static void RefrescarFlechas(CompendiumSectionBlessings seccion)
		{
			try
			{
				object obj = FPantalla?.GetValue(seccion);
				if (obj != null)
				{
					MRefrescarFlechas?.Invoke(obj, null);
				}
			}
			catch (Exception ex)
			{
				Log("no se pudieron refrescar las flechas: " + ex.Message, aviso: true);
			}
		}

		private static List<RectTransform> Columnas(CompendiumSectionBlessings seccion)
		{
			List<RectTransform> list = new List<RectTransform>();
			if (!(FColecciones?.GetValue(seccion) is IEnumerable enumerable))
			{
				return list;
			}
			foreach (object item in enumerable)
			{
				Component val = (Component)((item is Component) ? item : null);
				if (val != null && (Object)(object)val != (Object)null)
				{
					Transform transform = val.transform;
					RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
					if (val2 != null)
					{
						list.Add(val2);
					}
				}
			}
			return list;
		}

		private static float AnchoUtil(RectTransform raiz)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			if (WidthBudget > 1f)
			{
				return WidthBudget;
			}
			StringBuilder stringBuilder = new StringBuilder();
			float x = ((Transform)raiz).lossyScale.x;
			float num = 0f;
			bool flag = AnchoLoMandaElContenido((Transform)(object)raiz);
			Rect rect;
			if (!flag)
			{
				rect = raiz.rect;
				if (((Rect)(ref rect)).width > 1f)
				{
					rect = raiz.rect;
					num = ((Rect)(ref rect)).width;
				}
			}
			string name = ((Object)raiz).name;
			rect = raiz.rect;
			object arg = ((Rect)(ref rect)).width;
			rect = raiz.rect;
			stringBuilder.Append($"{name} {arg:0}x{((Rect)(ref rect)).height:0}").Append(flag ? " (el ancho lo manda el contenido, no cuenta)" : "");
			Transform parent = ((Transform)raiz).parent;
			RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
			int num2 = 0;
			while ((Object)(object)val != (Object)null && num2++ < 8)
			{
				rect = val.rect;
				float width = ((Rect)(ref rect)).width;
				float num3 = ((x > 0.0001f) ? (width * (((Transform)val).lossyScale.x / x)) : width);
				bool flag2 = AnchoLoMandaElContenido((Transform)(object)val);
				string name2 = ((Object)val).name;
				object arg2 = width;
				rect = val.rect;
				stringBuilder.Append($" <- {name2} {arg2:0}x{((Rect)(ref rect)).height:0}").Append((Mathf.Abs(num3 - width) > 1f) ? $" (={num3:0} en la raiz)" : "").Append(flag2 ? " (crece, no cuenta)" : "");
				if (!flag2 && num3 > 1f && (num <= 0f || num3 < num))
				{
					num = num3;
				}
				Transform parent2 = ((Transform)val).parent;
				val = (RectTransform)(object)((parent2 is RectTransform) ? parent2 : null);
			}
			if (!zonaTrazada)
			{
				zonaTrazada = true;
				Log($"zona: {stringBuilder} -> ancho util {num:0}");
			}
			return num;
		}

		private static void TrazarContenedor(RectTransform raiz)
		{
			if (contenedorTrazado || !Verbose)
			{
				return;
			}
			contenedorTrazado = true;
			StringBuilder stringBuilder = new StringBuilder();
			Component[] components = ((Component)raiz).GetComponents<Component>();
			foreach (Component val in components)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Type type = ((object)val).GetType();
				stringBuilder.Append(' ').Append(type.Name);
				if (!type.Name.Contains("LayoutGroup"))
				{
					continue;
				}
				stringBuilder.Append('(');
				string[] array = new string[8] { "spacing", "cellSize", "constraint", "constraintCount", "childForceExpandWidth", "childControlWidth", "childAlignment", "reverseArrangement" };
				foreach (string text in array)
				{
					object obj = null;
					try
					{
						obj = type.GetProperty(text)?.GetValue(val, null);
					}
					catch
					{
					}
					if (obj != null)
					{
						stringBuilder.Append(text).Append('=').Append(obj)
							.Append(' ');
					}
				}
				stringBuilder.Append($"padding={PaddingHorizontal((Transform)(object)raiz):0})");
			}
			Log($"contenedor {((Object)raiz).name}:{stringBuilder}");
		}

		private static float PaddingHorizontal(Transform t)
		{
			Component[] components = ((Component)t).GetComponents<Component>();
			foreach (Component val in components)
			{
				if ((Object)(object)val == (Object)null || !((object)val).GetType().Name.Contains("LayoutGroup"))
				{
					continue;
				}
				try
				{
					object obj = ((object)val).GetType().GetProperty("padding")?.GetValue(val, null);
					if (obj == null)
					{
						continue;
					}
					object obj2 = obj.GetType().GetProperty("left")?.GetValue(obj, null);
					object obj3 = obj.GetType().GetProperty("right")?.GetValue(obj, null);
					if (obj2 == null)
					{
						obj2 = 0;
					}
					return Convert.ToSingle(obj2) + Convert.ToSingle(obj3 ?? ((object)0));
				}
				catch
				{
					return 0f;
				}
			}
			return 0f;
		}

		private static bool AnchoLoMandaElContenido(Transform t)
		{
			Component[] components = ((Component)t).GetComponents<Component>();
			foreach (Component val in components)
			{
				if ((Object)(object)val == (Object)null || !((object)val).GetType().Name.Contains("ContentSizeFitter"))
				{
					continue;
				}
				Behaviour val2 = (Behaviour)(object)((val is Behaviour) ? val : null);
				if (val2 != null && !val2.enabled)
				{
					continue;
				}
				try
				{
					PropertyInfo property = ((object)val).GetType().GetProperty("horizontalFit");
					if (property == null)
					{
						return true;
					}
					object value = property.GetValue(val, null);
					if (value == null)
					{
						return true;
					}
					return Convert.ToInt32(value) != 0;
				}
				catch
				{
					return true;
				}
			}
			return false;
		}

		private static void Log(string mensaje, bool aviso = false)
		{
			if (aviso)
			{
				Plugin.Logger.LogWarning((object)("[ArtifactsPaging] " + mensaje));
			}
			else if (Verbose)
			{
				Plugin.Logger.LogInfo((object)("[ArtifactsPaging] " + mensaje));
			}
		}
	}
	[HarmonyPatch]
	public static class LogbookClanFit
	{
		public static bool Enabled = true;

		public static float MinScale = 0.45f;

		public static int MaxAutoColumns = 2;

		public static float ColumnSpacing = 16f;

		public static float HeaderReserve = 130f;

		public static float ScaleMultiplier = 1f;

		public static float HeightBudget = 0f;

		public static float WidthBudget = 0f;

		public static int RetryFrames = 5;

		public static bool Verbose = true;

		private static readonly FieldInfo? FClasses = AccessTools.Field(typeof(CompendiumSectionChampUpgrades), "classesOptionRoot");

		private static readonly FieldInfo? FCrew = AccessTools.Field(typeof(CompendiumSectionChampUpgrades), "crewClassesOptionRoot");

		private static readonly FieldInfo? FClases = AccessTools.Field(typeof(CompendiumSectionChampUpgrades), "availableClasses");

		private static float itemNatural;

		private static float vgapNatural;

		private static float hgapNatural;

		private static Vector2 origen;

		private static bool yaListado;

		private static int ultimoTotal = -1;

		private static int ultimoN = -1;

		[HarmonyPatch(typeof(CompendiumSectionChampUpgrades), "InitializeImpl")]
		[HarmonyPostfix]
		private static void TrasInicializar(CompendiumSectionChampUpgrades __instance)
		{
			Lanzar(__instance);
		}

		[HarmonyPatch(typeof(CompendiumSectionChampUpgrades), "Open")]
		[HarmonyPostfix]
		private static void TrasAbrir(CompendiumSectionChampUpgrades __instance)
		{
			Lanzar(__instance);
		}

		private static void Lanzar(CompendiumSectionChampUpgrades seccion)
		{
			if (!Enabled || (Object)(object)seccion == (Object)null)
			{
				return;
			}
			Encajar(seccion);
			if (!((Behaviour)seccion).isActiveAndEnabled)
			{
				return;
			}
			try
			{
				((MonoBehaviour)seccion).StartCoroutine(EncajarUnosFrames(seccion));
			}
			catch (Exception ex)
			{
				Log("no se pudo encolar el reintento: " + ex.Message, aviso: true);
			}
		}

		private static IEnumerator EncajarUnosFrames(CompendiumSectionChampUpgrades seccion)
		{
			for (int i = 0; i < Mathf.Max(1, RetryFrames); i++)
			{
				yield return null;
				if ((Object)(object)seccion == (Object)null || !((Behaviour)seccion).isActiveAndEnabled)
				{
					break;
				}
				Encajar(seccion);
			}
		}

		private static void Encajar(CompendiumSectionChampUpgrades seccion)
		{
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: 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_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: 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_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: 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_042a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0436: Unknown result type (might be due to invalid IL or missing references)
			//IL_0486: Unknown result type (might be due to invalid IL or missing references)
			//IL_048b: Unknown result type (might be due to invalid IL or missing references)
			//IL_048f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0566: Unknown result type (might be due to invalid IL or missing references)
			//IL_056b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0575: Unknown result type (might be due to invalid IL or missing references)
			//IL_051a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0531: Unknown result type (might be due to invalid IL or missing references)
			//IL_05df: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fc: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				ListarClanes(seccion);
				Transform val = ComoTransform(FClasses?.GetValue(seccion));
				Transform val2 = ComoTransform(FCrew?.GetValue(seccion));
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				Transform parent = val.parent;
				RectTransform val3 = (RectTransform)(object)((parent is RectTransform) ? parent : null);
				if (val3 == null)
				{
					return;
				}
				bool flag = (Object)(object)val2 != (Object)null && ((Component)val2).gameObject.activeInHierarchy;
				List<Transform> list = new List<Transform>();
				list.AddRange(Hijos(val));
				if (flag)
				{
					list.AddRange(Hijos(val2));
				}
				if (list.Count == 0)
				{
					return;
				}
				RectTransform val4 = Zona(val3);
				if ((Object)(object)val4 == (Object)null)
				{
					return;
				}
				Rect rect;
				float num;
				if (!(WidthBudget > 1f))
				{
					rect = val4.rect;
					num = ((Rect)(ref rect)).width;
				}
				else
				{
					num = WidthBudget;
				}
				float num2 = num;
				float num3;
				if (!(HeightBudget > 1f))
				{
					rect = val4.rect;
					num3 = ((Rect)(ref rect)).height;
				}
				else
				{
					num3 = HeightBudget;
				}
				float num4 = num3;
				if (num4 <= 1f || num2 <= 1f)
				{
					return;
				}
				float num5 = Mathf.Clamp(HeaderReserve, 0f, num4 * 0.5f);
				num4 -= num5;
				if (MaxAutoColumns <= 2)
				{
					RectTransform val5 = (RectTransform)(object)((val is RectTransform) ? val : null);
					float num6;
					if (val5 == null)
					{
						num6 = 0f;
					}
					else
					{
						rect = val5.rect;
						num6 = ((Rect)(ref rect)).height;
					}
					float num7 = num6;
					if (flag)
					{
						RectTransform val6 = (RectTransform)(object)((val2 is RectTransform) ? val2 : null);
						if (val6 != null)
						{
							float num8 = num7;
							rect = val6.rect;
							num7 = Mathf.Max(num8, ((Rect)(ref rect)).height);
						}
					}
					rect = val3.rect;
					float width = ((Rect)(ref rect)).width;
					if (!(num7 <= 1f))
					{
						float num9 = Mathf.Min(1f, num4 / num7);
						if (width > 1f)
						{
							num9 = Mathf.Min(num9, num2 / width);
						}
						num9 = Mathf.Clamp(num9 * Mathf.Clamp(ScaleMultiplier, 0.1f, 1f), MinScale, 1f);
						val.localScale = Vector3.one;
						if ((Object)(object)val2 != (Object)null)
						{
							val2.localScale = Vector3.one;
						}
						((Transform)val3).localScale = new Vector3(num9, num9, 1f);
						if (list.Count != ultimoTotal || ultimoN != 2)
						{
							ultimoTotal = list.Count;
							ultimoN = 2;
							Log($"{list.Count} rombos, rejilla del juego, contenido " + $"{width:0}x{num7:0}, zona {num2:0}x{num4:0}, factor {num9:0.00}");
						}
					}
				}
				else
				{
					if (!Medir(val, flag ? val2 : null))
					{
						return;
					}
					ApagarLayouts(val);
					if (flag)
					{
						ApagarLayouts(val2);
					}
					ApagarLayouts((Transform)(object)val3);
					int count = list.Count;
					int num10 = 2;
					float num11 = 0f;
					for (int i = 1; i <= Mathf.Max(1, MaxAutoColumns); i++)
					{
						int num12 = Mathf.CeilToInt((float)count / (float)i);
						float num13 = ((i > 2) ? ColumnSpacing : hgapNatural);
						float num14 = (float)num12 * itemNatural + (float)(num12 - 1) * vgapNatural;
						float num15 = (float)i * itemNatural + (float)(i - 1) * num13;
						float num16 = Mathf.Min(1f, Mathf.Min(num4 / num14, num2 / num15));
						if (num16 > num11 + 0.001f)
						{
							num11 = num16;
							num10 = i;
						}
					}
					num11 = Mathf.Clamp(num11 * Mathf.Clamp(ScaleMultiplier, 0.1f, 1f), MinScale, 1f);
					val.localScale = Vector3.one;
					if ((Object)(object)val2 != (Object)null)
					{
						val2.localScale = Vector3.one;
					}
					((Transform)val3).localScale = new Vector3(num11, num11, 1f);
					int num17 = Mathf.CeilToInt((float)count / (float)num10);
					float num18 = ((num10 > 2) ? ColumnSpacing : hgapNatural);
					float num19 = ((((Transform)val4).lossyScale.x != 0f) ? (((Transform)val3).lossyScale.x / ((Transform)val4).lossyScale.x) : num11);
					float num20 = (itemNatural + num18) * num19;
					float num21 = (itemNatural + vgapNatural) * num19;
					float num22 = itemNatural * num19;
					float num23 = (float)(num10 - 1) * num20 + num22;
					float num24 = (float)(num17 - 1) * num21 + num22;
					rect = val4.rect;
					float num25 = ((Rect)(ref rect)).center.y - num5 / 2f;
					rect = val4.rect;
					float num26 = ((Rect)(ref rect)).center.x - num23 / 2f + num22 / 2f;
					float num27 = num25 + num24 / 2f - num22 / 2f;
					for (int j = 0; j < count; j++)
					{
						int num28 = j / num17;
						int num29 = j % num17;
						Transform obj = list[j];
						float num30 = 0f;
						float num31 = 0f;
						RectTransform val7 = (RectTransform)(object)((obj is RectTransform) ? obj : null);
						if (val7 != null)
						{
							num30 = (val7.pivot.x - 0.5f) * num22;
							num31 = (val7.pivot.y - 0.5f) * num22;
						}
						obj.position = ((Transform)val4).TransformPoint(new Vector3(num26 + (float)num28 * num20 + num30, num27 - (float)num29 * num21 + num31, 0f));
						obj.localScale = Vector3.one;
					}
					if (count != ultimoTotal || num10 != ultimoN)
					{
						ultimoTotal = count;
						ultimoN = num10;
						string text = $"rejilla {num23:0}x{num24:0} centrada en {((Object)val4).name} ";
						object[] array = new object[4];
						rect = val4.rect;
						array[0] = ((Rect)(ref rect)).width;
						rect = val4.rect;
						array[1] = ((Rect)(ref rect)).height;
						array[2] = num26;
						array[3] = num27;
						Log(text + string.Format("({0:0}x{1:0}), salida ({2:0}, {3:0})", array));
						Log($"{count} rombos en {num10} columnas de {num17}, factor {num11:0.00} " + $"(zona {num2:0}x{num4:0} tras reservar {num5:0} de encabezado, " + $"rombo {itemNatural:0}, huecos {vgapNatural:0}/{num18:0})");
					}
				}
			}
			catch (Exception ex)
			{
				Log("fallo encajando la pagina: " + ex, aviso: true);
			}
		}

		private static List<Transform> Hijos(Transform raiz)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			List<Transform> list = new List<Transform>();
			foreach (Transform item in raiz)
			{
				Transform val = item;
				if (((Component)val).gameObject.activeSelf)
				{
					list.Add(val);
				}
			}
			return list;
		}

		private static bool Medir(Transform c1, Transform? c2)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: 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_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			if (itemNatural > 0f)
			{
				return true;
			}
			List<Transform> list = Hijos(c1);
			if (list.Count < 2)
			{
				return false;
			}
			Transform obj = list[0];
			RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null);
			if (val != null)
			{
				Transform obj2 = list[1];
				RectTransform val2 = (RectTransform)(object)((obj2 is RectTransform) ? obj2 : null);
				if (val2 != null)
				{
					Rect rect = val.rect;
					float height = ((Rect)(ref rect)).height;
					rect = val.rect;
					float width = ((Rect)(ref rect)).width;
					float num = Mathf.Abs(((Transform)val2).localPosition.y - ((Transform)val).localPosition.y);
					if (height < 10f || width < 10f || num < 10f)
					{
						return false;
					}
					itemNatural = height;
					vgapNatural = Mathf.Clamp(num - height, 0f, 200f);
					hgapNatural = 96f;
					if ((Object)(object)c2 != (Object)null)
					{
						float num2 = Mathf.Abs(c2.localPosition.x - c1.localPosition.x);
						if (num2 > width && num2 - width < 400f)
						{
							hgapNatural = num2 - width;
						}
					}
					origen = new Vector2(c1.localPosition.x + ((Transform)val).localPosition.x, c1.localPosition.y + ((Transform)val).localPosition.y);
					Log($"medidas naturales: rombo {itemNatural:0}x{width:0}, fila {vgapNatural:0}, " + $"columna {hgapNatural:0}, salida ({origen.x:0}, {origen.y:0})");
					return true;
				}
			}
			return false;
		}

		private static void ApagarLayouts(Transform t)
		{
			Component[] components = ((Component)t).GetComponents<Component>();
			foreach (Component val in components)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				string name = ((object)val).GetType().Name;
				if (name.Contains("LayoutGroup") || name.Contains("ContentSizeFitter"))
				{
					Behaviour val2 = (Behaviour)(object)((val is Behaviour) ? val : null);
					if (val2 != null && val2.enabled)
					{
						val2.enabled = false;
						Log("layout apagado en " + ((Object)t).name + ": " + name);
					}
				}
			}
		}

		private static RectTransform? Zona(RectTransform desde)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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)
			StringBuilder stringBuilder = new StringBuilder();
			Transform parent = ((Transform)desde).parent;
			RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
			int num = 0;
			while ((Object)(object)val != (Object)null && num++ < 8)
			{
				string name = ((Object)val).name;
				Rect rect = val.rect;
				object arg = ((Rect)(ref rect)).width;
				rect = val.rect;
				stringBuilder.Append($" <- {name} {arg:0}x{((Rect)(ref rect)).height:0}");
				rect = val.rect;
				if (((Rect)(ref rect)).width > 1f)
				{
					rect = val.rect;
					if (((Rect)(ref rect)).height > 1f)
					{
						return val;
					}
				}
				Transform parent2 = ((Transform)val).parent;
				val = (RectTransform)(object)((parent2 is RectTransform) ? parent2 : null);
			}
			Log($"zona: ningun ancestro mide;{stringBuilder}", aviso: true);
			return null;
		}

		private static void ListarClanes(CompendiumSectionChampUpgrades seccion)
		{
			if (yaListado || !Verbose || FClases == null || !(FClases.GetValue(seccion) is IEnumerable enumerable))
			{
				return;
			}
			List<string> list = new List<string>();
			foreach (object item in enumerable)
			{
				if (item != null)
				{
					MethodInfo? method = item.GetType().GetMethod("GetTitle", Type.EmptyTypes);
					MethodInfo method2 = item.GetType().GetMethod("IsCrew", Type.EmptyTypes);
					string text = (method?.Invoke(item, null) as string) ?? item.ToString();
					object obj = method2?.Invoke(item, null);
					bool flag = obj is bool && (bool)obj;
					list.Add(flag ? (text + " (crew)") : text);
				}
			}
			yaListado = true;
			Log($"clases registradas ({list.Count}): " + string.Join(", ", list));
		}

		private static Transform? ComoTransform(object? o)
		{
			if (o != null)
			{
				GameObject val = (GameObject)((o is GameObject) ? o : null);
				if (val == null)
				{
					Component val2 = (Component)((o is Component) ? o : null);
					if (val2 != null)
					{
						return val2.transform;
					}
					return null;
				}
				return val.transform;
			}
			return null;
		}

		private static void Log(string mensaje, bool aviso = false)
		{
			if (aviso)
			{
				Plugin.Logger.LogWarning((object)("[LogbookFit] " + mensaje));
			}
			else if (Verbose)
			{
				Plugin.Logger.LogInfo((object)("[LogbookFit] " + mensaje));
			}
		}
	}
	[HarmonyPatch]
	public static class LogbookProgressGrid
	{
		[HarmonyPatch]
		private static class InicializarDlcPatch
		{
			private static bool Prepare()
			{
				return TipoPaginaDlc != null;
			}

			private static MethodBase TargetMethod()
			{
				return AccessTools.Method(TipoPaginaDlc, "Initialize", (Type[])null, (Type[])null);
			}

			[HarmonyPostfix]
			private static void Postfix(ChecklistPage __instance)
			{
				TrasInicializarRail(__instance);
			}
		}

		public static bool Enabled = true;

		public static int Columns = 1;

		public static int RowsPerPage = 0;

		public static bool Verbose = true;

		public static int DetailSections = 0;

		public static bool WidenSections = true;

		public static bool FreeFlagWidth = true;

		public static float FlagSpacing = 6f;

		public static string Layout = "inflow";

		public static float PlaqueWidth = 280f;

		public static bool StretchPlaqueFill = true;

		public static bool DumpTree = false;

		public static bool BalanceFlagRows = true;

		public static bool FlagAlignLeft = true;

		public static float RibbonExtra = 0f;

		public static float FlagOffsetX = 0f;

		public static bool FixMasteryMeter = true;

		public static int MeterColumns = 12;

		public static int MeterRows = 5;

		private static readonly FieldInfo? FPaginas = AccessTools.Field(typeof(CompendiumSectionChecklist), "checklistPages");

		private static readonly FieldInfo? FPaginaActual = AccessTools.Field(typeof(CompendiumSectionChecklist), "currentPage");

		private static readonly FieldInfo? FLayoutTodos = AccessTools.Field(typeof(StandardChecklistPage), "clanSectionsLayoutAllClans");

		private static readonly FieldInfo? FLayoutIniciales = AccessTools.Field(typeof(StandardChecklistPage), "clanSectionsLayoutStartingClans");

		private static readonly FieldInfo? FSecciones = AccessTools.Field(typeof(StandardChecklistPage), "clanChecklistSections");

		private static readonly FieldInfo? FClase = AccessTools.Field(typeof(ClanChecklistSection), "classData");

		private static readonly FieldInfo? FFila = AccessTools.Field(typeof(ClanChecklistSection), "subclanVictoryLayout");

		private static readonly Type? TipoPaginaDlc = ResolverPaginaDlc(typeof(ChecklistPage).Assembly);

		private static readonly FieldInfo? FLayoutRail = ((TipoPaginaDlc == null) ? null : AccessTools.Field(TipoPaginaDlc, "clanSectionsLayoutAllDlcClans"));

		private static readonly FieldInfo? FLayoutRailInicial = ((TipoPaginaDlc == null) ? null : AccessTools.Field(TipoPaginaDlc, "clanSectionsLayoutStartingDlcClans"));

		private static readonly FieldInfo? FSeccionesRail = ((TipoPaginaDlc == null) ? null : AccessTools.Field(TipoPaginaDlc, "clanChecklistSections"));

		private static readonly FieldInfo? FIndicePagina = AccessTools.Field(typeof(PaginatedCompendiumSection), "currentPageIndex");

		private static readonly FieldInfo? FFilaCrew = AccessTools.Field(typeof(ClanChecklistSection), "subclanVictoryLayoutCrew");

		private static StandardChecklistPage? hoja;

		private static readonly List<Component> secciones = new List<Component>();

		private static ChecklistPage? hojaRail;

		private static readonly List<Component> seccionesRail = new List<Component>();

		private static int porHoja = 10;

		private static int subpagina;

		private static int subpaginas = 1;

		private static bool trazado;

		private static bool dlcIntegrado;

		private static bool pintandoRotulo;

		private static int indiceReal;

		private static Vector2 celdaOriginal;

		private static bool celdaGuardada;

		private static bool volcado;

		private static readonly MethodInfo? MReconstruir = AccessTools.Method(AccessTools.TypeByName("UnityEngine.UI.LayoutRebuilder"), "ForceRebuildLayoutImmediate", (Type[])null, (Type[])null);

		private static readonly Dictionary<Transform, float> anchoOriginal = new Dictionary<Transform, float>();

		private static readonly Dictionary<Transform, float> xOriginal = new Dictionary<Transform, float>();

		private static readonly Dictionary<Transform, Transform> devolverA = new Dictionary<Transform, Transform>();

		private static readonly Dictionary<Transform, int> ordenOriginal = new Dictionary<Transform, int>();

		internal static Type? ResolverPaginaDlc(Assembly gameAssembly)
		{
			return gameAssembly.GetType("DlcChecklistPage") ?? gameAssembly.GetType("RailforgedChecklistPage");
		}

		[HarmonyPatch(typeof(StandardChecklistPage), "Initialize")]
		[HarmonyPostfix]
		private static void TrasInicializarHoja(StandardChecklistPage __instance)
		{
			hoja = __instance;
			dlcIntegrado = false;
			secciones.Clear();
			subpagina = 0;
			if (FSecciones?.GetValue(__instance) is IEnumerable enumerable)
			{
				foreach (object item in enumerable)
				{
					Component val = (Component)((item is Component) ? item : null);
					if (val != null && (Object)(object)val != (Object)null)
					{
						secciones.Add(val);
					}
				}
			}
			if (!Enabled || secciones.Count == 0)
			{
				return;
			}
			Ajustar();
			if (!((Behaviour)__instance).isActiveAndEnabled)
			{
				return;
			}
			try
			{
				((MonoBehaviour)__instance).StartCoroutine(AjustarUnosFrames(__instance));
			}
			catch (Exception ex)
			{
				Log("no se pudo encolar el reintento: " + ex.Message, aviso: true);
			}
		}

		private static void TrasInicializarRail(ChecklistPage __instance)
		{
			hojaRail = __instance;
			seccionesRail.Clear();
			if (FSeccionesRail?.GetValue(__instance) is IEnumerable enumerable)
			{
				foreach (object item in enumerable)
				{
					Component val = (Component)((item is Component) ? item : null);
					if (val != null && (Object)(object)val != (Object)null)
					{
						seccionesRail.Add(val);
					}
				}
			}
			if (!Enabled || seccionesRail.Count == 0)
			{
				return;
			}
			Ajustar();
			if (!((Behaviour)__instance).isActiveAndEnabled)
			{
				return;
			}
			try
			{
				((MonoBehaviour)__instance).StartCoroutine(AjustarRailUnosFrames(__instance));
			}
			catch (Exception ex)
			{
				Log("no se pudo encolar el reintento de Railforged: " + ex.Message, aviso: true);
			}
		}

		[HarmonyPatch(typeof(CompendiumSectionChecklist), "InitializeImpl")]
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void IntegrarDlc(CompendiumSectionChecklist __instance)
		{
			if (!Enabled || (Object)(object)hoja == (Object)null || (Object)(object)hojaRail == (Object)null || seccionesRail.Count == 0 || !__instance.ChecklistPages.Contains((ChecklistPage)(object)hoja) || !__instance.ChecklistPages.Contains(hojaRail))
			{
				return;
			}
			object? obj = FLayoutTodos?.GetValue(hoja);
			Component val = (Component)((obj is Component) ? obj : null);
			if ((Object)(object)val == (Object)null || !val.gameObject.activeSelf)
			{
				object? obj2 = FLayoutIniciales?.GetValue(hoja);
				val = (Component)((obj2 is Component) ? obj2 : null);
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			foreach (Component item in seccionesRail)
			{
				item.transform.SetParent(val.transform, false);
				if (!secciones.Contains(item))
				{
					secciones.Add(item);
				}
			}
			dlcIntegrado = true;
			Ajustar();
			RefrescarRotulo((PaginatedCompendiumSection)(object)__instance);
			((PaginatedCompendiumSection)__instance).PageCountChangedSignal.Dispatch();
			if (FPaginaActual?.GetValue(__instance) == hojaRail)
			{
				AccessTools.Method(typeof(CompendiumSectionChecklist), "SetPage", (Type[])null, (Type[])null).Invoke(__instance, new object[1] { hojaRail });
			}
			Log("DLC integrado: " + secciones.Count + " clanes en " + subpaginas + " páginas.");
		}

		[HarmonyPatch(typeof(CompendiumSectionChecklist), "SetPage")]
		[HarmonyPrefix]
		private static void RedirigirDlc(ref ChecklistPage setPage)
		{
			if (Enabled && dlcIntegrado && !((Object)(object)setPage != (Object)(object)hojaRail) && !((Object)(object)hoja == (Object)null))
			{
				int num = secciones.FindIndex((Component c) => seccionesRail.Contains(c));
				subpagina = Mathf.Max(0, num / porHoja);
				setPage = (ChecklistPage)(object)hoja;
			}
		}

		[HarmonyPatch(typeof(CompendiumSectionChecklist), "Close")]
		[HarmonyPrefix]
		private static void ReiniciarNormal()
		{
			subpagina = 0;
		}

		[HarmonyPatch(typeof(StandardChecklistPage), "GetDefaultGameUISelectable")]
		[HarmonyPrefix]
		private static bool SeleccionarVisible(StandardChecklistPage __instance, ref IGameUIComponent? __result)
		{
			if (!Enabled || (Object)(object)__instance != (Object)(object)hoja)
			{
				return true;
			}
			foreach (Component seccione in secciones)
			{
				if ((Object)(object)seccione != (Object)null && seccione.gameObject.activeInHierarchy)
				{
					ClanChecklistSection val = (ClanChecklistSection)(object)((seccione is ClanChecklistSection) ? seccione : null);
					if (val != null)
					{
						__result = val.GetDefaultGameUISelectable();
						return false;
					}
				}
			}
			return true;
		}

		private static IEnumerator AjustarRailUnosFrames(ChecklistPage pagina)
		{
			for (int i = 1; i <= 40; i++)
			{
				yield return null;
				if ((Object)(object)pagina == (Object)null)
				{
					break;
				}
				if (i <= 5 || i == 10 || i == 20 || i == 40)
				{
					Ajustar();
				}
			}
		}

		private static IEnumerator AjustarUnosFrames(StandardChecklistPage pagina)
		{
			for (int i = 1; i <= 40; i++)
			{
				yield return null;
				if ((Object)(object)pagina == (Object)null)
				{
					yield break;
				}
				if (i <= 5 || i == 10 || i == 20 || i == 40)
				{
					Ajustar();
				}
			}
			Trazar();
		}

		private static void Ajustar()
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			if (!Enabled || (Object)(object)hoja == (Object)null || secciones.Count == 0)
			{
				return;
			}
			try
			{
				object? obj = FLayoutTodos?.GetValue(hoja);
				Component val = (Component)((obj is Component) ? obj : null);
				if (val == null)
				{
					return;
				}
				Transform transform = val.transform;
				RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				if (val2 == null)
				{
					return;
				}
				Component val3 = Rejilla(val.transform);
				if ((Object)(object)val3 == (Object)null)
				{
					return;
				}
				Rect rect = val2.rect;
				float width = ((Rect)(ref rect)).width;
				rect = val2.rect;
				float height = ((Rect)(ref rect)).height;
				if (width <= 1f || height <= 1f)
				{
					return;
				}
				Vector2 val4 = LeerVector(val3, "cellSize");
				Vector2 val5 = LeerVector(val3, "spacing");
				if (val4.y <= 1f)
				{
					return;
				}
				if (!celdaGuardada)
				{
					celdaOriginal = val4;
					celdaGuardada = true;
				}
				int num = Mathf.Max(1, Columns);
				float num2 = (width - (float)(num - 1) * val5.x) / (float)num;
				if (Mathf.Abs(num2 - val4.x) > 0.5f)
				{
					EscribirVector(val3, "cellSize", new Vector2(num2, celdaOriginal.y));
					Log($"celda {celdaOriginal.x:0}x{celdaOriginal.y:0} -> {num2:0}x{celdaOriginal.y:0} " + $"({num} columna(s) en {width:0} px)");
				}
				int num3 = ((RowsPerPage > 0) ? RowsPerPage : Mathf.Max(1, Mathf.FloorToInt((height + val5.y) / (celdaOriginal.y + val5.y))));
				porHoja = Mathf.Max(1, num3 * num);
				int num4 = Mathf.CeilToInt((float)secciones.Count / (float)porHoja);
				if (num4 != subpaginas)
				{
					subpaginas = num4;
					Log($"{secciones.Count} secciones, {porHoja} por hoja ({num}x{num3}) " + $"-> {subpaginas} sub-paginas");
				}
				subpagina = Mathf.Clamp(subpagina, 0, subpaginas - 1);
				Pintar();
				Volcar();
				Ensanchar(num2);
			}
			catch (Exception ex)
			{
				Log("fallo ajustando la hoja: " + ex, aviso: true);
			}
			AjustarRail();
		}

		private static void AjustarRail()
		{
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: 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_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			if (!Enabled || dlcIntegrado || (Object)(object)hojaRail == (Object)null || seccionesRail.Count == 0)
			{
				return;
			}
			try
			{
				object? obj = FLayoutRail?.GetValue(hojaRail);
				Component val = (Component)((obj is Component) ? obj : null);
				if ((Object)(object)val == (Object)null || !val.gameObject.activeSelf)
				{
					object? obj2 = FLayoutRailInicial?.GetValue(hojaRail);
					val = (Component)((obj2 is Component) ? obj2 : null);
				}
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				Transform transform = val.transform;
				RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				if (val2 == null)
				{
					return;
				}
				Component val3 = Rejilla(val.transform);
				if ((Object)(object)val3 == (Object)null)
				{
					return;
				}
				Rect rect = val2.rect;
				float width = ((Rect)(ref rect)).width;
				if (width <= 1f)
				{
					return;
				}
				Vector2 val4 = LeerVector(val3, "cellSize");
				Vector2 val5 = LeerVector(val3, "spacing");
				if (!(val4.y <= 1f))
				{
					int num = Mathf.Max(1, Columns);
					float num2 = (width - (float)(num - 1) * val5.x) / (float)num;
					if (Mathf.Abs(num2 - val4.x) > 0.5f)
					{
						EscribirVector(val3, "cellSize", new Vector2(num2, val4.y));
						Log($"Railforged: celda {val4.x:0} -> {num2:0} px ({num} columna(s))");
					}
					EnsancharLista(seccionesRail, num2);
				}
			}
			catch (Exception ex)
			{
				Log("fallo ajustando la hoja de Railforged: " + ex, aviso: true);
			}
		}

		private static void PintarYMedir()
		{
			Pintar();
			if ((Object)(object)hoja == (Object)null || !((Behaviour)hoja).isActiveAndEnabled)
			{
				return;
			}
			try
			{
				((MonoBehaviour)hoja).StartCoroutine(AjustarUnosFrames(hoja));
			}
			catch (Exception ex)
			{
				Log("no se pudo re-medir al cambiar de sub-pagina: " + ex.Message, aviso: true);
			}
		}

		private static void Pintar()
		{
			for (int i = 0; i < secciones.Count; i++)
			{
				Component val = secciones[i];
				if (!((Object)(object)val == (Object)null))
				{
					bool flag = subpaginas <= 1 || i / porHoja == subpagina;
					if (val.gameObject.activeSelf != flag)
					{
						val.gameObject.SetActive(flag);
					}
				}
			}
		}

		private static void Volcar()
		{
			if (!volcado && DumpTree && Verbose && secciones.Count != 0 && !((Object)(object)secciones[0] == (Object)null))
			{
				volcado = true;
				Log("---- arbol de la primera seccion ----");
				VolcarRama(secciones[0].transform, 0);
				Log("---- fin del arbol ----");
			}
		}

		private static void VolcarRama(Transform t, int nivel)
		{
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Expected O, but got Unknown
			if (nivel > 5)
			{
				return;
			}
			string text = "";
			Component[] components = ((Component)t).GetComponents<Component>();
			foreach (Component val in components)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string name = ((object)val).GetType().Name;
					if (name.Contains("Image") || name.Contains("Text") || name.Contains("Sprite") || name.Contains("Mask") || name.Contains("Canvas"))
					{
						text = text + " " + name;
					}
				}
			}
			Log($"{new string(' ', nivel * 2)}[{nivel}] \"{((Object)t).name}\"" + (((Component)t).gameObject.activeSelf ? "" : " (apagado)") + Medidas(t) + text);
			foreach (Transform item in t)
			{
				VolcarRama(item, nivel + 1);
			}
		}

		private static void Ensanchar(float anchoCelda)
		{
			EnsancharLista(secciones, anchoCelda);
		}

		private static void EnsancharLista(List<Component> lista, float anchoCelda)
		{
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Expected O, but got Unknown
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Expected O, but got Unknown
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e8: 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)
			if (anchoCelda <= 1f || (!WidenSections && !FreeFlagWidth))
			{
				return;
			}
			bool flag = !Layout.Equals("inflow", StringComparison.OrdinalIgnoreCase);
			int columnas = (FixMasteryMeter ? ColumnasMedidor() : 0);
			float num = ContenedorComun();
			foreach (Component listum in lista)
			{
				if ((Object)(object)listum == (Object)null)
				{
					continue;
				}
				Transform transform = listum.transform;
				RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				if (val == null || !listum.gameObject.activeInHierarchy)
				{
					continue;
				}
				ClanChecklistSection val2 = (ClanChecklistSection)(object)((listum is ClanChecklistSection) ? listum : null);
				if (val2 != null)
				{
					TrasRepartirAliados(val2);
				}
				foreach (Transform item in (Transform)val)
				{
					Transform val3 = item;
					if (!((Object)val3).name.Contains("Main class section"))
					{
						continue;
					}
					foreach (Transform item2 in val3)
					{
						Transform val4 = item2;
						if (((Object)val4).name.Contains("Ribbon container"))
						{
							GuardarFranja(val4);
						}
					}
				}
				if (WidenSections)
				{
					SoltarAjustador((Transform)(object)val);
					FijarAncho((Transform?)(object)val, anchoCelda);
				}
				Transform val5 = null;
				Transform val6 = null;
				Transform val7 = null;
				foreach (Transform item3 in (Transform)val)
				{
					Transform val8 = item3;
					if (((Object)val8).name.Contains("Main class section"))
					{
						val5 = val8;
					}
					else if (((Object)val8).name.Contains("victory container"))
					{
						val6 = val8;
					}
					else if (((Object)val8).name.Contains("Card mastery"))
					{
						val7 = val8;
					}
				}
				if ((Object)(object)val6 == (Object)null)
				{
					continue;
				}
				Component val9 = Componente(val6, "VerticalLayoutGroup");
				if (val9 != null)
				{
					if (FlagAlignLeft)
					{
						PonerAlineacion(val9, 3);
					}
					PonerRelleno(val9, 8);
				}
				float num2 = 0f;
				foreach (Transform item4 in val6)
				{
					Transform fila = item4;
					num2 = Mathf.Max(num2, Fila(fila));
				}
				if (num2 <= 1f)
				{
					continue;
				}
				float num3 = Mathf.Max(num2 + 16f, num);
				if (!WidenSections)
				{
					continue;
				}
				float num4 = LeerFloat(Componente((Transform)(object)val, "HorizontalLayoutGroup"), "spacing", 24f);
				if (FixMasteryMeter)
				{
					ArreglarMedidor(val7, columnas);
				}
				RectTransform val10 = (RectTransform)(object)((val7 is RectTransform) ? val7 : null);
				float num5;
				if (val10 != null)
				{
					Rect rect = val10.rect;
					if (((Rect)(ref rect)).width > 1f)
					{
						rect = val10.rect;
						num5 = ((Rect)(ref rect)).width;
						goto IL_02f1;
					}
				}
				num5 = 105f;
				goto IL_02f1;
				IL_02f1:
				float num6 = num5;
				if (flag)
				{
					float num7 = Mathf.Max(200f, anchoCelda - num6 - num4 * 2f);
					if ((Object)(object)val5 != (Object)null)
					{
						SoltarAjustador(val5);
						PreferirAncho(val5, num7);
						FijarAncho(val5, num7);
					}
					PonerIgnoreLayout(val6, valor: true);
					RectTransform val11 = (RectTransform)(object)((val6 is RectTransform) ? val6 : null);
					float num8 = ((val11 != null) ? Mathf.Abs(val11.anchoredPosition.x) : 0f);
					float ancho = Mathf.Max(num3, num7 - num8 - num4);
					FijarAncho(val6, ancho);
					continue;
				}
				EnFila(val6, num3);
				PonerIgnoreLayout(val6, valor: true);
				FijarAncho(val6, num3);
				if ((Object)(object)val5 != (Object)null)
				{
					float num9 = ((PlaqueWidth > 0f) ? PlaqueWidth : Mathf.Max(200f, anchoCelda - num3 - num6 - num4 * 2f));
					SoltarAjustador(val5);
					PreferirAncho(val5, num9);
					PonerFlexible(val5, 1f);
					FijarAncho(val5, num9);
					if (StretchPlaqueFill)
					{
						ReconstruirLayout(val);
						ColocarBanderas(val, val5, val6);
						EstirarFranja(val, val5, val7, num9, num3 + num4 * 2f);
					}
				}
			}
		}

		private static IEnumerable<Component> TodasLasSecciones()
		{
			foreach (Component seccione in secciones)
			{
				if ((Object)(object)seccione != (Object)null)
				{
					yield return seccione;
				}
			}
			foreach (Component item in seccionesRail)
			{
				if ((Object)(object)item != (Object)null)
				{
					yield return item;
				}
			}
		}

		private static float ContenedorComun()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			foreach (Component item in TodasLasSecciones())
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				foreach (Transform item2 in item.transform)
				{
					Transform val = item2;
					if (!((Object)val).name.Contains("victory container"))
					{
						continue;
					}
					if (BalanceFlagRows)
					{
						int num2 = 0;
						float num3 = 48f;
						foreach (Transform item3 in val)
						{
							foreach (Transform item4 in item3)
							{
								Transform val2 = item4;
								if (((Component)val2).gameObject.activeSelf)
								{
									num2++;
									RectTransform val3 = (RectTransform)(object)((val2 is RectTransform) ? val2 : null);
									if (val3 != null)
									{
										float num4 = num3;
										Rect rect = val3.rect;
										num3 = Mathf.Max(num4, ((Rect)(ref rect)).width);
									}
								}
							}
						}
						int num5 = (num2 + 1) / 2;
						if (num5 > 0)
						{
							num = Mathf.Max(num, (float)num5 * num3 + (float)(num5 - 1) * FlagSpacing);
						}
						break;
					}
					foreach (Transform item5 in val)
					{
						Transform fila = item5;
						num = Mathf.Max(num, Fila(fila));
					}
					break;
				}
			}
			if (!(num > 1f))
			{
				return 0f;
			}
			return num + 16f;
		}

		private static int ColumnasMedidor()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			foreach (Component item in TodasLasSecciones())
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				foreach (Transform item2 in item.transform)
				{
					Transform val = item2;
					if (!((Object)val).name.Contains("Card mastery"))
					{
						continue;
					}
					int num2 = 0;
					foreach (Transform item3 in val)
					{
						if (((Component)item3).gameObject.activeSelf)
						{
							num2++;
						}
					}
					if (num2 > num)
					{
						num = num2;
					}
					break;
				}
			}
			int num3 = Mathf.Max(1, MeterColumns);
			if (num == 0)
			{
				return num3;
			}
			int num4 = Mathf.CeilToInt((float)num / (float)Mathf.Max(1, MeterRows));
			return Mathf.Max(num3, num4);
		}

		private static void ArreglarMedidor(Transform? medidor, int columnas)
		{
			//IL_0027: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)(object)((medidor is RectTransform) ? medidor : null);
			if (val == null || columnas < 1)
			{
				return;
			}
			Component val2 = Rejilla(medidor);
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			try
			{
				Vector2 val3 = LeerVector(val2, "cellSize");
				Vector2 val4 = LeerVector(val2, "spacing");
				if (val3.x <= 0f)
				{
					return;
				}
				PropertyInfo property = ((object)val2).GetType().GetProperty("constraint");
				PropertyInfo property2 = ((object)val2).GetType().GetProperty("constraintCount");
				if (property == null || property2 == null)
				{
					return;
				}
				bool num = Convert.ToInt32(property.GetValue(val2, null)) != 1 || Convert.ToInt32(property2.GetValue(val2, null)) != columnas;
				property.SetValue(val2, Enum.ToObject(property.PropertyType, 1), null);
				property2.SetValue(val2, columnas, null);
				float num2 = (float)columnas * val3.x + (float)(columnas - 1) * val4.x;
				PreferirAncho(medidor, num2);
				FijarAncho((Transform?)(object)val, num2);
				if (!num)
				{
					return;
				}
				int num3 = 0;
				foreach (Transform item in medidor)
				{
					if (((Component)item).gameObject.activeSelf)
					{
						num3++;
					}
				}
				int num4 = Mathf.CeilToInt((float)num3 / (float)columnas);
				Log($"medidor: {num3} cartas en {columnas} columnas -> {num4} filas, " + $"{num2:0} px (mismo para todos)");
			}
			catch (Exception ex)
			{
				Log("fallo ajustando el medidor de cartas: " + ex.Message, aviso: true);
			}
		}

		private static void EnFila(Transform contenedor, float ancho)
		{
			Component val = LayoutElementDe(contenedor);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			try
			{
				Type type = ((object)val).GetType();
				type.GetProperty("ignoreLayout")?.SetValue(val, false, null);
				type.GetProperty("preferredWidth")?.SetValue(val, ancho, null);
				type.GetProperty("minWidth")?.SetValue(val, ancho, null);
				type.GetProperty("flexibleWidth")?.SetValue(val, 0f, null);
			}
			catch (Exception ex)
			{
				Log("no se pudo meter en fila " + ((Object)contenedor).name + ": " + ex.Message, aviso: true);
			}
		}

		private static void PonerFlexible(Transform t, float valor)
		{
			Component val = LayoutElementDe(t);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			try
			{
				((object)val).GetType().GetProperty("flexibleWidth")?.SetValue(val, valor, null);
			}
			catch (Exception ex)
			{
				Log("no se pudo dar holgura a " + ((Object)t).name + ": " + ex.Message, aviso: true);
			}
		}

		private static void EstirarFranja(RectTransform seccion, Transform placa, Transform? medidor, float anchoPlaca, float sobresale)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Expected O, but got Unknown
			//IL_018c: 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)
			RectTransform val = (RectTransform)(object)((placa is RectTransform) ? placa : null);
			if (val == null)
			{
				return;
			}
			Rect rect = val.rect;
			if (((Rect)(ref rect)).width <= 1f)
			{
				return;
			}
			float num = LeerFloat(Componente(placa, "HorizontalLayoutGroup"), "spacing", 0f);
			Transform val2 = null;
			float num2 = 0f;
			foreach (Transform item in placa)
			{
				Transform val3 = item;
				if (((Component)val3).gameObject.activeSelf)
				{
					if (((Object)val3).name.Contains("Ribbon container"))
					{
						val2 = val3;
						break;
					}
					float num3 = num2;
					RectTransform val4 = (RectTransform)(object)((val3 is RectTransform) ? val3 : null);
					float num4;
					if (val4 == null)
					{
						num4 = 0f;
					}
					else
					{
						rect = val4.rect;
						num4 = ((Rect)(ref rect)).width;
					}
					num2 = num3 + (num4 + num);
				}
			}
			RectTransform val5 = (RectTransform)(object)((val2 is RectTransform) ? val2 : null);
			if (val5 == null)
			{
				return;
			}
			rect = val5.rect;
			float num5 = Original((Transform)(object)val5, ((Rect)(ref rect)).width);
			rect = val5.rect;
			ColocarDesdeIzquierda(val5, ((Rect)(ref rect)).width, xOriginal[(Transform)(object)val5]);
			float num6 = Mathf.Max(0f, anchoPlaca - num2) + Mathf.Max(0f, sobresale);
			float num7 = DistanciaHasta(seccion, val5, medidor);
			float num8 = 0f;
			foreach (Transform item2 in val2)
			{
				Transform val6 = item2;
				if (((Object)val6).name.Contains("Edge"))
				{
					RectTransform val7 = (RectTransform)(object)((val6 is RectTransform) ? val6 : null);
					if (val7 != null)
					{
						float num9 = num8;
						float num10 = xOriginal[val6];
						rect = val7.rect;
						num8 = Mathf.Max(num9, num10 + Original(val6, ((Rect)(ref rect)).width) - num5);
					}
				}
			}
			float num11 = ((num7 > 1f) ? num7 : num6) - num8 - 20f + RibbonExtra;
			if (!(num5 <= 1f) && !(num11 <= 1f))
			{
				float crece = num11 - num5;
				PonerIgnoreLayout(val2, valor: true);
				EstirarManteniendoIzquierda(val5, num11);
				int num12 = EstirarDentro(val2, num5, crece, 0);
				Log($"cinta \"{((Object)val2).name}\" {num5:0} -> {num11:0} px " + $"(calculado {num6:0}, medido {num7:0} hasta " + string.Format("\"{0}\", placa {1:0}, ", ((Object)(object)medidor != (Object)null) ? ((Object)medidor).name : "?", anchoPlaca) + $"antes {num2:0}, extra {RibbonExtra:0}, {num12} pieza(s) dentro)");
			}
		}

		private static void ColocarBanderas(RectTransform seccion, Transform placa, Transform contenedor)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)(object)((contenedor is RectTransform) ? contenedor : null);
			if (val == null)
			{
				return;
			}
			Transform val2 = null;
			foreach (Transform item in placa)
			{
				Transform val3 = item;
				if (((Object)val3).name.Contains("Image background"))
				{
					val2 = val3;
					break;
				}
			}
			RectTransform val4 = (RectTransform)(object)((val2 is RectTransform) ? val2 : null);
			if (val4 != null)
			{
				Vector3[] array = (Vector3[])(object)new Vector3[4];
				val4.GetWorldCorners(array);
				float x = ((Transform)seccion).InverseTransformPoint(array[3]).x;
				Vector3 localPosition = ((Transform)val).localPosition;
				float num = x + 24f + Mathf.Max(0f, FlagOffsetX);
				Rect rect = val.rect;
				localPosition.x = num + ((Rect)(ref rect)).width * val.pivot.x;
				((Transform)val).localPosition = localPosition;
			}
		}

		private static void ReconstruirLayout(RectTransform rt)
		{
			try
			{
				MReconstruir?.Invoke(null, new object[1] { rt });
			}
			catch (Exception ex)
			{
				Log("no se pudo reconstruir el layout: " + ex.Message, aviso: true);
			}
		}

		private static float DistanciaHasta(RectTransform seccion, RectTransform desde, Transform? hasta)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)(object)((hasta is RectTransform) ? hasta : null);
			if (val == null)
			{
				return 0f;
			}
			try
			{
				Vector3[] array = (Vector3[])(object)new Vector3[4];
				desde.GetWorldCorners(array);
				float x = ((Transform)seccion).InverseTransformPoint(array[0]).x;
				val.GetWorldCorners(array);
				float x2 = ((Transform)seccion).InverseTransformPoint(array[0]).x;
				return Mathf.Max(0f, x2 - x);
			}
			catch (Exception ex)
			{
				Log("no se pudo medir la distancia al medidor: " + ex.Message, aviso: true);
				return 0f;
			}
		}

		private static int EstirarDentro(Transform padre, float anchoViejo, float crece, int nivel)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			if (nivel > 3 || anchoViejo <= 1f)
			{
				return 0;
			}
			int num = 0;
			foreach (Transform item in padre)
			{
				Transform val = item;
				if (!((Component)val).gameObject.activeSelf)
				{
					continue;
				}
				RectTransform val2 = (RectTransform)(object)((val is RectTransform) ? val : null);
				if (val2 == null)
				{
					continue;
				}
				Rect rect;
				if (((Object)val).name.Contains("Edge"))
				{
					rect = val2.rect;
					ColocarDesdeIzquierda(val2, Original(val, ((Rect)(ref rect)).width), xOriginal[val] + crece);
					num++;
					continue;
				}
				rect = val2.rect;
				float num2 = Original(val, ((Rect)(ref rect)).width);
				float num3 = anchoViejo - num2;
				if (num3 >= -1f && num3 <= 24f)
				{
					EstirarManteniendoIzquierda(val2, num2 + crece);
					num++;
				}
				num += EstirarDentro(val, anchoViejo, crece, nivel + 1);
			}
			return num;
		}

		private static void EstirarManteniendoIzquierda(RectTransform rt, float ancho)
		{
			ColocarDesdeIzquierda(rt, ancho, xOriginal[(Transform)(object)rt]);
		}

		private static void ColocarDesdeIzquierda(RectTransform rt, float ancho, float izquierda)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			FijarAncho((Transform?)(object)rt, ancho