using System; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Bulldozer.Properties; using Bulldozer.SelectiveDecoration; using HarmonyLib; using Microsoft.CodeAnalysis; using PowerNetworkStructures; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("Semar")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.12.0")] [assembly: AssemblyInformationalVersion("1.1.12+f4cf066458e3c1927b04637db2507d251d15b545")] [assembly: AssemblyProduct("Bulldozer")] [assembly: AssemblyTitle("Bulldozer")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/mattsemar/dsp-bulldozer")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.12.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Bulldozer { public class BulldozeIcon { private static byte[] pngBytes = new byte[19377] { 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 2, 0, 0, 0, 2, 0, 8, 6, 0, 0, 0, 244, 120, 212, 250, 0, 0, 0, 4, 115, 66, 73, 84, 8, 8, 8, 8, 124, 8, 100, 136, 0, 0, 0, 9, 112, 72, 89, 115, 0, 0, 13, 215, 0, 0, 13, 215, 1, 66, 40, 155, 120, 0, 0, 0, 25, 116, 69, 88, 116, 83, 111, 102, 116, 119, 97, 114, 101, 0, 119, 119, 119, 46, 105, 110, 107, 115, 99, 97, 112, 101, 46, 111, 114, 103, 155, 238, 60, 26, 0, 0, 32, 0, 73, 68, 65, 84, 120, 156, 236, 221, 121, 220, 173, 213, 220, 199, 241, 207, 247, 116, 154, 211, 28, 149, 74, 137, 82, 146, 70, 105, 82, 137, 122, 240, 80, 66, 33, 165, 34, 67, 74, 25, 162, 40, 205, 66, 148, 16, 30, 34, 149, 68, 105, 146, 50, 115, 154, 52, 104, 164, 80, 74, 138, 230, 57, 81, 29, 213, 239, 249, 99, 93, 39, 183, 227, 12, 247, 189, 215, 186, 166, 189, 191, 239, 215, 107, 191, 120, 60, 231, 90, 235, 183, 239, 123, 223, 251, 250, 93, 107, 253, 214, 90, 138, 8, 204, 204, 204, 108, 180, 76, 106, 59, 0, 51, 51, 51, 107, 158, 19, 0, 51, 51, 179, 17, 228, 4, 192, 204, 204, 108, 4, 57, 1, 48, 51, 51, 27, 65, 78, 0, 204, 204, 204, 70, 144, 19, 0, 51, 51, 179, 17, 228, 4, 192, 204, 204, 108, 4, 57, 1, 48, 51, 51, 27, 65, 78, 0, 204, 204, 204, 70, 144, 19, 0, 51, 51, 179, 17, 228, 4, 192, 204, 204, 108, 4, 57, 1, 48, 51, 51, 27, 65, 78, 0, 204, 204, 204, 70, 144, 19, 0, 51, 51, 179, 17, 228, 4, 192, 204, 204, 108, 4, 57, 1, 48, 51, 51, 27, 65, 78, 0, 204, 204, 204, 70, 144, 19, 0, 51, 51, 179, 17, 228, 4, 192, 204, 204, 108, 4, 57, 1, 48, 51, 51, 27, 65, 78, 0, 204, 204, 204, 70, 144, 19, 0, 51, 51, 179, 17, 228, 4, 192, 204, 204, 108, 4, 57, 1, 48, 51, 51, 27, 65, 78, 0, 204, 204, 204, 70, 144, 19, 0, 51, 51, 179, 17, 228, 4, 192, 204, 204, 108, 4, 57, 1, 48, 51, 51, 27, 65, 78, 0, 204, 204, 204, 70, 144, 19, 0, 51, 51, 179, 17, 228, 4, 192, 204, 204, 108, 4, 57, 1, 48, 51, 51, 27, 65, 78, 0, 204, 204, 204, 70, 144, 19, 0, 51, 51, 179, 17, 228, 4, 192, 204, 204, 108, 4, 57, 1, 48, 51, 51, 27, 65, 78, 0, 204, 204, 204, 70, 144, 19, 0, 51, 51, 179, 17, 228, 4, 192, 204, 204, 108, 4, 57, 1, 48, 51, 51, 27, 65, 78, 0, 204, 204, 204, 70, 144, 19, 0, 51, 51, 179, 17, 228, 4, 192, 204, 204, 108, 4, 57, 1, 48, 51, 51, 27, 65, 78, 0, 204, 204, 204, 70, 144, 19, 0, 51, 51, 179, 17, 228, 4, 192, 204, 204, 108, 4, 57, 1, 48, 51, 51, 27, 65, 78, 0, 204, 204, 204, 70, 144, 19, 0, 51, 51, 179, 17, 228, 4, 192, 204, 204, 108, 4, 57, 1, 48, 51, 51, 27, 65, 78, 0, 204, 204, 204, 70, 144, 19, 0, 51, 51, 179, 17, 228, 4, 192, 204, 204, 108, 4, 57, 1, 48, 51, 51, 27, 65, 78, 0, 204, 204, 204, 70, 144, 19, 0, 51, 51, 179, 17, 228, 4, 192, 204, 204, 108, 4, 57, 1, 48, 51, 51, 27, 65, 78, 0, 204, 204, 204, 70, 144, 19, 0, 51, 51, 179, 17, 228, 4, 192, 204, 204, 108, 4, 57, 1, 48, 51, 51, 27, 65, 78, 0, 204, 204, 204, 70, 144, 19, 0, 51, 51, 179, 17, 228, 4, 192, 204, 204, 108, 4, 57, 1, 48, 51, 51, 27, 65, 78, 0, 204, 204, 204, 70, 144, 19, 0, 51, 51, 179, 17, 228, 4, 192, 204, 204, 108, 4, 57, 1, 48, 51, 51, 27, 65, 78, 0, 204, 204, 204, 70, 144, 19, 0, 51, 51, 179, 17, 228, 4, 192, 204, 204, 108, 4, 57, 1, 48, 51, 51, 27, 65, 78, 0, 204, 204, 204, 70, 144, 19, 0, 51, 51, 179, 17, 228, 4, 192, 204, 204, 108, 4, 57, 1, 48, 51, 51, 27, 65, 78, 0, 204, 204, 204, 70, 144, 19, 0, 51, 51, 179, 17, 228, 4, 192, 204, 204, 108, 4, 77, 110, 59, 0, 27, 63, 73, 47, 4, 94, 5, 60, 31, 88, 6, 120, 54, 48, 79, 171, 65, 153, 213, 235, 110, 224, 242, 234, 117, 86, 68, 252, 163, 229, 120, 204, 134, 134, 34, 162, 237, 24, 108, 22, 36, 45, 4, 124, 24, 216, 30, 88, 161, 229, 112, 204, 218, 116, 19, 240, 246, 136, 184, 168, 237, 64, 204, 134, 129, 19, 128, 142, 146, 52, 7, 176, 7, 176, 31, 176, 88, 203, 225, 152, 117, 197, 83, 192, 30, 17, 241, 229, 182, 3, 49, 235, 59, 39, 0, 29, 36, 105, 97, 224, 20, 224, 149, 109, 199, 98, 214, 65, 143, 3, 235, 68, 196, 181, 109, 7, 98, 214, 103, 78, 0, 58, 70, 210, 10, 192, 143, 128, 149, 219, 142, 197, 172, 195, 174, 2, 214, 14, 127, 129, 153, 13, 204, 9, 64, 135, 72, 90, 16, 184, 4, 88, 165, 237, 88, 204, 122, 224, 5, 17, 113, 125, 219, 65, 152, 245, 149, 151, 1, 118, 132, 164, 73, 192, 201, 248, 230, 111, 54, 94, 235, 180, 29, 128, 89, 159, 57, 1, 232, 142, 119, 3, 175, 110, 59, 8, 179, 30, 89, 189, 237, 0, 204, 250, 204, 251, 0, 116, 128, 164, 5, 128, 3, 219, 142, 195, 172, 103, 254, 90, 71, 163, 146, 54, 7, 214, 7, 214, 2, 22, 2, 174, 36, 237, 67, 112, 118, 68, 252, 179, 142, 62, 205, 218, 224, 4, 160, 27, 62, 8, 60, 179, 237, 32, 204, 122, 230, 242, 146, 141, 73, 90, 6, 248, 26, 105, 179, 173, 177, 94, 94, 253, 231, 77, 146, 222, 17, 17, 231, 149, 236, 215, 172, 45, 46, 2, 236, 0, 73, 127, 2, 158, 215, 118, 28, 102, 61, 242, 48, 176, 100, 68, 60, 90, 162, 49, 73, 27, 1, 231, 0, 11, 206, 230, 159, 6, 240, 233, 136, 216, 183, 68, 191, 102, 109, 114, 13, 64, 203, 170, 237, 125, 125, 243, 55, 155, 152, 189, 10, 222, 252, 231, 3, 190, 197, 236, 111, 254, 0, 2, 246, 145, 116, 84, 137, 190, 205, 218, 228, 4, 160, 125, 46, 252, 51, 155, 152, 31, 68, 196, 113, 5, 219, 59, 12, 88, 113, 130, 215, 236, 229, 36, 192, 250, 206, 9, 64, 251, 38, 250, 197, 99, 54, 170, 2, 248, 2, 240, 230, 194, 237, 238, 56, 224, 117, 78, 2, 172, 215, 92, 4, 216, 190, 165, 218, 14, 192, 172, 227, 254, 74, 170, 196, 63, 58, 34, 126, 85, 178, 97, 73, 203, 1, 139, 102, 52, 177, 151, 36, 34, 226, 3, 165, 98, 50, 107, 138, 19, 128, 246, 45, 153, 113, 237, 222, 192, 15, 51, 251, 63, 1, 88, 119, 192, 107, 223, 14, 92, 150, 217, 127, 223, 29, 8, 108, 151, 113, 237, 247, 138, 69, 210, 142, 29, 129, 65, 11, 226, 78, 0, 14, 159, 205, 191, 185, 39, 34, 238, 27, 176, 253, 241, 88, 173, 64, 27, 78, 2, 172, 151, 156, 0, 180, 111, 238, 140, 107, 127, 30, 17, 127, 204, 233, 92, 82, 206, 186, 230, 91, 115, 251, 239, 59, 73, 15, 102, 92, 126, 87, 223, 127, 126, 146, 238, 206, 184, 252, 129, 14, 188, 255, 219, 11, 181, 179, 151, 164, 251, 34, 226, 208, 66, 237, 153, 213, 206, 53, 0, 102, 54, 202, 126, 15, 252, 171, 80, 91, 7, 75, 122, 125, 161, 182, 204, 106, 231, 4, 192, 204, 70, 86, 68, 76, 5, 126, 93, 168, 57, 1, 39, 74, 122, 110, 161, 246, 204, 106, 229, 4, 192, 204, 70, 221, 238, 192, 212, 66, 109, 205, 15, 28, 82, 168, 45, 179, 90, 57, 1, 48, 179, 145, 22, 17, 215, 82, 246, 166, 253, 22, 73, 107, 20, 108, 207, 172, 22, 78, 0, 204, 204, 210, 106, 132, 147, 10, 181, 37, 96, 207, 66, 109, 153, 213, 198, 9, 128, 153, 141, 188, 136, 120, 146, 180, 172, 181, 84, 18, 240, 26, 73, 254, 126, 181, 78, 243, 7, 212, 204, 140, 226, 73, 192, 18, 164, 35, 133, 205, 58, 203, 9, 128, 153, 89, 165, 112, 18, 176, 102, 129, 54, 204, 106, 227, 4, 192, 204, 108, 140, 130, 73, 192, 179, 10, 132, 99, 86, 27, 39, 0, 102, 102, 211, 25, 147, 4, 156, 158, 209, 76, 206, 54, 223, 102, 181, 115, 2, 96, 102, 54, 3, 85, 18, 112, 106, 70, 19, 11, 148, 138, 197, 172, 14, 78, 0, 204, 204, 234, 161, 182, 3, 48, 155, 21, 39, 0, 102, 102, 102, 35, 200, 9, 128, 153, 153, 217, 8, 114, 2, 96, 102, 102, 54, 130, 38, 183, 29, 128, 89, 73, 146, 230, 5, 94, 1, 172, 3, 172, 13, 60, 12, 92, 14, 92, 26, 17, 23, 181, 25, 155, 153, 89, 151, 56, 1, 176, 161, 33, 105, 61, 224, 4, 96, 165, 233, 254, 95, 111, 169, 254, 255, 63, 0, 222, 21, 17, 119, 53, 29, 155, 153, 89, 215, 120, 10, 192, 134, 130, 164, 247, 1, 23, 241, 223, 55, 255, 177, 94, 7, 92, 43, 105, 237, 102, 162, 50, 51, 235, 46, 39, 0, 214, 123, 213, 209, 171, 71, 1, 115, 140, 227, 159, 47, 14, 156, 40, 105, 238, 122, 163, 50, 51, 235, 54, 39, 0, 214, 107, 146, 38, 147, 134, 253, 231, 156, 192, 101, 171, 0, 7, 213, 19, 145, 153, 89, 63, 56, 1, 176, 190, 123, 49, 240, 162, 1, 174, 219, 190, 116, 32, 102, 102, 125, 226, 4, 192, 250, 110, 221, 1, 175, 91, 70, 146, 247, 106, 55, 179, 145, 229, 4, 192, 250, 110, 173, 150, 174, 53, 51, 235, 53, 39, 0, 214, 119, 11, 182, 116, 173, 153, 89, 175, 57, 1, 48, 51, 51, 27, 65, 78, 0, 204, 204, 204, 70, 144, 19, 0, 51, 51, 179, 17, 228, 4, 192, 204, 204, 108, 4, 57, 1, 48, 51, 51, 27, 65, 78, 0, 204, 204, 204, 70, 144, 19, 0, 51, 51, 179, 17, 228, 4, 192, 204, 204, 108, 4, 57, 1, 48, 51, 51, 27, 65, 78, 0, 204, 204, 204, 70, 144, 19, 0, 51, 51, 179, 17, 228, 4, 192, 204, 204, 108, 4, 57, 1, 48, 51, 51, 27, 65, 78, 0, 204, 204, 204, 70, 144, 19, 0, 51, 51, 179, 17, 52, 185, 237, 0, 204, 204, 186, 64, 210, 36, 96, 67, 224, 37, 192, 210, 213, 107, 149, 140, 38, 55, 145, 116, 6, 112, 7, 112, 59, 112, 3, 240, 147, 136, 120, 40, 55, 86, 179, 18, 156, 0, 152, 217, 72, 147, 180, 26, 240, 1, 224, 181, 192, 18, 5, 155, 94, 18, 216, 122, 186, 255, 237, 95, 146, 126, 5, 124, 19, 56, 37, 34, 162, 96, 127, 102, 19, 226, 41, 0, 51, 27, 73, 146, 150, 145, 244, 77, 224, 26, 96, 23, 202, 222, 252, 103, 102, 78, 96, 11, 224, 187, 192, 101, 146, 54, 109, 160, 79, 179, 25, 114, 2, 96, 102, 35, 71, 210, 43, 128, 223, 1, 59, 211, 222, 247, 224, 58, 192, 175, 36, 29, 38, 73, 45, 197, 96, 35, 204, 9, 128, 153, 141, 20, 73, 239, 5, 126, 4, 44, 220, 118, 44, 149, 143, 1, 103, 72, 154, 191, 237, 64, 108, 180, 56, 1, 48, 179, 145, 33, 233, 109, 192, 151, 233, 94, 253, 211, 86, 192, 73, 30, 9, 176, 38, 57, 1, 48, 203, 243, 84, 198, 181, 254, 178, 111, 144, 164, 245, 129, 99, 219, 142, 99, 22, 182, 2, 14, 105, 59, 8, 27, 29, 78, 0, 172, 239, 230, 204, 184, 182, 68, 5, 246, 131, 25, 215, 46, 84, 160, 127, 27, 7, 73, 243, 2, 223, 3, 230, 110, 59, 150, 217, 248, 184, 164, 141, 218, 14, 194, 70, 67, 215, 134, 193, 108, 98, 142, 146, 148, 187, 166, 120, 181, 140, 107, 15, 149, 116, 111, 102, 255, 57, 230, 0, 94, 157, 113, 253, 253, 5, 98, 184, 39, 227, 218, 38, 170, 206, 45, 217, 19, 88, 182, 237, 32, 198, 233, 8, 96, 253, 182, 131, 176, 225, 231, 4, 160, 223, 54, 109, 185, 255, 13, 91, 238, 63, 215, 237, 5, 218, 200, 73, 0, 22, 47, 208, 191, 205, 134, 164, 69, 129, 125, 218, 142, 99, 2, 94, 42, 233, 13, 17, 113, 90, 219, 129, 216, 112, 243, 20, 128, 141, 178, 59, 10, 180, 225, 17, 128, 238, 123, 61, 253, 155, 110, 217, 169, 237, 0, 108, 248, 57, 1, 176, 81, 117, 125, 68, 148, 152, 2, 184, 59, 227, 90, 143, 0, 52, 99, 171, 182, 3, 24, 192, 43, 188, 44, 208, 234, 230, 4, 160, 69, 146, 118, 39, 111, 175, 113, 27, 220, 153, 133, 218, 241, 8, 64, 135, 73, 154, 27, 120, 69, 219, 113, 12, 96, 30, 96, 243, 182, 131, 176, 225, 230, 26, 128, 22, 72, 90, 136, 180, 28, 233, 141, 109, 199, 50, 194, 206, 40, 212, 142, 19, 128, 110, 91, 22, 152, 183, 237, 32, 6, 180, 82, 219, 1, 216, 112, 243, 8, 64, 195, 36, 173, 13, 92, 137, 111, 254, 109, 154, 18, 17, 151, 150, 104, 40, 34, 30, 7, 254, 62, 224, 229, 243, 75, 90, 176, 68, 28, 54, 83, 75, 183, 29, 64, 134, 62, 199, 110, 61, 224, 17, 128, 6, 85, 67, 254, 159, 3, 230, 106, 59, 150, 17, 22, 192, 222, 133, 219, 188, 7, 120, 198, 128, 215, 110, 72, 218, 150, 214, 234, 177, 84, 198, 181, 55, 145, 150, 15, 62, 153, 209, 198, 246, 192, 219, 6, 188, 54, 39, 118, 179, 217, 114, 2, 208, 128, 106, 200, 255, 27, 192, 27, 218, 142, 197, 248, 102, 68, 92, 94, 184, 205, 187, 129, 231, 14, 120, 237, 38, 56, 1, 168, 83, 206, 240, 255, 133, 17, 113, 78, 78, 231, 146, 230, 97, 240, 4, 160, 175, 83, 23, 214, 19, 158, 2, 168, 217, 152, 33, 127, 223, 252, 219, 119, 57, 176, 123, 13, 237, 94, 147, 113, 237, 38, 197, 162, 48, 51, 155, 0, 39, 0, 53, 146, 180, 7, 240, 107, 6, 127, 58, 180, 114, 110, 3, 182, 142, 136, 199, 106, 104, 251, 188, 140, 107, 215, 241, 114, 47, 51, 107, 131, 19, 128, 26, 72, 90, 72, 210, 247, 129, 47, 224, 249, 254, 46, 184, 28, 88, 47, 34, 110, 171, 169, 253, 243, 51, 174, 157, 76, 255, 119, 84, 52, 179, 30, 114, 2, 80, 152, 164, 117, 240, 144, 127, 87, 4, 112, 28, 240, 178, 26, 111, 254, 84, 109, 223, 148, 209, 132, 167, 1, 204, 172, 113, 78, 0, 10, 170, 134, 252, 47, 194, 67, 254, 93, 240, 51, 96, 157, 136, 216, 37, 34, 30, 109, 160, 191, 156, 105, 0, 39, 0, 102, 214, 56, 39, 0, 5, 84, 67, 254, 167, 225, 33, 255, 54, 5, 105, 228, 229, 19, 192, 234, 17, 177, 69, 68, 92, 217, 96, 255, 57, 9, 192, 122, 213, 129, 53, 102, 102, 141, 241, 50, 192, 76, 213, 144, 255, 41, 192, 10, 53, 118, 115, 5, 112, 56, 121, 235, 145, 135, 81, 144, 142, 244, 253, 27, 112, 91, 68, 76, 109, 49, 150, 156, 4, 96, 50, 176, 53, 240, 205, 66, 177, 152, 153, 205, 150, 19, 128, 12, 146, 222, 79, 58, 187, 187, 206, 167, 254, 47, 1, 31, 106, 249, 230, 102, 179, 17, 17, 183, 72, 186, 21, 88, 110, 192, 38, 222, 132, 19, 0, 51, 107, 144, 167, 0, 6, 32, 105, 225, 106, 200, 255, 104, 234, 187, 249, 63, 4, 188, 49, 34, 246, 240, 205, 191, 55, 114, 70, 1, 54, 247, 52, 128, 153, 53, 201, 9, 192, 4, 73, 90, 151, 52, 215, 188, 77, 141, 221, 92, 1, 172, 21, 17, 167, 213, 216, 135, 149, 151, 147, 0, 204, 73, 154, 6, 48, 51, 107, 132, 19, 128, 9, 168, 134, 252, 47, 164, 222, 249, 254, 47, 1, 27, 68, 196, 159, 107, 236, 195, 234, 241, 67, 224, 169, 140, 235, 223, 84, 42, 16, 51, 179, 217, 113, 2, 48, 14, 213, 144, 255, 233, 120, 200, 223, 102, 33, 34, 238, 34, 111, 83, 32, 79, 3, 152, 89, 99, 156, 0, 204, 198, 152, 33, 255, 215, 215, 216, 141, 135, 252, 135, 199, 169, 25, 215, 122, 26, 192, 204, 26, 227, 4, 96, 22, 36, 237, 73, 253, 67, 254, 95, 196, 67, 254, 195, 228, 52, 60, 13, 96, 102, 61, 224, 4, 96, 6, 198, 12, 249, 127, 158, 122, 135, 252, 223, 16, 17, 239, 247, 144, 255, 240, 240, 52, 128, 153, 245, 133, 19, 128, 233, 84, 67, 254, 87, 81, 239, 144, 255, 229, 192, 154, 17, 113, 122, 141, 125, 88, 123, 60, 13, 96, 102, 157, 231, 4, 96, 140, 49, 67, 254, 203, 215, 216, 205, 23, 128, 13, 35, 226, 230, 26, 251, 176, 118, 121, 26, 192, 204, 58, 207, 9, 64, 69, 210, 238, 52, 51, 228, 191, 167, 135, 252, 135, 155, 167, 1, 198, 109, 51, 73, 59, 72, 90, 164, 237, 64, 204, 70, 145, 19, 0, 64, 210, 22, 164, 155, 127, 93, 60, 228, 63, 122, 60, 13, 48, 123, 171, 3, 39, 0, 119, 75, 250, 133, 164, 61, 36, 13, 186, 149, 178, 153, 77, 208, 200, 39, 0, 146, 22, 7, 190, 7, 204, 81, 83, 23, 30, 242, 31, 77, 158, 6, 24, 191, 201, 192, 203, 73, 127, 43, 183, 72, 186, 82, 210, 39, 36, 173, 222, 114, 92, 102, 67, 109, 228, 19, 0, 210, 89, 236, 11, 215, 208, 238, 131, 192, 54, 30, 242, 31, 77, 158, 6, 200, 178, 38, 112, 16, 112, 141, 164, 63, 75, 58, 82, 210, 38, 146, 234, 74, 210, 205, 70, 146, 19, 0, 216, 168, 134, 54, 127, 67, 218, 216, 231, 140, 26, 218, 182, 254, 240, 52, 64, 190, 21, 128, 15, 0, 83, 128, 59, 37, 29, 39, 105, 43, 73, 243, 182, 27, 150, 89, 255, 57, 1, 128, 13, 11, 183, 119, 52, 176, 145, 135, 252, 13, 79, 3, 148, 182, 56, 176, 19, 112, 38, 112, 159, 164, 51, 37, 237, 36, 105, 177, 118, 195, 50, 235, 39, 39, 0, 240, 204, 66, 237, 76, 27, 242, 223, 203, 67, 254, 6, 158, 6, 168, 217, 188, 192, 86, 192, 113, 192, 93, 146, 166, 72, 218, 75, 82, 157, 187, 118, 154, 13, 21, 39, 0, 101, 252, 134, 84, 229, 239, 33, 127, 155, 222, 41, 25, 215, 122, 26, 96, 124, 230, 32, 213, 242, 28, 5, 252, 89, 210, 53, 146, 14, 146, 180, 102, 203, 113, 153, 117, 154, 19, 128, 124, 211, 134, 252, 255, 210, 118, 32, 214, 73, 167, 227, 105, 128, 166, 173, 14, 124, 130, 116, 136, 215, 49, 45, 199, 98, 214, 89, 78, 0, 242, 236, 224, 33, 127, 155, 21, 79, 3, 180, 110, 190, 182, 3, 48, 235, 42, 39, 0, 121, 46, 108, 59, 0, 235, 5, 79, 3, 152, 89, 231, 56, 1, 48, 171, 159, 167, 1, 204, 172, 115, 156, 0, 152, 213, 204, 211, 0, 189, 229, 189, 6, 108, 168, 57, 1, 48, 107, 134, 167, 1, 250, 103, 91, 73, 183, 72, 58, 90, 210, 102, 146, 38, 183, 29, 144, 89, 73, 78, 0, 204, 154, 225, 105, 128, 126, 90, 14, 120, 63, 240, 75, 210, 126, 3, 199, 75, 218, 90, 146, 139, 11, 173, 247, 156, 0, 152, 53, 160, 154, 6, 56, 47, 163, 9, 79, 3, 180, 111, 81, 96, 71, 224, 12, 224, 94, 239, 68, 104, 125, 231, 4, 192, 172, 57, 62, 27, 224, 63, 29, 7, 108, 79, 250, 185, 60, 210, 114, 44, 19, 53, 163, 157, 8, 247, 148, 180, 124, 171, 81, 153, 77, 128, 19, 0, 179, 230, 120, 26, 224, 63, 61, 28, 17, 223, 137, 136, 109, 73, 251, 252, 191, 6, 248, 58, 112, 87, 187, 97, 77, 216, 180, 157, 8, 63, 15, 220, 44, 233, 42, 73, 7, 72, 122, 113, 203, 113, 153, 205, 146, 19, 0, 179, 134, 84, 211, 0, 23, 100, 52, 49, 180, 211, 0, 17, 241, 120, 68, 156, 27, 17, 239, 2, 150, 38, 29, 210, 117, 4, 240, 167, 118, 35, 27, 200, 26, 192, 129, 192, 213, 192, 241, 237, 134, 98, 54, 115, 78, 0, 204, 154, 229, 213, 0, 179, 17, 17, 79, 69, 196, 175, 35, 226, 35, 17, 177, 18, 240, 66, 224, 227, 164, 51, 55, 162, 221, 232, 38, 108, 193, 182, 3, 48, 155, 25, 39, 0, 102, 205, 242, 52, 192, 4, 69, 196, 239, 35, 226, 147, 17, 241, 18, 96, 89, 224, 125, 192, 207, 128, 127, 181, 27, 153, 89, 191, 57, 1, 48, 107, 80, 68, 220, 137, 167, 1, 6, 22, 17, 183, 69, 196, 151, 35, 98, 11, 210, 81, 222, 125, 45, 34, 52, 107, 157, 19, 0, 179, 230, 121, 26, 160, 128, 136, 120, 112, 72, 138, 8, 103, 102, 174, 182, 3, 176, 225, 230, 4, 192, 172, 121, 158, 6, 40, 108, 200, 138, 8, 167, 121, 149, 164, 63, 75, 58, 82, 210, 203, 36, 205, 209, 118, 64, 54, 92, 156, 0, 152, 53, 204, 211, 0, 245, 26, 178, 34, 194, 21, 128, 15, 144, 54, 145, 186, 83, 210, 55, 37, 189, 78, 146, 207, 41, 176, 108, 78, 0, 204, 218, 225, 105, 128, 134, 12, 81, 17, 225, 226, 192, 206, 192, 89, 164, 157, 8, 79, 151, 180, 163, 147, 65, 27, 148, 19, 0, 179, 118, 120, 26, 160, 5, 211, 21, 17, 46, 193, 191, 139, 8, 255, 222, 110, 100, 19, 54, 31, 240, 122, 210, 62, 3, 119, 73, 250, 165, 164, 247, 75, 90, 174, 229, 184, 172, 71, 156, 0, 152, 181, 192, 211, 0, 237, 139, 136, 135, 198, 20, 17, 46, 65, 127, 139, 8, 39, 3, 155, 1, 71, 3, 183, 72, 186, 66, 210, 254, 146, 94, 212, 114, 92, 214, 113, 78, 0, 204, 218, 227, 105, 128, 142, 24, 178, 34, 194, 181, 128, 131, 129, 223, 74, 186, 73, 210, 231, 36, 109, 44, 201, 223, 247, 246, 31, 252, 129, 48, 107, 143, 167, 1, 58, 104, 200, 138, 8, 159, 11, 124, 16, 56, 159, 84, 68, 248, 13, 73, 175, 149, 52, 79, 203, 113, 89, 7, 56, 1, 48, 107, 137, 167, 1, 250, 97, 136, 138, 8, 151, 0, 118, 1, 126, 64, 42, 34, 60, 77, 210, 14, 146, 22, 105, 57, 46, 107, 137, 19, 0, 179, 118, 121, 26, 160, 71, 134, 168, 136, 112, 126, 96, 27, 224, 4, 224, 110, 73, 191, 144, 180, 187, 164, 101, 91, 142, 203, 26, 228, 4, 192, 172, 93, 158, 6, 232, 169, 25, 20, 17, 190, 26, 248, 26, 112, 103, 187, 145, 77, 216, 100, 224, 229, 192, 23, 129, 91, 37, 93, 46, 105, 63, 73, 171, 181, 28, 151, 213, 204, 9, 128, 89, 139, 60, 13, 48, 28, 170, 34, 194, 31, 69, 196, 187, 129, 103, 3, 27, 0, 159, 1, 110, 104, 55, 178, 129, 172, 13, 28, 2, 252, 78, 210, 141, 146, 142, 144, 180, 106, 219, 65, 89, 121, 78, 0, 204, 218, 231, 105, 128, 33, 82, 21, 17, 94, 28, 17, 31, 141, 136, 149, 129, 85, 129, 143, 1, 151, 209, 191, 34, 194, 21, 129, 15, 3, 215, 73, 186, 160, 170, 25, 112, 1, 225, 144, 112, 2, 96, 214, 62, 79, 3, 12, 177, 136, 248, 67, 68, 28, 30, 17, 235, 145, 138, 8, 119, 3, 126, 74, 255, 138, 8, 55, 34, 213, 12, 220, 46, 233, 211, 146, 158, 209, 118, 64, 150, 199, 9, 128, 89, 203, 60, 13, 48, 58, 170, 34, 194, 175, 68, 196, 150, 164, 186, 129, 183, 146, 70, 128, 250, 84, 68, 184, 8, 240, 17, 224, 143, 146, 222, 220, 118, 48, 54, 56, 39, 0, 102, 221, 224, 105, 128, 17, 83, 21, 17, 158, 28, 17, 219, 209, 207, 34, 194, 165, 129, 147, 37, 253, 92, 210, 11, 218, 14, 198, 38, 78, 17, 125, 155, 146, 42, 75, 210, 95, 128, 231, 12, 120, 249, 113, 192, 195, 229, 162, 25, 58, 1, 60, 2, 220, 63, 131, 215, 221, 17, 113, 95, 139, 177, 117, 138, 164, 37, 129, 219, 24, 60, 41, 255, 113, 68, 188, 170, 96, 72, 227, 34, 105, 47, 224, 168, 1, 47, 63, 58, 34, 246, 42, 25, 207, 48, 144, 36, 224, 165, 164, 164, 110, 107, 96, 165, 118, 35, 26, 151, 199, 128, 157, 35, 226, 187, 109, 7, 98, 227, 55, 185, 237, 0, 122, 110, 231, 182, 3, 232, 51, 73, 183, 2, 151, 142, 121, 93, 17, 17, 143, 182, 27, 85, 59, 34, 226, 78, 73, 23, 0, 155, 12, 216, 196, 230, 146, 22, 141, 136, 251, 75, 198, 101, 205, 139, 244, 84, 118, 113, 245, 250, 168, 164, 85, 248, 119, 50, 176, 46, 160, 22, 195, 155, 153, 121, 72, 163, 1, 43, 71, 196, 65, 109, 7, 99, 227, 227, 41, 0, 107, 211, 114, 164, 2, 182, 207, 146, 230, 192, 31, 150, 116, 165, 164, 131, 36, 61, 191, 221, 208, 90, 225, 105, 0, 251, 47, 211, 21, 17, 46, 67, 183, 139, 8, 15, 148, 244, 29, 175, 20, 232, 7, 39, 0, 214, 37, 147, 129, 53, 129, 79, 0, 55, 72, 186, 164, 218, 157, 108, 241, 150, 227, 106, 138, 87, 3, 216, 44, 69, 196, 237, 61, 40, 34, 124, 11, 112, 142, 164, 185, 218, 14, 196, 102, 205, 9, 128, 117, 217, 122, 164, 221, 201, 110, 151, 116, 182, 164, 77, 91, 142, 167, 86, 94, 13, 96, 19, 49, 93, 17, 225, 226, 116, 171, 136, 240, 229, 192, 177, 109, 7, 97, 179, 230, 4, 192, 250, 96, 78, 224, 127, 129, 95, 73, 250, 169, 164, 117, 218, 14, 168, 70, 158, 6, 176, 9, 139, 136, 169, 99, 118, 34, 92, 154, 110, 236, 68, 184, 131, 164, 3, 91, 236, 223, 102, 195, 9, 128, 245, 205, 43, 129, 223, 84, 39, 153, 13, 227, 246, 164, 158, 6, 176, 44, 145, 116, 101, 39, 194, 3, 36, 237, 216, 112, 159, 54, 78, 78, 0, 250, 183, 53, 167, 37, 219, 144, 246, 42, 255, 150, 164, 229, 218, 14, 166, 148, 17, 155, 6, 240, 223, 94, 3, 58, 80, 68, 248, 21, 73, 203, 55, 212, 151, 77, 128, 247, 1, 144, 206, 7, 54, 110, 59, 14, 203, 242, 24, 240, 121, 224, 240, 136, 232, 253, 190, 12, 146, 118, 3, 142, 201, 104, 226, 124, 224, 170, 66, 225, 204, 206, 54, 164, 237, 109, 7, 113, 80, 68, 28, 88, 48, 22, 155, 0, 73, 11, 145, 234, 6, 182, 6, 94, 5, 212, 185, 181, 239, 15, 35, 226, 181, 53, 182, 111, 3, 112, 2, 32, 29, 9, 124, 160, 237, 56, 172, 136, 123, 128, 131, 128, 255, 139, 136, 39, 218, 14, 102, 80, 5, 54, 5, 234, 139, 93, 35, 194, 133, 98, 29, 80, 85, 236, 111, 78, 74, 6, 222, 0, 44, 86, 67, 55, 219, 68, 196, 25, 53, 180, 107, 3, 26, 246, 47, 152, 241, 184, 172, 237, 0, 172, 152, 37, 128, 47, 1, 215, 74, 218, 170, 237, 96, 6, 85, 96, 26, 160, 47, 254, 218, 118, 0, 150, 76, 87, 68, 184, 60, 176, 47, 112, 111, 225, 110, 142, 150, 180, 64, 225, 54, 45, 131, 19, 0, 56, 13, 248, 109, 219, 65, 88, 81, 43, 3, 103, 74, 58, 175, 199, 43, 6, 114, 86, 3, 244, 193, 83, 192, 213, 109, 7, 97, 255, 45, 34, 30, 137, 136, 79, 1, 43, 80, 54, 17, 88, 22, 120, 95, 161, 182, 172, 128, 145, 159, 2, 0, 144, 180, 6, 105, 36, 96, 206, 182, 99, 177, 226, 2, 56, 25, 248, 88, 68, 220, 210, 118, 48, 227, 85, 77, 3, 252, 13, 152, 163, 237, 88, 106, 242, 235, 136, 216, 176, 237, 32, 108, 246, 170, 167, 246, 83, 72, 117, 2, 185, 110, 5, 158, 27, 17, 79, 22, 104, 203, 50, 121, 4, 0, 136, 136, 171, 73, 187, 87, 249, 112, 154, 225, 35, 210, 110, 105, 215, 87, 103, 152, 47, 212, 118, 64, 227, 81, 77, 3, 124, 187, 237, 56, 106, 116, 102, 219, 1, 216, 248, 68, 196, 35, 164, 218, 128, 31, 22, 104, 110, 57, 192, 197, 128, 29, 225, 17, 128, 49, 170, 167, 174, 99, 72, 155, 206, 120, 27, 203, 225, 116, 47, 112, 48, 240, 213, 136, 232, 226, 94, 234, 79, 171, 150, 78, 221, 192, 240, 141, 76, 253, 157, 244, 20, 88, 122, 142, 217, 106, 84, 21, 10, 126, 143, 252, 205, 166, 126, 25, 17, 155, 23, 8, 201, 50, 57, 1, 152, 129, 234, 131, 254, 98, 96, 13, 96, 254, 150, 195, 153, 168, 103, 2, 251, 208, 252, 137, 97, 143, 2, 119, 84, 175, 219, 171, 215, 157, 192, 124, 192, 82, 164, 221, 201, 150, 174, 254, 251, 18, 180, 63, 250, 244, 39, 224, 163, 93, 175, 74, 150, 116, 12, 105, 221, 246, 48, 57, 32, 34, 14, 110, 59, 8, 155, 56, 73, 115, 146, 166, 3, 114, 147, 128, 23, 68, 196, 245, 5, 66, 178, 12, 78, 0, 134, 136, 164, 249, 128, 95, 1, 47, 105, 160, 187, 251, 73, 67, 130, 103, 2, 231, 77, 228, 24, 90, 73, 147, 129, 21, 73, 67, 129, 91, 145, 182, 45, 109, 43, 33, 184, 16, 248, 80, 68, 116, 114, 53, 136, 164, 165, 128, 155, 128, 121, 219, 142, 165, 144, 191, 2, 171, 86, 195, 202, 214, 67, 146, 150, 0, 254, 12, 228, 84, 244, 239, 25, 17, 95, 40, 20, 146, 13, 200, 9, 192, 144, 144, 52, 137, 180, 162, 161, 206, 189, 224, 111, 37, 221, 240, 207, 4, 46, 40, 181, 214, 94, 210, 51, 249, 119, 50, 240, 74, 210, 217, 226, 77, 10, 210, 208, 230, 190, 17, 241, 151, 134, 251, 158, 45, 73, 59, 1, 223, 164, 155, 231, 192, 79, 196, 163, 192, 70, 17, 113, 101, 219, 129, 88, 30, 73, 135, 2, 31, 207, 104, 226, 180, 136, 120, 99, 169, 120, 108, 48, 78, 0, 134, 132, 164, 163, 128, 189, 106, 106, 254, 38, 210, 94, 226, 167, 70, 205, 31, 24, 73, 139, 1, 251, 145, 134, 189, 155, 174, 195, 120, 156, 116, 250, 224, 97, 17, 241, 96, 195, 125, 207, 146, 164, 93, 72, 167, 171, 245, 53, 9, 8, 224, 205, 17, 49, 236, 203, 27, 71, 130, 164, 133, 129, 155, 129, 133, 7, 108, 226, 158, 136, 120, 102, 193, 144, 108, 0, 109, 207, 195, 90, 1, 146, 246, 160, 158, 155, 255, 61, 192, 30, 192, 42, 17, 113, 74, 221, 55, 127, 128, 136, 184, 47, 34, 62, 64, 90, 203, 127, 18, 205, 238, 23, 63, 55, 240, 97, 224, 70, 73, 123, 86, 243, 157, 157, 16, 17, 223, 4, 222, 73, 63, 247, 207, 127, 4, 120, 131, 111, 254, 195, 163, 74, 144, 63, 155, 209, 196, 18, 146, 86, 41, 21, 143, 13, 198, 35, 0, 61, 39, 233, 117, 192, 25, 148, 77, 230, 254, 1, 28, 9, 28, 17, 17, 127, 47, 216, 238, 132, 73, 90, 19, 248, 52, 105, 106, 160, 105, 55, 2, 251, 68, 196, 105, 45, 244, 61, 67, 146, 222, 74, 58, 247, 96, 137, 182, 99, 25, 167, 27, 72, 91, 192, 94, 215, 118, 32, 86, 150, 164, 103, 0, 15, 48, 248, 94, 21, 239, 168, 18, 91, 107, 137, 71, 0, 122, 172, 218, 229, 238, 100, 202, 254, 30, 255, 0, 172, 17, 17, 159, 104, 251, 230, 15, 16, 17, 87, 69, 196, 22, 164, 41, 129, 166, 247, 247, 127, 30, 240, 125, 73, 23, 74, 122, 105, 195, 125, 207, 80, 68, 124, 135, 180, 67, 219, 62, 116, 123, 223, 138, 123, 129, 61, 129, 213, 124, 243, 31, 78, 213, 247, 195, 77, 25, 77, 44, 93, 42, 22, 27, 140, 19, 128, 158, 146, 244, 28, 224, 108, 210, 50, 187, 82, 206, 1, 94, 26, 17, 55, 22, 108, 179, 136, 136, 248, 10, 176, 5, 237, 220, 244, 54, 4, 46, 150, 244, 61, 73, 207, 109, 161, 255, 255, 16, 17, 255, 136, 136, 79, 147, 18, 129, 143, 3, 151, 0, 93, 168, 89, 120, 156, 244, 25, 218, 21, 88, 49, 34, 190, 208, 245, 189, 22, 44, 219, 31, 50, 174, 93, 188, 88, 20, 54, 16, 79, 1, 244, 80, 85, 128, 115, 17, 176, 106, 193, 102, 63, 77, 218, 46, 247, 169, 130, 109, 22, 87, 221, 128, 207, 166, 236, 123, 159, 136, 169, 164, 3, 135, 14, 141, 136, 7, 90, 138, 97, 134, 170, 213, 20, 47, 0, 86, 34, 111, 137, 214, 68, 252, 157, 127, 239, 253, 240, 167, 136, 248, 71, 67, 253, 90, 7, 72, 250, 36, 233, 188, 128, 65, 124, 39, 34, 182, 47, 25, 143, 77, 140, 19, 128, 158, 169, 10, 211, 126, 12, 188, 188, 80, 147, 143, 1, 239, 140, 136, 147, 10, 181, 87, 187, 106, 238, 241, 59, 164, 29, 27, 219, 114, 63, 112, 40, 112, 76, 68, 76, 109, 49, 14, 179, 214, 72, 218, 1, 56, 97, 192, 203, 127, 26, 17, 91, 150, 140, 199, 38, 198, 83, 0, 253, 243, 117, 202, 221, 252, 3, 120, 107, 159, 110, 254, 240, 244, 220, 227, 235, 129, 159, 183, 24, 198, 162, 164, 66, 201, 63, 72, 122, 83, 139, 113, 152, 181, 233, 134, 140, 107, 23, 43, 22, 133, 13, 196, 9, 64, 143, 72, 58, 0, 120, 123, 193, 38, 15, 236, 250, 86, 184, 51, 83, 109, 66, 180, 45, 105, 75, 223, 54, 61, 23, 56, 69, 210, 175, 37, 109, 208, 114, 44, 102, 77, 123, 60, 227, 218, 201, 197, 162, 176, 129, 56, 1, 232, 9, 73, 59, 2, 7, 22, 108, 242, 251, 192, 33, 5, 219, 107, 92, 53, 7, 255, 58, 224, 161, 182, 99, 1, 214, 7, 46, 146, 116, 170, 164, 21, 219, 14, 198, 204, 108, 118, 156, 0, 244, 128, 164, 205, 72, 187, 192, 149, 114, 13, 176, 83, 19, 27, 251, 212, 45, 34, 254, 8, 188, 25, 232, 202, 249, 226, 111, 4, 126, 47, 233, 40, 73, 139, 182, 29, 140, 153, 217, 204, 56, 1, 232, 184, 106, 183, 172, 211, 41, 119, 36, 236, 189, 192, 86, 195, 84, 173, 29, 17, 63, 6, 62, 218, 118, 28, 99, 204, 69, 218, 153, 241, 70, 73, 31, 170, 78, 151, 52, 51, 235, 20, 39, 0, 29, 38, 233, 89, 192, 185, 12, 190, 223, 246, 140, 236, 31, 17, 183, 20, 108, 175, 43, 142, 4, 174, 106, 59, 136, 233, 44, 66, 218, 46, 245, 143, 146, 182, 107, 59, 24, 51, 179, 177, 156, 0, 116, 84, 117, 180, 239, 217, 192, 242, 5, 155, 189, 129, 178, 83, 9, 157, 81, 77, 103, 116, 105, 20, 96, 172, 21, 128, 239, 74, 186, 68, 210, 134, 109, 7, 99, 102, 6, 78, 0, 58, 169, 58, 218, 247, 59, 192, 186, 133, 155, 222, 183, 212, 17, 190, 93, 20, 17, 63, 3, 126, 214, 118, 28, 179, 176, 30, 112, 161, 164, 211, 36, 61, 175, 237, 96, 204, 108, 180, 57, 1, 232, 166, 163, 128, 173, 10, 183, 121, 73, 68, 156, 94, 184, 205, 46, 250, 40, 221, 63, 49, 111, 27, 82, 161, 224, 209, 213, 241, 199, 102, 102, 141, 115, 2, 208, 49, 146, 246, 4, 222, 95, 67, 211, 31, 169, 161, 205, 206, 137, 136, 171, 72, 7, 36, 117, 221, 156, 164, 223, 243, 141, 146, 246, 150, 52, 119, 219, 1, 153, 217, 104, 113, 2, 208, 33, 146, 182, 34, 21, 179, 149, 246, 171, 136, 184, 160, 134, 118, 187, 234, 224, 182, 3, 152, 128, 133, 129, 207, 144, 10, 5, 223, 34, 73, 109, 7, 100, 102, 163, 193, 9, 64, 71, 72, 90, 151, 52, 239, 95, 199, 239, 164, 51, 231, 217, 55, 33, 34, 174, 7, 174, 205, 104, 226, 41, 224, 167, 133, 194, 25, 175, 229, 73, 191, 255, 75, 37, 109, 220, 112, 223, 102, 54, 130, 156, 0, 116, 128, 164, 229, 41, 127, 180, 239, 52, 1, 156, 85, 67, 187, 93, 119, 102, 198, 181, 147, 128, 247, 145, 142, 31, 254, 109, 153, 112, 198, 109, 93, 224, 124, 73, 103, 72, 90, 169, 225, 190, 205, 108, 132, 56, 1, 104, 89, 117, 180, 239, 185, 192, 179, 106, 234, 226, 138, 136, 248, 91, 77, 109, 119, 89, 78, 2, 0, 176, 70, 181, 170, 96, 77, 96, 23, 210, 113, 183, 77, 218, 26, 184, 78, 210, 23, 37, 249, 220, 116, 51, 43, 206, 9, 64, 139, 170, 29, 226, 78, 7, 86, 169, 177, 155, 220, 27, 97, 47, 69, 196, 21, 192, 95, 51, 154, 120, 113, 213, 206, 83, 17, 113, 28, 240, 124, 224, 0, 224, 145, 2, 225, 141, 215, 100, 96, 119, 82, 161, 224, 71, 37, 205, 211, 96, 223, 102, 54, 228, 156, 0, 180, 235, 88, 96, 179, 154, 251, 104, 60, 1, 144, 52, 191, 164, 141, 36, 237, 41, 233, 237, 146, 94, 88, 237, 109, 208, 180, 156, 169, 143, 53, 198, 254, 31, 17, 241, 207, 136, 56, 152, 148, 8, 124, 157, 102, 207, 30, 88, 8, 248, 20, 112, 189, 164, 237, 93, 40, 104, 102, 37, 56, 1, 104, 137, 164, 131, 128, 29, 106, 238, 230, 111, 17, 113, 93, 205, 125, 60, 77, 210, 34, 146, 78, 2, 30, 6, 46, 0, 62, 15, 124, 139, 84, 144, 247, 128, 164, 247, 53, 124, 243, 250, 113, 198, 181, 107, 204, 232, 127, 140, 136, 59, 35, 226, 93, 164, 17, 130, 31, 101, 180, 63, 136, 229, 128, 111, 3, 151, 73, 218, 164, 225, 190, 205, 108, 200, 56, 1, 104, 129, 164, 183, 3, 159, 104, 160, 171, 198, 246, 252, 151, 180, 41, 233, 70, 255, 86, 102, 252, 185, 90, 16, 248, 18, 240, 243, 234, 140, 131, 38, 228, 188, 255, 101, 102, 117, 136, 79, 68, 92, 23, 17, 175, 6, 94, 73, 58, 93, 177, 73, 235, 0, 83, 36, 157, 37, 105, 229, 134, 251, 54, 179, 33, 225, 4, 160, 97, 146, 94, 78, 26, 66, 110, 194, 29, 77, 116, 34, 105, 73, 210, 82, 195, 165, 199, 241, 207, 95, 14, 124, 179, 222, 136, 158, 150, 251, 254, 103, 123, 8, 83, 68, 252, 28, 88, 11, 216, 25, 184, 45, 179, 191, 137, 122, 29, 112, 173, 164, 99, 36, 45, 209, 112, 223, 102, 214, 115, 78, 0, 26, 36, 105, 85, 202, 30, 237, 59, 59, 77, 85, 174, 255, 31, 176, 232, 4, 254, 253, 171, 37, 237, 82, 87, 48, 211, 68, 196, 125, 192, 227, 25, 77, 44, 50, 206, 126, 158, 138, 136, 111, 1, 43, 1, 251, 211, 124, 161, 224, 110, 192, 77, 146, 62, 38, 105, 222, 6, 251, 54, 179, 30, 115, 2, 208, 144, 234, 41, 249, 92, 82, 65, 87, 83, 106, 79, 0, 36, 189, 144, 244, 36, 58, 81, 31, 43, 29, 203, 76, 220, 153, 113, 237, 132, 142, 97, 174, 10, 5, 15, 5, 158, 71, 74, 138, 154, 44, 20, 124, 6, 112, 24, 169, 80, 112, 71, 23, 10, 154, 217, 236, 56, 1, 104, 192, 152, 163, 125, 159, 211, 112, 215, 77, 76, 1, 172, 53, 224, 117, 43, 74, 154, 200, 168, 193, 160, 114, 146, 160, 9, 37, 0, 211, 68, 196, 93, 17, 241, 30, 96, 117, 224, 156, 140, 254, 7, 177, 44, 112, 60, 112, 69, 53, 221, 100, 102, 54, 67, 78, 0, 106, 86, 45, 127, 59, 153, 84, 184, 213, 180, 38, 166, 0, 6, 77, 0, 0, 214, 46, 22, 197, 204, 53, 158, 0, 76, 19, 17, 191, 143, 136, 255, 5, 54, 7, 174, 202, 105, 107, 0, 107, 2, 191, 144, 244, 67, 73, 117, 238, 51, 97, 102, 61, 229, 4, 160, 126, 159, 103, 176, 33, 242, 190, 200, 57, 122, 183, 235, 195, 212, 79, 148, 104, 36, 34, 126, 73, 74, 118, 222, 14, 52, 189, 43, 227, 107, 128, 223, 73, 250, 106, 131, 171, 47, 204, 172, 7, 156, 0, 212, 72, 210, 94, 192, 30, 45, 134, 48, 158, 170, 252, 92, 151, 183, 116, 237, 120, 229, 252, 12, 138, 141, 160, 68, 114, 2, 169, 80, 240, 227, 192, 223, 75, 181, 61, 14, 115, 0, 239, 6, 254, 36, 105, 63, 23, 10, 154, 25, 56, 1, 168, 141, 164, 215, 3, 159, 107, 57, 140, 165, 26, 232, 99, 208, 155, 248, 205, 17, 113, 127, 209, 72, 102, 172, 19, 9, 192, 52, 17, 241, 104, 68, 124, 146, 84, 40, 248, 21, 10, 141, 50, 140, 211, 51, 128, 67, 72, 137, 192, 78, 45, 237, 206, 104, 102, 29, 225, 47, 128, 26, 72, 122, 9, 112, 18, 237, 255, 124, 107, 31, 1, 136, 136, 27, 72, 75, 27, 39, 234, 211, 165, 99, 153, 137, 37, 7, 188, 46, 168, 177, 136, 50, 34, 238, 142, 136, 221, 128, 23, 145, 10, 68, 155, 244, 108, 224, 56, 82, 161, 224, 43, 26, 238, 219, 204, 58, 162, 237, 27, 212, 208, 145, 180, 2, 233, 11, 189, 212, 48, 107, 206, 28, 123, 19, 83, 0, 0, 239, 1, 238, 158, 192, 191, 255, 89, 68, 252, 95, 93, 193, 76, 35, 105, 49, 96, 238, 1, 47, 191, 47, 34, 166, 150, 140, 103, 70, 34, 226, 143, 17, 241, 58, 210, 153, 16, 87, 214, 221, 223, 116, 214, 0, 126, 38, 233, 220, 106, 57, 167, 153, 141, 16, 39, 0, 5, 73, 90, 132, 180, 214, 255, 153, 133, 154, 188, 25, 56, 56, 227, 250, 38, 166, 0, 136, 136, 123, 128, 109, 24, 223, 233, 123, 23, 0, 59, 213, 26, 208, 191, 229, 188, 255, 70, 143, 255, 141, 136, 41, 164, 149, 34, 59, 144, 119, 138, 225, 32, 94, 5, 92, 35, 233, 107, 213, 126, 21, 102, 54, 2, 156, 0, 20, 82, 237, 27, 127, 6, 240, 130, 66, 77, 62, 64, 250, 98, 206, 57, 112, 166, 177, 125, 7, 34, 226, 34, 96, 53, 224, 27, 204, 120, 94, 251, 97, 96, 79, 96, 147, 136, 104, 234, 230, 154, 243, 254, 27, 77, 0, 224, 233, 66, 193, 111, 147, 10, 5, 247, 37, 253, 204, 154, 50, 7, 176, 43, 169, 62, 224, 19, 213, 222, 21, 102, 54, 196, 156, 0, 148, 243, 13, 160, 212, 9, 109, 83, 129, 173, 35, 226, 122, 210, 65, 51, 131, 22, 138, 45, 83, 109, 63, 220, 136, 136, 120, 56, 34, 222, 73, 58, 248, 103, 125, 210, 89, 246, 59, 145, 18, 131, 69, 34, 226, 11, 17, 145, 51, 165, 49, 81, 91, 102, 92, 219, 200, 57, 10, 51, 18, 17, 143, 69, 196, 167, 72, 133, 130, 95, 166, 217, 66, 193, 5, 128, 131, 72, 137, 192, 46, 46, 20, 52, 27, 94, 254, 227, 46, 64, 210, 193, 192, 219, 10, 54, 185, 75, 68, 156, 15, 233, 102, 0, 252, 62, 163, 173, 173, 203, 132, 52, 126, 85, 165, 251, 37, 17, 113, 76, 68, 28, 95, 157, 156, 247, 84, 211, 113, 0, 91, 101, 92, 219, 248, 8, 192, 244, 34, 226, 158, 136, 120, 31, 41, 129, 250, 65, 195, 221, 47, 77, 74, 106, 175, 146, 180, 69, 195, 125, 155, 89, 3, 156, 0, 100, 146, 180, 19, 233, 0, 152, 82, 246, 143, 136, 147, 166, 251, 223, 114, 138, 195, 26, 79, 0, 186, 64, 210, 90, 192, 114, 25, 77, 52, 118, 148, 242, 236, 68, 196, 245, 17, 177, 21, 176, 41, 205, 236, 157, 48, 214, 234, 192, 79, 36, 253, 88, 210, 139, 26, 238, 219, 204, 106, 228, 4, 32, 131, 164, 205, 129, 175, 21, 108, 242, 155, 213, 97, 50, 211, 187, 34, 163, 205, 117, 36, 53, 181, 26, 160, 75, 114, 158, 254, 1, 126, 90, 36, 138, 130, 34, 226, 60, 224, 37, 164, 209, 166, 91, 27, 238, 126, 75, 224, 106, 73, 199, 74, 106, 164, 184, 212, 204, 234, 229, 4, 96, 64, 213, 178, 169, 211, 40, 119, 180, 239, 207, 73, 187, 181, 205, 72, 206, 8, 128, 200, 191, 25, 246, 81, 206, 200, 199, 213, 17, 209, 153, 17, 128, 177, 170, 66, 193, 147, 128, 149, 129, 125, 128, 135, 26, 236, 126, 18, 240, 14, 82, 125, 192, 129, 146, 230, 111, 176, 111, 51, 43, 204, 9, 192, 0, 170, 39, 160, 146, 71, 251, 94, 11, 188, 33, 34, 102, 86, 236, 117, 53, 121, 71, 203, 110, 147, 113, 109, 239, 72, 122, 30, 105, 232, 122, 80, 103, 150, 138, 165, 46, 85, 161, 224, 167, 73, 133, 130, 95, 162, 217, 66, 193, 249, 129, 3, 72, 137, 192, 59, 93, 40, 104, 214, 79, 254, 195, 157, 160, 234, 169, 231, 108, 242, 230, 151, 199, 186, 3, 120, 117, 68, 204, 116, 201, 87, 68, 252, 147, 148, 36, 12, 234, 21, 146, 214, 207, 184, 190, 111, 246, 203, 188, 190, 243, 9, 192, 52, 17, 113, 111, 68, 236, 1, 188, 144, 230, 227, 94, 10, 248, 58, 105, 15, 129, 255, 105, 184, 111, 51, 203, 228, 4, 96, 2, 36, 205, 1, 124, 151, 114, 199, 216, 62, 2, 188, 38, 34, 198, 179, 241, 203, 9, 153, 125, 125, 38, 243, 250, 94, 144, 180, 58, 105, 51, 157, 65, 253, 37, 34, 174, 41, 21, 79, 83, 34, 226, 134, 136, 120, 61, 240, 50, 224, 55, 13, 119, 191, 26, 240, 35, 73, 63, 173, 126, 254, 102, 214, 3, 78, 0, 38, 230, 104, 224, 127, 11, 181, 245, 36, 240, 230, 136, 24, 239, 57, 241, 199, 3, 143, 103, 244, 183, 145, 164, 97, 62, 150, 120, 154, 79, 145, 247, 185, 238, 205, 211, 255, 140, 68, 196, 5, 192, 122, 192, 91, 129, 191, 52, 220, 253, 43, 73, 203, 6, 191, 57, 162, 133, 167, 102, 189, 226, 4, 96, 156, 36, 125, 16, 120, 95, 193, 38, 247, 136, 136, 115, 198, 251, 143, 35, 226, 62, 224, 251, 153, 125, 30, 94, 141, 98, 12, 37, 73, 155, 145, 118, 79, 204, 209, 235, 4, 0, 158, 46, 20, 60, 153, 180, 43, 229, 71, 104, 190, 80, 112, 103, 82, 125, 192, 65, 146, 22, 104, 176, 111, 51, 155, 0, 39, 0, 227, 32, 105, 27, 224, 136, 130, 77, 126, 54, 34, 190, 50, 192, 117, 95, 205, 236, 119, 85, 210, 151, 243, 208, 145, 36, 242, 167, 57, 238, 3, 46, 44, 16, 78, 39, 68, 196, 227, 17, 113, 4, 176, 34, 240, 5, 224, 95, 13, 118, 63, 31, 240, 9, 82, 34, 176, 235, 48, 39, 158, 102, 125, 229, 4, 96, 54, 36, 173, 7, 124, 155, 114, 63, 171, 239, 147, 158, 202, 38, 44, 34, 46, 36, 111, 87, 64, 128, 195, 36, 45, 147, 217, 70, 23, 237, 78, 58, 76, 39, 199, 247, 35, 34, 103, 181, 69, 39, 69, 196, 125, 17, 177, 39, 169, 80, 112, 144, 163, 155, 115, 44, 73, 218, 43, 227, 26, 73, 185, 163, 51, 102, 86, 144, 19, 128, 89, 144, 244, 92, 202, 30, 237, 123, 49, 176, 67, 230, 126, 248, 185, 199, 232, 62, 19, 56, 83, 82, 169, 247, 212, 186, 234, 76, 251, 35, 51, 155, 121, 12, 56, 172, 64, 56, 157, 21, 17, 127, 138, 136, 55, 0, 27, 3, 151, 54, 220, 253, 11, 129, 115, 37, 253, 76, 210, 26, 13, 247, 109, 102, 51, 224, 4, 96, 38, 198, 28, 237, 187, 68, 161, 38, 111, 2, 182, 136, 243, 9, 254, 0, 0, 32, 0, 73, 68, 65, 84, 170, 246, 246, 207, 113, 2, 240, 104, 102, 27, 107, 3, 199, 101, 182, 209, 9, 146, 86, 2, 78, 5, 38, 103, 54, 245, 165, 113, 174, 198, 232, 189, 136, 184, 48, 34, 94, 10, 188, 153, 116, 228, 116, 147, 94, 1, 92, 33, 233, 56, 73, 207, 110, 184, 111, 51, 27, 195, 9, 192, 12, 84, 71, 251, 158, 73, 218, 109, 173, 132, 251, 73, 107, 253, 239, 201, 109, 40, 34, 30, 4, 190, 147, 31, 18, 219, 73, 202, 93, 47, 223, 42, 73, 11, 147, 70, 104, 22, 206, 108, 234, 65, 224, 147, 249, 17, 245, 75, 68, 124, 15, 88, 5, 248, 48, 233, 103, 208, 148, 73, 164, 83, 34, 255, 36, 233, 16, 73, 207, 104, 176, 111, 51, 171, 56, 1, 152, 177, 227, 72, 235, 169, 75, 120, 156, 116, 180, 239, 13, 133, 218, 131, 180, 209, 77, 137, 47, 236, 131, 37, 189, 190, 64, 59, 141, 147, 52, 25, 56, 5, 88, 169, 64, 115, 135, 71, 196, 3, 5, 218, 233, 157, 170, 80, 240, 115, 164, 66, 193, 207, 211, 108, 161, 224, 188, 164, 207, 242, 159, 36, 189, 219, 133, 130, 102, 205, 114, 2, 48, 29, 73, 135, 146, 214, 80, 151, 16, 192, 78, 213, 218, 236, 98, 34, 226, 78, 224, 163, 5, 154, 18, 240, 29, 73, 165, 222, 111, 35, 170, 39, 198, 51, 72, 235, 206, 115, 253, 141, 84, 33, 63, 210, 34, 226, 254, 136, 248, 0, 105, 68, 224, 180, 134, 187, 127, 22, 105, 133, 203, 239, 36, 189, 166, 225, 190, 205, 70, 150, 242, 234, 209, 134, 139, 164, 93, 72, 103, 160, 151, 242, 177, 136, 56, 188, 96, 123, 79, 171, 150, 189, 157, 15, 108, 84, 168, 201, 195, 129, 143, 103, 22, 40, 214, 78, 210, 242, 164, 97, 255, 213, 10, 53, 185, 75, 68, 52, 86, 15, 33, 105, 49, 224, 217, 99, 94, 79, 0, 183, 85, 175, 219, 171, 41, 158, 214, 73, 218, 0, 248, 28, 240, 210, 22, 186, 255, 37, 240, 225, 9, 108, 146, 101, 45, 169, 10, 58, 7, 253, 61, 93, 19, 17, 46, 8, 109, 145, 19, 128, 74, 85, 73, 254, 35, 242, 139, 201, 166, 57, 54, 34, 118, 45, 212, 214, 12, 73, 90, 133, 116, 80, 208, 92, 133, 154, 60, 11, 120, 91, 68, 60, 82, 168, 189, 162, 36, 109, 76, 90, 198, 182, 120, 161, 38, 175, 3, 86, 143, 136, 167, 10, 181, 247, 95, 170, 29, 241, 182, 34, 157, 78, 184, 49, 179, 95, 81, 242, 119, 224, 23, 164, 26, 148, 31, 86, 27, 64, 181, 70, 210, 182, 164, 228, 240, 185, 13, 119, 29, 192, 137, 192, 126, 163, 82, 156, 217, 71, 78, 0, 250, 205, 83, 0, 128, 164, 213, 72, 195, 158, 165, 110, 254, 63, 5, 222, 91, 168, 173, 153, 138, 136, 63, 144, 182, 190, 45, 101, 43, 224, 215, 213, 83, 118, 167, 84, 163, 51, 63, 167, 220, 205, 63, 72, 79, 153, 197, 111, 254, 146, 38, 87, 115, 218, 151, 146, 166, 24, 190, 12, 108, 193, 248, 150, 147, 62, 131, 148, 44, 124, 11, 184, 75, 210, 175, 36, 109, 87, 141, 248, 52, 46, 34, 78, 33, 77, 11, 124, 8, 104, 178, 78, 66, 192, 142, 192, 245, 146, 14, 115, 161, 160, 89, 121, 35, 159, 0, 140, 57, 218, 119, 193, 66, 77, 254, 22, 120, 227, 44, 142, 246, 45, 237, 147, 192, 245, 5, 219, 123, 17, 105, 211, 150, 143, 73, 154, 175, 96, 187, 3, 145, 180, 170, 164, 31, 144, 166, 102, 74, 141, 116, 0, 28, 20, 17, 63, 46, 216, 30, 0, 146, 222, 68, 218, 172, 233, 171, 192, 75, 72, 55, 178, 65, 205, 1, 108, 74, 58, 128, 234, 55, 146, 54, 207, 14, 112, 0, 17, 49, 53, 34, 142, 36, 21, 10, 30, 5, 76, 109, 176, 251, 121, 129, 143, 1, 55, 74, 122, 111, 85, 252, 105, 102, 5, 140, 116, 2, 80, 29, 237, 251, 67, 96, 217, 66, 77, 222, 78, 58, 221, 239, 239, 133, 218, 155, 173, 136, 120, 28, 120, 55, 233, 137, 182, 148, 5, 73, 155, 226, 76, 59, 239, 189, 241, 234, 108, 73, 207, 150, 116, 44, 41, 161, 122, 109, 225, 230, 79, 1, 14, 46, 217, 160, 164, 181, 37, 93, 86, 181, 253, 252, 146, 109, 87, 214, 6, 126, 46, 233, 39, 146, 86, 172, 161, 253, 217, 138, 136, 7, 34, 226, 131, 164, 17, 129, 83, 27, 238, 254, 153, 164, 145, 148, 223, 73, 42, 253, 121, 48, 27, 73, 35, 155, 0, 84, 55, 181, 239, 1, 107, 21, 106, 114, 218, 209, 190, 127, 43, 212, 222, 184, 69, 196, 121, 192, 222, 53, 52, 189, 52, 233, 188, 247, 223, 53, 117, 146, 160, 164, 133, 36, 29, 14, 252, 9, 120, 7, 233, 41, 184, 164, 43, 72, 43, 51, 138, 37, 76, 146, 222, 76, 58, 67, 96, 221, 82, 109, 206, 194, 22, 192, 101, 146, 94, 222, 64, 95, 51, 20, 17, 127, 142, 136, 109, 129, 13, 128, 95, 55, 220, 253, 11, 128, 31, 84, 83, 35, 165, 142, 229, 54, 27, 73, 35, 155, 0, 144, 150, 126, 149, 90, 114, 244, 36, 176, 109, 68, 92, 93, 168, 189, 9, 171, 214, 114, 151, 172, 7, 24, 107, 21, 224, 44, 73, 55, 72, 250, 180, 164, 245, 75, 206, 73, 75, 90, 88, 210, 246, 146, 78, 33, 205, 153, 239, 67, 185, 237, 151, 199, 186, 157, 180, 27, 99, 238, 78, 138, 64, 90, 137, 33, 233, 16, 224, 100, 96, 158, 18, 109, 142, 211, 162, 192, 79, 36, 213, 94, 103, 50, 43, 17, 113, 113, 68, 108, 8, 188, 137, 180, 211, 101, 147, 54, 37, 77, 139, 156, 40, 105, 185, 134, 251, 54, 27, 10, 35, 185, 10, 64, 210, 135, 128, 207, 22, 108, 242, 61, 17, 145, 187, 71, 127, 17, 146, 190, 14, 188, 179, 129, 174, 238, 4, 126, 64, 170, 86, 63, 47, 34, 254, 57, 222, 11, 171, 228, 97, 57, 210, 208, 254, 86, 192, 38, 192, 156, 117, 4, 57, 198, 163, 192, 38, 17, 241, 155, 18, 141, 73, 154, 68, 186, 241, 111, 91, 162, 189, 12, 159, 141, 136, 58, 70, 127, 38, 164, 218, 61, 115, 55, 96, 127, 82, 130, 210, 164, 199, 72, 155, 24, 29, 30, 17, 15, 55, 220, 247, 72, 243, 42, 128, 126, 27, 185, 4, 64, 210, 27, 72, 243, 151, 165, 158, 96, 63, 19, 17, 37, 54, 229, 41, 162, 154, 218, 56, 5, 216, 166, 225, 174, 31, 36, 61, 97, 223, 81, 253, 231, 237, 164, 36, 97, 62, 96, 41, 210, 116, 194, 210, 213, 127, 95, 138, 178, 5, 125, 227, 241, 150, 136, 248, 110, 169, 198, 36, 125, 138, 50, 155, 49, 149, 240, 222, 136, 200, 61, 42, 186, 136, 234, 12, 141, 143, 3, 123, 208, 252, 239, 248, 94, 224, 64, 224, 255, 26, 44, 194, 29, 105, 78, 0, 250, 109, 164, 18, 0, 73, 47, 37, 109, 50, 82, 106, 120, 249, 20, 224, 205, 93, 219, 60, 71, 210, 220, 164, 149, 13, 173, 205, 19, 119, 204, 254, 17, 113, 104, 169, 198, 36, 109, 79, 58, 34, 186, 43, 254, 5, 108, 17, 17, 83, 218, 14, 100, 26, 73, 43, 144, 246, 15, 216, 174, 133, 238, 111, 0, 62, 18, 17, 103, 181, 208, 247, 72, 113, 2, 208, 111, 35, 83, 3, 80, 85, 78, 255, 128, 114, 55, 255, 95, 3, 111, 239, 218, 205, 31, 158, 94, 25, 176, 53, 169, 224, 109, 148, 77, 5, 118, 46, 124, 243, 95, 23, 56, 182, 84, 123, 133, 204, 9, 156, 90, 221, 116, 59, 33, 34, 110, 142, 136, 55, 147, 118, 18, 188, 168, 225, 238, 87, 34, 29, 121, 125, 94, 245, 251, 50, 179, 25, 24, 137, 4, 64, 210, 162, 148, 61, 218, 247, 70, 202, 28, 237, 91, 155, 106, 41, 226, 150, 164, 205, 115, 70, 209, 93, 192, 102, 17, 241, 173, 82, 13, 86, 211, 43, 199, 211, 108, 193, 223, 120, 45, 14, 116, 162, 14, 101, 172, 136, 184, 52, 34, 54, 2, 222, 64, 250, 187, 105, 210, 203, 128, 75, 37, 157, 36, 233, 57, 13, 247, 109, 214, 121, 67, 159, 0, 84, 195, 225, 103, 82, 230, 212, 56, 128, 251, 72, 71, 251, 222, 91, 168, 189, 218, 84, 219, 200, 110, 73, 154, 23, 173, 109, 187, 219, 14, 186, 26, 120, 73, 68, 148, 94, 162, 246, 14, 210, 138, 136, 174, 122, 165, 164, 45, 218, 14, 98, 70, 34, 226, 116, 96, 85, 96, 79, 210, 223, 80, 83, 68, 58, 220, 235, 250, 106, 5, 203, 66, 13, 246, 109, 214, 105, 67, 157, 0, 84, 213, 230, 199, 145, 246, 96, 47, 225, 49, 210, 147, 255, 159, 10, 181, 87, 187, 136, 120, 42, 34, 14, 34, 37, 2, 119, 183, 29, 79, 3, 78, 3, 54, 138, 136, 91, 75, 54, 90, 109, 26, 117, 80, 201, 54, 107, 242, 153, 106, 133, 66, 231, 68, 196, 191, 34, 226, 11, 192, 243, 128, 35, 72, 71, 101, 55, 101, 110, 224, 35, 192, 77, 146, 246, 144, 84, 247, 170, 19, 179, 206, 235, 228, 23, 69, 65, 135, 2, 111, 41, 212, 86, 144, 230, 252, 155, 158, 207, 44, 34, 34, 126, 14, 172, 73, 58, 65, 112, 88, 29, 12, 188, 41, 34, 254, 81, 67, 219, 31, 2, 150, 172, 161, 221, 210, 94, 12, 188, 173, 237, 32, 102, 37, 34, 30, 140, 136, 143, 144, 54, 245, 57, 153, 178, 187, 88, 206, 206, 98, 164, 61, 64, 174, 147, 244, 250, 6, 251, 53, 235, 156, 161, 77, 0, 36, 189, 131, 180, 135, 120, 41, 251, 86, 7, 163, 244, 86, 68, 220, 78, 90, 25, 240, 41, 154, 253, 210, 173, 219, 173, 192, 54, 17, 113, 64, 29, 69, 153, 213, 19, 245, 110, 133, 155, 189, 137, 180, 199, 255, 233, 164, 205, 143, 74, 218, 189, 112, 123, 181, 136, 136, 191, 68, 196, 91, 73, 133, 130, 23, 52, 220, 253, 243, 129, 211, 37, 93, 32, 233, 37, 13, 247, 109, 214, 9, 67, 185, 12, 176, 154, 7, 61, 135, 114, 167, 251, 125, 45, 34, 222, 93, 168, 173, 78, 144, 180, 37, 105, 24, 246, 69, 109, 199, 146, 225, 1, 210, 82, 179, 47, 214, 89, 144, 41, 105, 3, 202, 84, 178, 223, 67, 26, 73, 56, 39, 34, 238, 159, 174, 143, 37, 73, 155, 10, 125, 18, 152, 63, 179, 159, 0, 150, 141, 136, 219, 50, 219, 105, 84, 245, 68, 254, 41, 202, 213, 235, 140, 87, 144, 182, 5, 223, 55, 34, 254, 210, 112, 223, 189, 214, 213, 101, 128, 213, 65, 102, 107, 144, 234, 78, 234, 60, 64, 234, 49, 224, 15, 192, 181, 53, 141, 60, 214, 43, 34, 134, 234, 69, 186, 161, 61, 68, 250, 163, 46, 241, 250, 17, 48, 185, 237, 247, 85, 211, 207, 74, 192, 27, 129, 223, 21, 252, 121, 53, 241, 122, 140, 180, 147, 227, 34, 13, 253, 156, 62, 83, 32, 230, 83, 128, 37, 198, 209, 215, 10, 164, 189, 42, 114, 251, 219, 173, 237, 207, 215, 128, 63, 235, 57, 73, 155, 8, 221, 211, 210, 231, 234, 8, 96, 225, 182, 127, 14, 125, 121, 145, 110, 178, 131, 254, 188, 175, 174, 33, 158, 53, 129, 139, 129, 39, 26, 254, 236, 60, 9, 156, 4, 44, 223, 246, 239, 100, 34, 175, 161, 154, 2, 144, 180, 52, 233, 201, 191, 212, 209, 190, 215, 144, 246, 248, 31, 202, 93, 197, 34, 249, 62, 176, 58, 233, 233, 243, 186, 150, 67, 154, 157, 0, 78, 4, 86, 142, 136, 15, 71, 68, 83, 231, 211, 111, 157, 121, 253, 55, 34, 98, 219, 136, 184, 103, 118, 255, 48, 34, 110, 6, 54, 7, 126, 145, 217, 103, 110, 204, 173, 136, 84, 40, 248, 69, 82, 161, 224, 103, 72, 55, 229, 166, 204, 13, 124, 152, 84, 40, 184, 167, 11, 5, 251, 69, 210, 126, 192, 165, 164, 41, 165, 166, 79, 48, 157, 196, 191, 87, 155, 188, 161, 225, 190, 7, 54, 52, 83, 0, 146, 22, 32, 21, 184, 173, 89, 168, 201, 191, 1, 47, 141, 158, 13, 163, 230, 168, 230, 186, 223, 4, 124, 130, 52, 116, 214, 21, 1, 252, 132, 52, 68, 219, 232, 129, 75, 213, 250, 241, 191, 100, 52, 113, 11, 240, 162, 152, 224, 17, 209, 85, 191, 191, 3, 158, 49, 96, 191, 255, 2, 230, 235, 123, 242, 90, 253, 28, 62, 73, 42, 230, 45, 118, 0, 213, 56, 221, 8, 236, 19, 17, 167, 53, 220, 111, 111, 116, 101, 10, 64, 210, 187, 232, 206, 62, 24, 143, 147, 150, 138, 255, 178, 237, 64, 102, 103, 40, 70, 0, 198, 28, 237, 91, 234, 230, 255, 119, 210, 209, 190, 35, 115, 243, 7, 136, 180, 100, 240, 123, 164, 105, 148, 215, 1, 223, 32, 237, 237, 223, 134, 199, 73, 211, 47, 239, 6, 150, 142, 136, 87, 53, 125, 243, 175, 44, 155, 121, 253, 59, 38, 122, 243, 7, 136, 136, 91, 72, 167, 34, 14, 106, 78, 250, 177, 106, 97, 150, 34, 226, 150, 136, 216, 30, 120, 9, 205, 175, 96, 121, 30, 240, 125, 73, 23, 85, 219, 136, 91, 7, 85, 73, 98, 201, 195, 221, 114, 205, 13, 28, 47, 169, 206, 218, 131, 34, 134, 34, 1, 0, 190, 4, 188, 186, 80, 91, 79, 144, 150, 146, 253, 182, 80, 123, 189, 83, 37, 2, 103, 71, 196, 59, 129, 103, 3, 107, 147, 78, 121, 187, 132, 122, 55, 20, 122, 136, 180, 44, 108, 59, 210, 124, 249, 171, 35, 226, 107, 17, 113, 103, 141, 125, 206, 206, 210, 25, 215, 222, 27, 17, 57, 67, 249, 185, 135, 23, 229, 196, 222, 41, 17, 113, 121, 68, 108, 66, 154, 218, 184, 190, 225, 238, 55, 0, 46, 150, 244, 61, 73, 207, 109, 184, 111, 155, 189, 143, 50, 248, 72, 89, 93, 150, 33, 213, 87, 117, 90, 239, 19, 0, 73, 123, 3, 239, 41, 216, 228, 110, 17, 241, 147, 130, 237, 245, 90, 85, 39, 112, 101, 68, 28, 26, 17, 235, 147, 158, 42, 119, 36, 221, 156, 174, 33, 109, 185, 59, 209, 164, 32, 72, 69, 94, 215, 144, 158, 242, 191, 72, 218, 168, 104, 137, 136, 120, 107, 68, 156, 50, 200, 83, 115, 77, 150, 202, 184, 54, 235, 44, 134, 72, 43, 5, 110, 202, 104, 34, 39, 246, 78, 138, 116, 192, 207, 106, 164, 165, 142, 179, 173, 169, 40, 108, 91, 224, 15, 146, 62, 87, 157, 122, 104, 221, 208, 213, 101, 156, 77, 28, 203, 158, 165, 243, 67, 20, 179, 34, 233, 141, 192, 167, 11, 54, 249, 169, 136, 248, 122, 193, 246, 134, 78, 85, 200, 118, 98, 245, 2, 158, 158, 130, 89, 130, 148, 28, 44, 73, 186, 241, 44, 9, 60, 11, 248, 7, 255, 62, 30, 120, 218, 113, 193, 119, 68, 196, 191, 154, 141, 124, 96, 57, 55, 209, 43, 11, 244, 255, 27, 96, 197, 1, 175, 29, 186, 4, 0, 160, 170, 107, 56, 70, 210, 137, 192, 190, 192, 94, 52, 119, 62, 195, 92, 192, 7, 129, 157, 37, 29, 2, 28, 19, 17, 83, 27, 234, 219, 166, 83, 109, 245, 222, 213, 165, 204, 27, 72, 154, 59, 210, 225, 108, 157, 212, 219, 4, 64, 210, 250, 164, 155, 80, 169, 194, 160, 239, 82, 118, 227, 160, 145, 17, 17, 79, 2, 119, 86, 175, 97, 147, 83, 9, 254, 207, 2, 253, 231, 180, 49, 212, 85, 236, 17, 241, 48, 176, 175, 164, 175, 0, 135, 1, 219, 211, 92, 161, 224, 34, 192, 145, 192, 238, 146, 246, 137, 136, 83, 27, 234, 215, 254, 211, 146, 164, 164, 172, 139, 230, 37, 141, 78, 52, 189, 201, 213, 184, 245, 114, 10, 96, 204, 209, 190, 165, 178, 254, 11, 129, 157, 98, 88, 150, 68, 88, 73, 57, 69, 144, 107, 21, 232, 63, 231, 56, 219, 182, 10, 56, 27, 21, 17, 183, 70, 196, 14, 164, 159, 213, 148, 134, 187, 127, 46, 112, 138, 164, 95, 87, 27, 70, 89, 179, 154, 94, 25, 50, 81, 155, 182, 29, 192, 172, 244, 46, 1, 144, 180, 24, 105, 222, 120, 241, 66, 77, 222, 0, 108, 221, 229, 97, 26, 107, 85, 107, 9, 64, 181, 155, 89, 206, 114, 204, 145, 72, 0, 166, 137, 136, 43, 34, 98, 51, 210, 10, 150, 63, 54, 220, 253, 250, 192, 69, 146, 78, 173, 30, 80, 204, 192, 9, 64, 57, 99, 142, 246, 125, 126, 161, 38, 239, 37, 173, 215, 108, 242, 120, 82, 235, 151, 219, 51, 174, 125, 142, 164, 149, 51, 174, 127, 5, 121, 27, 154, 228, 196, 222, 91, 17, 113, 54, 105, 94, 120, 55, 154, 63, 1, 243, 141, 192, 239, 37, 29, 37, 105, 209, 134, 251, 182, 238, 89, 95, 82, 87, 167, 40, 250, 147, 0, 84, 71, 251, 126, 11, 216, 168, 80, 147, 143, 1, 175, 139, 136, 156, 42, 107, 27, 126, 185, 79, 209, 223, 170, 138, 36, 39, 68, 210, 130, 164, 213, 17, 57, 70, 106, 4, 96, 172, 136, 120, 34, 34, 190, 66, 90, 203, 255, 73, 224, 209, 6, 187, 159, 139, 84, 152, 120, 147, 164, 15, 117, 249, 6, 96, 181, 155, 23, 88, 175, 237, 32, 102, 166, 55, 9, 0, 233, 143, 248, 205, 133, 218, 10, 96, 135, 136, 184, 184, 80, 123, 54, 188, 110, 32, 239, 41, 242, 165, 164, 117, 202, 19, 117, 36, 176, 92, 70, 191, 151, 71, 141, 7, 36, 245, 69, 68, 252, 61, 34, 62, 14, 172, 12, 156, 64, 250, 219, 111, 202, 194, 164, 13, 106, 254, 40, 105, 187, 6, 251, 181, 110, 217, 180, 237, 0, 102, 166, 23, 9, 128, 164, 93, 201, 219, 21, 109, 122, 31, 169, 246, 192, 55, 155, 165, 136, 120, 138, 84, 112, 154, 227, 64, 73, 251, 140, 103, 36, 64, 210, 60, 146, 142, 4, 222, 145, 217, 231, 153, 153, 215, 15, 149, 136, 248, 107, 68, 188, 157, 180, 169, 85, 211, 91, 180, 174, 0, 124, 87, 210, 37, 146, 54, 108, 184, 111, 107, 223, 166, 109, 7, 48, 51, 157, 63, 11, 160, 58, 182, 246, 135, 148, 91, 178, 248, 149, 136, 40, 125, 182, 187, 13, 49, 73, 175, 33, 125, 6, 115, 93, 66, 90, 109, 50, 195, 157, 236, 36, 173, 7, 28, 79, 122, 90, 205, 181, 90, 68, 116, 253, 112, 167, 214, 84, 191, 211, 35, 128, 85, 90, 232, 254, 116, 224, 163, 17, 113, 99, 11, 125, 23, 213, 246, 89, 0, 146, 150, 7, 110, 30, 240, 242, 71, 72, 39, 248, 141, 199, 11, 128, 77, 6, 236, 231, 81, 210, 9, 147, 157, 219, 47, 162, 211, 9, 128, 164, 213, 73, 75, 244, 74, 109, 243, 120, 46, 105, 222, 255, 201, 66, 237, 217, 8, 144, 52, 15, 105, 215, 185, 5, 10, 52, 23, 164, 221, 253, 174, 32, 109, 20, 52, 23, 233, 169, 116, 45, 242, 134, 252, 199, 186, 49, 34, 74, 21, 202, 14, 173, 106, 68, 102, 87, 224, 64, 210, 166, 85, 77, 250, 23, 240, 21, 224, 224, 62, 23, 33, 247, 60, 1, 184, 37, 34, 150, 31, 103, 63, 235, 2, 151, 13, 216, 15, 192, 203, 34, 162, 115, 251, 1, 116, 118, 10, 64, 210, 179, 73, 71, 251, 150, 186, 249, 95, 5, 108, 231, 155, 191, 77, 84, 53, 151, 158, 187, 47, 255, 52, 34, 21, 166, 109, 71, 218, 197, 242, 16, 210, 254, 246, 165, 110, 254, 144, 138, 101, 109, 54, 34, 226, 201, 136, 248, 42, 105, 85, 209, 97, 52, 91, 40, 56, 39, 240, 126, 224, 70, 73, 123, 87, 43, 156, 172, 187, 174, 36, 29, 18, 55, 168, 77, 11, 197, 81, 84, 39, 19, 128, 234, 104, 223, 31, 146, 14, 84, 40, 225, 175, 192, 255, 70, 196, 35, 133, 218, 179, 209, 115, 32, 101, 118, 246, 171, 219, 29, 192, 81, 109, 7, 209, 39, 85, 161, 224, 126, 164, 68, 224, 120, 234, 61, 240, 106, 122, 11, 3, 159, 33, 21, 10, 190, 165, 90, 237, 100, 29, 83, 61, 56, 230, 60, 193, 111, 90, 40, 148, 162, 58, 151, 0, 84, 195, 114, 167, 0, 69, 206, 137, 6, 30, 38, 29, 237, 59, 146, 107, 162, 173, 140, 234, 104, 232, 207, 183, 29, 199, 56, 28, 16, 17, 125, 72, 84, 58, 39, 34, 110, 139, 136, 157, 72, 83, 50, 57, 167, 56, 14, 98, 121, 224, 59, 192, 165, 146, 54, 110, 184, 111, 27, 159, 41, 25, 215, 118, 114, 63, 128, 206, 37, 0, 192, 49, 192, 171, 10, 181, 245, 4, 240, 198, 136, 248, 93, 161, 246, 108, 180, 125, 154, 230, 79, 160, 155, 136, 223, 3, 223, 108, 59, 136, 190, 139, 136, 171, 35, 226, 21, 192, 107, 128, 166, 11, 41, 215, 5, 206, 151, 116, 134, 164, 149, 26, 238, 219, 102, 109, 74, 198, 181, 157, 220, 15, 160, 83, 9, 128, 164, 143, 0, 239, 46, 216, 228, 123, 34, 226, 103, 5, 219, 179, 17, 86, 29, 62, 179, 103, 219, 113, 204, 196, 19, 192, 123, 93, 227, 82, 78, 68, 156, 11, 188, 152, 244, 157, 212, 244, 65, 87, 91, 3, 215, 73, 250, 162, 164, 82, 219, 158, 91, 158, 161, 171, 3, 232, 76, 2, 32, 105, 91, 224, 83, 5, 155, 60, 44, 34, 190, 81, 176, 61, 51, 34, 226, 100, 210, 156, 109, 215, 188, 63, 34, 206, 111, 59, 136, 97, 83, 21, 10, 126, 141, 84, 31, 112, 8, 205, 214, 129, 76, 6, 118, 39, 21, 10, 126, 180, 90, 141, 98, 45, 25, 198, 58, 128, 78, 36, 0, 213, 41, 90, 199, 83, 238, 100, 167, 239, 0, 251, 23, 106, 203, 108, 122, 251, 146, 86, 168, 116, 197, 87, 170, 109, 111, 173, 38, 17, 241, 72, 68, 124, 130, 148, 8, 28, 71, 179, 133, 130, 11, 145, 30, 142, 174, 151, 180, 189, 11, 5, 91, 53, 37, 227, 218, 206, 213, 1, 180, 158, 0, 72, 122, 30, 112, 22, 229, 142, 246, 61, 31, 216, 197, 71, 251, 90, 93, 170, 221, 1, 223, 10, 92, 219, 118, 44, 164, 98, 181, 247, 183, 29, 196, 168, 136, 136, 219, 35, 98, 23, 96, 77, 160, 233, 233, 197, 229, 128, 111, 3, 151, 73, 26, 116, 83, 26, 203, 51, 37, 227, 218, 206, 213, 1, 180, 154, 0, 84, 71, 251, 158, 75, 185, 163, 125, 175, 7, 94, 239, 163, 125, 173, 110, 85, 61, 192, 70, 192, 79, 90, 12, 227, 4, 210, 10, 151, 39, 90, 140, 97, 36, 69, 196, 111, 35, 98, 11, 82, 193, 114, 211, 137, 224, 58, 192, 20, 73, 103, 101, 158, 54, 105, 19, 55, 84, 117, 0, 173, 37, 0, 213, 124, 214, 89, 148, 59, 218, 247, 30, 210, 209, 190, 247, 23, 106, 207, 108, 150, 34, 226, 33, 82, 165, 248, 209, 13, 119, 253, 20, 233, 60, 139, 183, 59, 217, 109, 87, 68, 252, 152, 180, 100, 121, 87, 154, 63, 125, 241, 117, 192, 181, 146, 142, 145, 180, 68, 195, 125, 143, 164, 97, 171, 3, 104, 37, 1, 168, 230, 176, 142, 7, 74, 29, 140, 241, 40, 105, 139, 223, 63, 23, 106, 207, 108, 92, 170, 34, 177, 189, 72, 135, 247, 60, 212, 64, 151, 119, 146, 62, 235, 71, 52, 208, 151, 141, 67, 245, 25, 56, 150, 244, 48, 115, 16, 240, 143, 6, 187, 159, 12, 236, 70, 42, 20, 220, 215, 133, 130, 141, 152, 146, 113, 109, 167, 234, 0, 218, 26, 1, 56, 28, 216, 182, 80, 91, 79, 1, 111, 139, 136, 75, 10, 181, 103, 54, 97, 17, 241, 77, 224, 185, 164, 99, 124, 235, 120, 42, 127, 24, 216, 15, 88, 49, 34, 186, 84, 128, 104, 149, 136, 248, 71, 68, 28, 72, 74, 4, 190, 65, 179, 133, 130, 11, 146, 142, 76, 191, 65, 210, 14, 46, 20, 172, 213, 148, 140, 107, 59, 85, 7, 208, 120, 2, 32, 233, 93, 12, 118, 62, 250, 204, 236, 29, 17, 167, 23, 108, 207, 108, 32, 17, 113, 127, 68, 124, 8, 88, 137, 180, 31, 127, 137, 189, 229, 31, 38, 237, 64, 184, 98, 68, 28, 230, 93, 254, 186, 47, 34, 238, 136, 136, 119, 146, 166, 6, 154, 174, 17, 89, 150, 84, 27, 114, 185, 164, 205, 26, 238, 123, 84, 92, 73, 250, 187, 28, 212, 166, 133, 226, 200, 214, 104, 2, 32, 233, 127, 72, 59, 253, 149, 114, 76, 68, 28, 89, 176, 61, 179, 108, 17, 113, 107, 68, 236, 76, 42, 110, 221, 134, 244, 133, 60, 145, 218, 148, 219, 129, 175, 2, 255, 3, 44, 17, 17, 31, 136, 136, 123, 203, 71, 106, 117, 138, 136, 223, 69, 196, 255, 0, 91, 2, 77, 239, 70, 186, 22, 240, 75, 73, 103, 75, 106, 227, 200, 227, 161, 85, 213, 1, 92, 152, 209, 196, 166, 133, 66, 201, 214, 216, 113, 192, 146, 94, 76, 42, 158, 40, 117, 186, 223, 15, 129, 173, 189, 243, 153, 245, 65, 117, 198, 197, 11, 129, 103, 3, 75, 141, 121, 61, 73, 42, 30, 155, 246, 250, 27, 240, 7, 47, 99, 29, 46, 146, 38, 1, 59, 145, 54, 19, 90, 186, 225, 238, 159, 0, 142, 37, 157, 19, 113, 119, 201, 134, 71, 229, 56, 224, 25, 244, 187, 55, 131, 111, 8, 246, 40, 176, 112, 68, 76, 29, 240, 250, 98, 26, 73, 0, 170, 163, 125, 47, 37, 125, 249, 149, 240, 32, 240, 62, 96, 42, 233, 201, 234, 78, 224, 78, 175, 0, 48, 179, 46, 147, 52, 63, 240, 97, 96, 111, 96, 254, 134, 187, 255, 59, 233, 60, 139, 35, 35, 162, 200, 209, 199, 35, 156, 0, 172, 11, 92, 54, 96, 191, 0, 47, 139, 136, 156, 213, 4, 69, 212, 158, 0, 72, 122, 6, 233, 201, 255, 197, 181, 118, 148, 76, 5, 238, 162, 74, 8, 170, 215, 13, 192, 79, 35, 226, 183, 13, 244, 111, 102, 54, 91, 146, 150, 36, 141, 6, 236, 12, 204, 209, 112, 247, 127, 35, 21, 148, 158, 88, 109, 106, 53, 176, 17, 78, 0, 230, 32, 61, 124, 46, 56, 96, 223, 159, 136, 136, 67, 6, 188, 182, 152, 90, 107, 0, 36, 77, 6, 78, 165, 153, 155, 63, 192, 92, 164, 34, 152, 117, 129, 215, 146, 214, 230, 30, 1, 92, 35, 233, 118, 73, 199, 73, 218, 78, 210, 162, 13, 197, 99, 102, 246, 95, 34, 226, 206, 136, 216, 149, 84, 40, 216, 244, 209, 195, 203, 144, 138, 84, 175, 144, 180, 121, 195, 125, 15, 133, 97, 169, 3, 168, 187, 8, 240, 203, 164, 2, 152, 46, 88, 138, 52, 7, 247, 93, 224, 30, 73, 151, 72, 58, 176, 202, 96, 205, 204, 26, 37, 105, 53, 224, 157, 164, 109, 133, 219, 176, 6, 240, 115, 73, 231, 72, 90, 181, 165, 24, 250, 108, 74, 198, 181, 157, 216, 15, 160, 182, 4, 64, 210, 62, 164, 39, 240, 46, 154, 68, 90, 139, 121, 0, 112, 149, 164, 31, 75, 218, 168, 229, 152, 204, 108, 200, 73, 154, 95, 210, 59, 36, 93, 76, 90, 25, 176, 39, 208, 246, 136, 228, 171, 129, 223, 74, 250, 63, 73, 207, 106, 57, 150, 62, 153, 146, 113, 109, 39, 246, 3, 168, 37, 1, 144, 180, 29, 105, 83, 138, 190, 216, 18, 184, 64, 210, 121, 146, 94, 217, 118, 48, 102, 54, 92, 36, 45, 34, 233, 72, 210, 74, 143, 99, 129, 151, 182, 28, 210, 244, 230, 0, 222, 69, 218, 81, 112, 127, 73, 243, 182, 29, 80, 15, 244, 126, 63, 128, 226, 9, 64, 245, 36, 93, 242, 104, 223, 38, 189, 12, 248, 169, 164, 75, 37, 189, 206, 187, 105, 153, 89, 14, 73, 147, 37, 189, 15, 248, 19, 240, 1, 202, 45, 131, 174, 203, 2, 192, 193, 164, 17, 1, 143, 138, 206, 194, 48, 212, 1, 20, 77, 0, 36, 61, 31, 56, 19, 152, 187, 100, 187, 45, 120, 9, 233, 160, 162, 171, 36, 181, 62, 76, 99, 102, 253, 35, 105, 11, 224, 26, 224, 75, 192, 98, 45, 135, 51, 81, 207, 3, 206, 147, 244, 121, 73, 243, 181, 29, 76, 135, 77, 201, 184, 182, 245, 58, 128, 201, 165, 26, 146, 180, 56, 233, 104, 223, 190, 125, 208, 103, 229, 197, 192, 133, 146, 14, 0, 62, 149, 187, 100, 166, 11, 170, 81, 141, 37, 248, 247, 70, 52, 179, 58, 60, 228, 41, 210, 147, 203, 245, 77, 191, 247, 106, 249, 232, 154, 180, 63, 63, 106, 245, 122, 132, 52, 44, 126, 123, 68, 60, 208, 118, 48, 37, 72, 90, 134, 180, 147, 227, 107, 218, 142, 37, 211, 36, 82, 141, 194, 107, 36, 237, 20, 17, 23, 181, 29, 80, 7, 77, 201, 184, 118, 90, 29, 64, 107, 251, 1, 20, 73, 0, 198, 28, 237, 251, 188, 18, 237, 117, 204, 100, 224, 48, 224, 149, 146, 118, 136, 136, 191, 181, 29, 208, 68, 85, 155, 143, 188, 6, 216, 154, 84, 240, 179, 208, 4, 155, 120, 68, 210, 37, 164, 35, 104, 7, 93, 243, 59, 91, 213, 110, 105, 123, 146, 230, 34, 87, 162, 197, 227, 170, 173, 121, 146, 110, 7, 126, 64, 26, 69, 252, 69, 68, 60, 209, 114, 72, 19, 86, 109, 119, 126, 34, 105, 27, 232, 97, 49, 109, 52, 224, 227, 192, 103, 188, 75, 229, 127, 152, 86, 7, 48, 232, 126, 0, 155, 210, 98, 2, 64, 68, 100, 189, 72, 115, 253, 167, 0, 49, 2, 175, 251, 128, 109, 114, 127, 102, 77, 189, 72, 251, 34, 236, 9, 220, 83, 232, 253, 79, 5, 14, 4, 230, 168, 33, 214, 21, 73, 243, 105, 109, 255, 142, 253, 234, 198, 235, 6, 250, 245, 183, 54, 7, 112, 40, 105, 212, 172, 237, 159, 93, 157, 175, 51, 73, 219, 216, 78, 123, 223, 107, 100, 180, 117, 117, 129, 159, 251, 242, 25, 253, 255, 165, 208, 239, 254, 156, 140, 24, 126, 209, 230, 231, 182, 196, 19, 214, 167, 129, 55, 21, 104, 167, 15, 22, 5, 78, 171, 150, 203, 116, 122, 94, 172, 170, 93, 248, 35, 233, 36, 185, 82, 79, 35, 115, 146, 150, 78, 126, 164, 80, 123, 0, 84, 21, 199, 63, 2, 54, 44, 217, 174, 245, 218, 243, 73, 127, 107, 23, 84, 91, 137, 119, 86, 181, 171, 223, 207, 128, 143, 211, 207, 226, 231, 137, 216, 138, 116, 210, 160, 247, 79, 249, 183, 41, 25, 215, 182, 90, 7, 144, 149, 0, 72, 122, 15, 105, 79, 235, 81, 243, 46, 224, 215, 146, 58, 89, 239, 32, 233, 173, 164, 15, 229, 10, 53, 117, 113, 64, 225, 141, 67, 14, 39, 125, 225, 155, 77, 111, 35, 210, 13, 167, 147, 197, 184, 213, 158, 240, 87, 1, 163, 116, 244, 238, 138, 192, 197, 146, 118, 105, 59, 144, 142, 152, 146, 113, 109, 171, 251, 1, 12, 156, 0, 72, 122, 21, 169, 186, 117, 84, 189, 24, 248, 153, 164, 133, 219, 14, 100, 172, 106, 201, 209, 73, 204, 186, 184, 47, 215, 220, 164, 225, 206, 108, 213, 94, 222, 239, 47, 209, 150, 13, 173, 37, 73, 115, 208, 47, 111, 59, 144, 177, 36, 173, 67, 122, 242, 95, 178, 237, 88, 90, 48, 15, 240, 13, 224, 168, 182, 3, 233, 128, 222, 238, 7, 48, 80, 2, 80, 13, 255, 156, 66, 243, 135, 88, 116, 205, 154, 192, 79, 36, 13, 90, 0, 82, 148, 164, 45, 129, 163, 27, 234, 110, 253, 66, 237, 172, 199, 240, 15, 155, 90, 190, 185, 129, 239, 87, 75, 141, 91, 39, 105, 45, 224, 167, 76, 188, 160, 118, 216, 108, 218, 118, 0, 109, 139, 30, 239, 7, 48, 225, 85, 0, 213, 18, 151, 115, 72, 27, 70, 180, 97, 42, 105, 217, 208, 109, 164, 147, 255, 22, 37, 29, 51, 252, 108, 210, 112, 74, 211, 94, 2, 252, 72, 210, 150, 17, 241, 72, 11, 253, 3, 79, 63, 73, 127, 143, 230, 146, 178, 37, 37, 45, 19, 249, 171, 34, 214, 45, 18, 141, 141, 130, 69, 128, 179, 37, 173, 17, 17, 143, 181, 21, 68, 245, 0, 244, 179, 42, 158, 166, 61, 1, 220, 93, 189, 238, 34, 157, 45, 191, 4, 240, 172, 234, 213, 245, 141, 134, 134, 213, 20, 210, 10, 171, 65, 172, 47, 105, 174, 136, 152, 90, 48, 158, 113, 153, 80, 2, 80, 61, 233, 158, 3, 44, 93, 79, 56, 255, 229, 26, 210, 242, 194, 203, 72, 55, 252, 219, 128, 123, 163, 42, 189, 156, 65, 124, 139, 240, 239, 100, 96, 117, 224, 117, 192, 6, 212, 191, 156, 108, 3, 224, 135, 146, 94, 29, 17, 255, 172, 185, 175, 153, 57, 156, 230, 159, 70, 22, 33, 29, 45, 154, 219, 134, 217, 120, 173, 12, 236, 14, 124, 182, 141, 206, 37, 173, 14, 252, 156, 102, 246, 167, 120, 4, 56, 191, 234, 111, 10, 112, 43, 112, 255, 204, 190, 255, 170, 248, 230, 5, 158, 9, 172, 13, 188, 2, 216, 156, 180, 164, 214, 234, 53, 37, 227, 218, 246, 246, 3, 152, 192, 82, 135, 73, 164, 74, 237, 58, 151, 152, 76, 37, 101, 214, 187, 3, 203, 21, 90, 162, 177, 56, 233, 20, 192, 211, 73, 127, 80, 117, 198, 255, 51, 96, 158, 166, 151, 114, 144, 158, 162, 155, 94, 126, 244, 79, 96, 114, 129, 216, 223, 215, 112, 220, 126, 245, 255, 117, 31, 99, 150, 162, 53, 248, 119, 182, 36, 105, 244, 177, 206, 247, 118, 43, 105, 169, 237, 134, 192, 156, 133, 226, 94, 22, 216, 153, 244, 240, 214, 165, 101, 138, 67, 177, 12, 176, 138, 99, 14, 224, 161, 140, 88, 246, 111, 250, 243, 28, 17, 76, 228, 13, 238, 83, 227, 7, 225, 62, 210, 62, 217, 11, 213, 252, 7, 60, 15, 176, 3, 112, 115, 141, 239, 229, 184, 198, 127, 137, 237, 236, 195, 112, 113, 161, 216, 215, 107, 33, 118, 191, 250, 255, 250, 96, 195, 127, 99, 115, 0, 191, 170, 241, 253, 252, 150, 244, 221, 84, 228, 166, 63, 139, 247, 177, 42, 169, 120, 239, 241, 14, 252, 14, 135, 38, 1, 168, 98, 233, 221, 126, 0, 227, 125, 99, 107, 144, 158, 206, 75, 127, 0, 30, 37, 237, 35, 208, 104, 54, 79, 42, 40, 250, 16, 112, 127, 77, 31, 236, 173, 26, 126, 47, 15, 183, 240, 199, 187, 75, 161, 248, 39, 3, 87, 180, 16, 191, 95, 253, 126, 157, 223, 240, 119, 198, 97, 53, 189, 143, 41, 192, 255, 52, 249, 94, 170, 247, 179, 20, 105, 218, 176, 141, 239, 142, 105, 175, 97, 75, 0, 246, 206, 136, 229, 159, 192, 92, 141, 127, 14, 198, 241, 166, 230, 1, 174, 45, 252, 139, 127, 10, 56, 129, 66, 195, 252, 25, 191, 176, 69, 72, 115, 137, 143, 21, 126, 127, 119, 1, 75, 52, 244, 30, 94, 213, 194, 31, 238, 143, 11, 191, 135, 23, 214, 240, 59, 240, 107, 184, 95, 79, 0, 139, 55, 248, 55, 86, 122, 232, 252, 65, 96, 231, 54, 191, 255, 170, 247, 182, 28, 169, 198, 160, 141, 223, 225, 176, 37, 0, 235, 102, 254, 60, 54, 106, 250, 247, 63, 158, 226, 184, 79, 146, 190, 160, 75, 185, 21, 88, 47, 34, 118, 140, 136, 91, 11, 182, 59, 97, 17, 241, 64, 68, 124, 24, 88, 133, 180, 150, 179, 148, 103, 2, 95, 43, 216, 222, 172, 148, 90, 142, 55, 94, 127, 4, 118, 45, 217, 96, 68, 92, 71, 170, 251, 104, 188, 10, 214, 122, 107, 14, 26, 216, 64, 69, 210, 178, 164, 189, 253, 75, 46, 85, 253, 9, 176, 90, 68, 28, 87, 176, 205, 129, 84, 223, 193, 175, 36, 253, 253, 253, 163, 229, 112, 250, 174, 119, 251, 1, 204, 50, 1, 168, 54, 222, 216, 171, 96, 127, 191, 6, 214, 141, 136, 223, 20, 108, 51, 91, 68, 220, 12, 108, 76, 154, 75, 47, 101, 107, 73, 59, 21, 108, 111, 102, 154, 90, 145, 241, 20, 240, 57, 96, 205, 136, 248, 107, 233, 198, 35, 226, 88, 82, 229, 114, 201, 68, 204, 134, 219, 178, 13, 244, 113, 2, 229, 78, 56, 125, 4, 216, 53, 34, 254, 39, 58, 116, 168, 88, 36, 199, 144, 54, 55, 243, 137, 127, 3, 138, 30, 238, 7, 48, 211, 101, 128, 213, 14, 119, 223, 162, 92, 230, 123, 28, 240, 158, 104, 97, 173, 227, 120, 68, 90, 190, 183, 157, 164, 107, 129, 131, 40, 243, 190, 143, 150, 244, 203, 154, 71, 58, 114, 18, 128, 155, 73, 197, 71, 51, 51, 237, 56, 224, 203, 129, 75, 235, 30, 177, 137, 136, 107, 171, 45, 95, 215, 6, 214, 169, 254, 211, 199, 1, 15, 183, 141, 25, 252, 119, 188, 76, 201, 64, 166, 39, 233, 245, 148, 251, 82, 126, 144, 52, 215, 127, 105, 161, 246, 138, 139, 136, 155, 170, 135, 190, 239, 2, 175, 111, 59, 158, 158, 154, 194, 224, 251, 1, 108, 208, 244, 126, 0, 179, 218, 7, 224, 40, 202, 100, 216, 79, 146, 142, 145, 61, 178, 64, 91, 181, 139, 136, 67, 36, 93, 71, 202, 252, 231, 207, 108, 110, 65, 224, 91, 146, 54, 143, 106, 146, 168, 6, 57, 235, 232, 119, 140, 136, 156, 140, 181, 184, 72, 71, 192, 94, 90, 189, 108, 200, 73, 218, 29, 248, 226, 128, 151, 215, 118, 22, 135, 164, 57, 73, 5, 202, 37, 220, 3, 188, 50, 34, 174, 41, 212, 94, 109, 34, 98, 170, 164, 55, 145, 30, 216, 118, 104, 59, 158, 30, 250, 85, 198, 181, 243, 146, 54, 150, 107, 236, 59, 121, 134, 83, 0, 146, 158, 75, 153, 95, 126, 0, 219, 247, 229, 230, 63, 77, 68, 156, 78, 218, 64, 227, 209, 2, 205, 109, 6, 188, 166, 64, 59, 51, 147, 51, 82, 209, 187, 243, 214, 109, 232, 228, 124, 6, 235, 220, 66, 250, 189, 148, 57, 160, 234, 54, 224, 101, 125, 184, 249, 79, 83, 13, 101, 191, 29, 248, 114, 219, 177, 244, 208, 85, 244, 168, 14, 96, 102, 53, 0, 31, 166, 204, 150, 178, 7, 69, 196, 247, 10, 180, 211, 184, 106, 168, 174, 212, 105, 87, 31, 46, 212, 142, 153, 213, 172, 154, 254, 252, 68, 129, 166, 238, 4, 54, 142, 136, 63, 22, 104, 171, 81, 85, 93, 192, 251, 128, 47, 180, 29, 75, 159, 84, 201, 83, 206, 142, 126, 155, 22, 10, 101, 92, 254, 43, 1, 144, 180, 4, 105, 231, 188, 92, 167, 0, 7, 23, 104, 167, 53, 17, 241, 93, 224, 144, 2, 77, 109, 82, 157, 28, 102, 102, 221, 183, 31, 249, 211, 11, 79, 2, 111, 169, 10, 140, 251, 236, 67, 52, 56, 36, 61, 36, 166, 100, 92, 187, 129, 164, 185, 74, 5, 50, 59, 51, 26, 1, 120, 63, 249, 135, 234, 92, 1, 236, 84, 227, 188, 119, 147, 14, 0, 78, 43, 208, 142, 71, 1, 204, 58, 174, 122, 250, 223, 173, 64, 83, 7, 68, 196, 148, 2, 237, 180, 170, 170, 201, 121, 51, 112, 111, 219, 177, 244, 200, 148, 140, 107, 167, 213, 1, 52, 226, 63, 18, 0, 73, 11, 144, 246, 102, 207, 113, 59, 105, 39, 188, 18, 243, 231, 173, 171, 146, 152, 29, 73, 115, 59, 57, 222, 88, 157, 216, 103, 102, 221, 245, 86, 242, 31, 128, 126, 76, 218, 63, 101, 40, 68, 196, 109, 164, 154, 176, 97, 120, 160, 107, 66, 111, 234, 0, 166, 31, 1, 216, 149, 252, 211, 217, 118, 171, 62, 48, 67, 163, 90, 34, 248, 54, 210, 176, 222, 160, 230, 160, 236, 158, 10, 102, 86, 222, 59, 50, 175, 191, 13, 120, 219, 144, 140, 126, 62, 45, 34, 126, 76, 185, 85, 17, 67, 173, 79, 117, 0, 79, 39, 0, 146, 38, 147, 14, 228, 201, 113, 81, 68, 156, 149, 217, 70, 39, 69, 196, 239, 129, 227, 51, 155, 121, 71, 53, 196, 104, 102, 29, 35, 105, 77, 96, 173, 204, 102, 62, 22, 17, 247, 149, 136, 167, 131, 14, 38, 141, 240, 218, 236, 77, 201, 184, 182, 177, 58, 128, 177, 35, 0, 27, 147, 191, 238, 255, 163, 153, 215, 119, 221, 1, 228, 45, 13, 92, 128, 116, 44, 167, 153, 117, 79, 238, 211, 255, 117, 192, 183, 75, 4, 210, 69, 213, 180, 110, 175, 11, 187, 27, 52, 37, 227, 218, 198, 234, 0, 198, 38, 0, 175, 204, 108, 235, 7, 17, 49, 212, 219, 72, 86, 219, 119, 14, 186, 105, 201, 52, 91, 150, 136, 197, 204, 202, 145, 52, 15, 176, 125, 102, 51, 31, 143, 136, 167, 74, 196, 211, 97, 223, 32, 237, 14, 106, 179, 214, 139, 58, 128, 177, 9, 192, 22, 25, 237, 60, 9, 236, 155, 25, 75, 95, 28, 14, 60, 144, 113, 253, 70, 213, 46, 99, 102, 214, 29, 91, 2, 57, 211, 115, 151, 12, 235, 244, 231, 88, 213, 170, 128, 18, 123, 36, 12, 181, 190, 212, 1, 76, 2, 144, 180, 24, 176, 102, 70, 59, 39, 85, 115, 228, 67, 47, 34, 30, 4, 142, 200, 104, 98, 126, 210, 177, 145, 102, 214, 29, 27, 101, 94, 63, 74, 55, 197, 239, 145, 142, 136, 183, 89, 155, 146, 113, 109, 35, 117, 0, 211, 70, 0, 94, 193, 108, 78, 6, 156, 141, 239, 20, 136, 165, 79, 114, 223, 239, 102, 69, 162, 48, 179, 82, 54, 204, 184, 246, 78, 224, 23, 165, 2, 233, 186, 106, 133, 195, 73, 109, 199, 209, 3, 83, 50, 174, 109, 164, 14, 96, 218, 77, 63, 103, 248, 255, 97, 242, 14, 64, 232, 157, 136, 184, 5, 184, 58, 163, 9, 39, 0, 102, 29, 33, 105, 110, 210, 201, 147, 131, 58, 99, 4, 230, 254, 167, 119, 106, 219, 1, 244, 64, 231, 235, 0, 166, 37, 0, 57, 5, 128, 231, 118, 245, 136, 223, 154, 157, 153, 113, 237, 6, 213, 151, 142, 153, 181, 111, 29, 32, 103, 184, 181, 196, 78, 161, 189, 18, 17, 55, 145, 191, 57, 218, 80, 235, 67, 29, 192, 36, 73, 43, 147, 183, 252, 47, 231, 70, 216, 103, 57, 239, 123, 94, 96, 189, 82, 129, 152, 89, 150, 156, 225, 255, 251, 200, 27, 234, 237, 179, 239, 183, 29, 64, 15, 76, 201, 184, 182, 246, 58, 128, 201, 192, 202, 25, 215, 79, 5, 206, 45, 20, 203, 132, 72, 154, 15, 88, 5, 184, 37, 34, 26, 223, 167, 58, 34, 174, 145, 116, 51, 176, 194, 128, 77, 108, 47, 41, 167, 238, 98, 154, 5, 51, 174, 93, 171, 90, 254, 100, 214, 150, 149, 50, 174, 93, 90, 210, 166, 5, 98, 120, 85, 198, 181, 215, 0, 27, 75, 117, 158, 76, 220, 89, 119, 101, 94, 191, 64, 129, 223, 223, 146, 153, 215, 215, 109, 74, 198, 181, 211, 234, 0, 106, 59, 140, 73, 164, 237, 127, 191, 54, 224, 245, 63, 141, 136, 198, 214, 181, 87, 55, 171, 253, 129, 215, 145, 110, 254, 211, 142, 44, 190, 5, 56, 159, 180, 11, 215, 223, 26, 140, 231, 104, 210, 225, 73, 102, 102, 214, 47, 183, 68, 196, 242, 117, 118, 32, 105, 14, 224, 126, 6, 127, 80, 219, 63, 34, 14, 45, 24, 210, 127, 152, 4, 60, 43, 227, 250, 27, 74, 5, 50, 59, 213, 113, 186, 87, 2, 31, 3, 86, 227, 223, 55, 127, 128, 231, 144, 14, 171, 184, 86, 210, 78, 77, 197, 68, 131, 239, 223, 204, 204, 250, 165, 235, 117, 0, 185, 9, 64, 35, 251, 66, 75, 90, 150, 180, 204, 102, 149, 217, 252, 211, 133, 128, 227, 36, 109, 87, 127, 84, 128, 247, 197, 54, 51, 179, 89, 155, 146, 113, 109, 173, 117, 0, 189, 72, 0, 128, 175, 51, 177, 33, 148, 47, 73, 90, 162, 174, 96, 198, 184, 163, 129, 62, 204, 204, 172, 191, 166, 100, 92, 91, 235, 126, 0, 185, 9, 64, 237, 55, 64, 73, 175, 98, 226, 251, 231, 47, 14, 236, 87, 67, 56, 211, 243, 8, 128, 153, 153, 205, 74, 103, 247, 3, 232, 195, 8, 192, 160, 75, 116, 114, 150, 246, 140, 215, 157, 192, 80, 157, 251, 109, 102, 102, 229, 116, 185, 14, 96, 18, 240, 204, 140, 235, 155, 24, 2, 95, 103, 192, 235, 94, 84, 247, 26, 202, 106, 3, 164, 97, 61, 251, 219, 204, 204, 202, 152, 146, 113, 109, 109, 117, 0, 147, 72, 115, 12, 131, 250, 71, 169, 64, 102, 97, 208, 17, 138, 185, 128, 69, 74, 6, 50, 19, 143, 52, 208, 135, 153, 153, 245, 215, 148, 140, 107, 107, 171, 3, 152, 68, 26, 198, 30, 84, 206, 244, 193, 120, 13, 186, 221, 228, 29, 17, 145, 187, 81, 197, 120, 116, 125, 35, 10, 51, 51, 107, 87, 39, 235, 0, 38, 145, 55, 143, 191, 116, 169, 64, 102, 225, 242, 134, 175, 27, 55, 73, 139, 0, 222, 73, 207, 204, 204, 102, 170, 171, 117, 0, 125, 72, 0, 206, 4, 30, 26, 224, 186, 19, 74, 7, 50, 3, 77, 188, 127, 51, 51, 235, 191, 41, 25, 215, 214, 82, 7, 144, 155, 0, 44, 85, 42, 144, 153, 137, 136, 219, 129, 61, 39, 120, 217, 105, 17, 209, 196, 65, 21, 181, 191, 127, 51, 51, 27, 10, 83, 50, 174, 173, 165, 14, 160, 15, 35, 0, 68, 196, 241, 192, 113, 227, 252, 231, 127, 4, 118, 171, 49, 156, 177, 60, 2, 96, 102, 102, 227, 209, 185, 58, 128, 94, 36, 0, 0, 17, 177, 11, 240, 38, 224, 238, 153, 252, 147, 167, 128, 207, 1, 107, 70, 196, 204, 254, 77, 105, 78, 0, 204, 204, 108, 182, 186, 88, 7, 48, 153, 188, 4, 224, 101, 165, 2, 25, 143, 136, 248, 190, 164, 159, 3, 155, 144, 246, 7, 88, 29, 248, 43, 169, 224, 239, 162, 136, 248, 83, 147, 241, 84, 113, 12, 234, 175, 192, 159, 75, 5, 98, 102, 3, 91, 157, 193, 151, 12, 223, 6, 220, 88, 48, 150, 62, 153, 11, 88, 63, 227, 250, 203, 201, 95, 74, 62, 15, 176, 94, 102, 27, 77, 154, 2, 188, 102, 192, 107, 215, 151, 52, 87, 181, 255, 76, 17, 2, 86, 5, 174, 203, 104, 99, 141, 136, 184, 166, 80, 60, 189, 33, 233, 25, 192, 189, 164, 63, 130, 65, 236, 18, 17, 227, 157, 214, 48, 179, 154, 72, 250, 2, 176, 199, 128, 151, 95, 28, 17, 27, 148, 140, 167, 47, 36, 109, 69, 42, 210, 30, 196, 19, 192, 34, 17, 145, 181, 143, 138, 164, 165, 24, 252, 33, 246, 190, 136, 88, 60, 167, 255, 137, 170, 78, 181, 253, 77, 70, 19, 27, 71, 196, 133, 165, 226, 153, 68, 202, 96, 115, 108, 93, 34, 144, 30, 122, 53, 131, 223, 252, 33, 111, 40, 200, 204, 202, 201, 249, 66, 125, 169, 164, 103, 23, 139, 164, 95, 222, 148, 113, 237, 111, 114, 111, 254, 149, 187, 73, 211, 191, 131, 163, 201, 90, 188, 0, 0, 11, 22, 73, 68, 65, 84, 88, 172, 58, 105, 182, 73, 87, 49, 216, 170, 182, 105, 54, 45, 20, 7, 0, 147, 34, 226, 33, 224, 183, 25, 109, 140, 106, 2, 144, 243, 190, 239, 136, 136, 81, 29, 54, 52, 235, 154, 156, 4, 64, 192, 54, 165, 2, 233, 11, 73, 115, 3, 175, 205, 104, 226, 87, 37, 226, 168, 230, 213, 115, 106, 190, 214, 46, 17, 199, 120, 85, 241, 230, 124, 222, 54, 45, 20, 10, 144, 70, 0, 96, 240, 97, 28, 128, 53, 36, 61, 167, 68, 48, 125, 81, 173, 199, 124, 117, 70, 19, 126, 250, 55, 235, 136, 106, 169, 113, 78, 61, 206, 27, 74, 197, 210, 35, 91, 50, 177, 35, 218, 167, 87, 36, 1, 168, 228, 156, 73, 179, 113, 177, 40, 198, 111, 74, 198, 181, 235, 151, 220, 15, 160, 68, 2, 0, 163, 55, 10, 176, 25, 121, 31, 126, 39, 0, 102, 221, 146, 243, 84, 182, 177, 164, 156, 67, 213, 250, 232, 141, 25, 215, 78, 5, 46, 42, 21, 8, 121, 133, 236, 187, 75, 122, 81, 177, 72, 198, 103, 74, 198, 181, 243, 81, 112, 63, 128, 73, 0, 17, 113, 21, 112, 107, 70, 59, 123, 72, 154, 179, 76, 72, 189, 240, 193, 204, 235, 207, 47, 18, 133, 153, 149, 146, 147, 0, 76, 2, 222, 95, 42, 144, 174, 147, 180, 12, 121, 243, 255, 151, 70, 196, 163, 165, 226, 33, 111, 219, 247, 185, 128, 19, 235, 62, 57, 118, 58, 157, 169, 3, 152, 52, 230, 191, 159, 149, 209, 206, 138, 192, 187, 51, 99, 233, 5, 73, 175, 0, 182, 200, 104, 226, 1, 224, 218, 66, 225, 152, 89, 25, 185, 73, 249, 94, 146, 154, 56, 28, 173, 11, 14, 32, 239, 12, 148, 146, 195, 255, 144, 63, 130, 253, 98, 224, 219, 146, 22, 46, 17, 204, 236, 116, 169, 14, 96, 108, 2, 144, 251, 67, 220, 95, 210, 2, 153, 109, 116, 154, 36, 1, 159, 202, 108, 230, 228, 136, 24, 180, 106, 213, 204, 106, 16, 17, 215, 3, 87, 100, 52, 49, 63, 176, 95, 161, 112, 58, 75, 210, 202, 192, 206, 153, 205, 20, 77, 0, 34, 226, 106, 224, 47, 153, 205, 188, 9, 184, 86, 210, 150, 249, 17, 141, 203, 148, 140, 107, 139, 213, 1, 40, 34, 210, 127, 145, 38, 147, 170, 41, 7, 221, 16, 3, 224, 160, 136, 56, 176, 64, 92, 157, 36, 233, 205, 192, 201, 153, 205, 188, 56, 34, 114, 86, 93, 152, 89, 13, 36, 189, 3, 56, 54, 163, 137, 169, 192, 11, 34, 226, 230, 66, 33, 117, 142, 164, 83, 200, 27, 254, 191, 21, 88, 49, 34, 158, 40, 20, 18, 0, 146, 62, 207, 196, 207, 140, 153, 153, 223, 140, 121, 93, 11, 252, 171, 80, 187, 99, 173, 1, 124, 43, 227, 250, 183, 49, 190, 253, 123, 30, 7, 110, 140, 136, 25, 190, 135, 167, 19, 0, 0, 73, 39, 86, 13, 15, 234, 17, 210, 47, 183, 169, 173, 120, 27, 83, 213, 56, 252, 129, 52, 221, 49, 168, 145, 221, 52, 196, 172, 235, 36, 205, 71, 42, 40, 91, 40, 163, 153, 147, 34, 34, 231, 59, 180, 179, 36, 173, 11, 92, 74, 90, 250, 56, 168, 15, 69, 196, 145, 133, 66, 122, 154, 164, 151, 144, 98, 179, 255, 54, 21, 248, 29, 240, 19, 224, 208, 177, 245, 23, 147, 166, 251, 135, 103, 100, 118, 180, 0, 249, 67, 228, 93, 245, 1, 242, 110, 254, 0, 95, 45, 17, 136, 153, 149, 23, 17, 255, 36, 255, 24, 241, 237, 171, 145, 194, 161, 82, 77, 239, 126, 155, 188, 155, 255, 67, 192, 215, 203, 68, 244, 159, 34, 226, 50, 242, 239, 95, 195, 106, 46, 210, 126, 7, 31, 3, 174, 150, 244, 244, 246, 205, 211, 143, 0, 204, 65, 218, 20, 104, 213, 204, 14, 119, 143, 136, 99, 50, 219, 232, 12, 73, 91, 0, 231, 2, 115, 100, 52, 243, 0, 176, 116, 68, 60, 86, 38, 42, 51, 43, 77, 210, 42, 192, 239, 51, 155, 121, 4, 88, 167, 170, 43, 24, 10, 146, 190, 3, 188, 37, 179, 153, 35, 34, 226, 35, 37, 226, 153, 145, 170, 62, 225, 90, 210, 25, 55, 54, 115, 83, 129, 181, 35, 226, 218, 255, 24, 1, 168, 170, 19, 247, 41, 208, 193, 231, 171, 106, 249, 222, 147, 244, 2, 224, 20, 242, 110, 254, 0, 199, 251, 230, 111, 214, 109, 17, 241, 7, 224, 188, 204, 102, 22, 0, 78, 149, 52, 111, 129, 144, 90, 39, 233, 221, 228, 223, 252, 255, 5, 28, 93, 32, 156, 153, 170, 18, 174, 90, 70, 24, 134, 204, 92, 192, 241, 146, 38, 255, 199, 8, 192, 52, 146, 46, 0, 54, 202, 236, 228, 1, 224, 165, 17, 113, 67, 102, 59, 173, 145, 180, 8, 112, 25, 240, 188, 204, 166, 166, 2, 171, 70, 196, 77, 249, 81, 153, 89, 157, 36, 189, 22, 248, 65, 129, 166, 142, 171, 142, 49, 239, 45, 73, 107, 0, 23, 147, 183, 236, 15, 224, 196, 136, 216, 177, 64, 72, 179, 84, 109, 200, 116, 13, 176, 100, 221, 125, 13, 129, 119, 79, 95, 3, 48, 77, 137, 97, 154, 69, 128, 179, 155, 90, 91, 89, 90, 181, 42, 226, 251, 228, 223, 252, 1, 142, 242, 205, 223, 172, 31, 34, 226, 108, 82, 193, 84, 174, 157, 37, 125, 178, 64, 59, 173, 144, 180, 42, 112, 14, 249, 55, 127, 128, 207, 21, 104, 99, 182, 170, 2, 244, 109, 72, 213, 239, 54, 107, 27, 205, 48, 1, 136, 136, 139, 41, 83, 80, 177, 18, 41, 9, 88, 172, 64, 91, 141, 145, 52, 15, 112, 34, 240, 242, 2, 205, 221, 6, 28, 90, 160, 29, 51, 107, 206, 251, 73, 35, 119, 185, 246, 149, 244, 133, 106, 15, 145, 222, 144, 180, 54, 105, 42, 100, 233, 2, 205, 157, 219, 228, 145, 241, 213, 253, 107, 36, 54, 166, 203, 180, 246, 204, 70, 0, 32, 85, 12, 62, 89, 160, 147, 141, 128, 223, 72, 90, 173, 64, 91, 181, 171, 206, 151, 158, 2, 148, 170, 228, 221, 187, 208, 177, 151, 102, 214, 144, 106, 234, 242, 243, 133, 154, 219, 3, 56, 86, 210, 172, 190, 111, 59, 67, 210, 70, 192, 47, 129, 197, 11, 52, 247, 48, 240, 222, 2, 237, 76, 72, 68, 28, 79, 67, 163, 14, 61, 182, 204, 76, 63, 144, 17, 241, 71, 224, 27, 133, 58, 90, 1, 248, 117, 53, 183, 214, 89, 146, 214, 33, 109, 254, 176, 94, 161, 38, 207, 139, 136, 220, 141, 131, 204, 172, 29, 135, 144, 70, 240, 74, 216, 5, 56, 185, 235, 133, 129, 146, 254, 151, 52, 253, 145, 115, 216, 217, 88, 123, 70, 68, 206, 57, 51, 57, 246, 6, 14, 2, 254, 187, 208, 205, 0, 174, 158, 93, 70, 122, 32, 240, 143, 66, 157, 61, 3, 56, 83, 82, 137, 85, 6, 197, 85, 107, 119, 207, 7, 158, 93, 168, 201, 39, 73, 153, 191, 153, 245, 80, 53, 114, 183, 119, 193, 38, 183, 5, 174, 145, 180, 97, 193, 54, 139, 144, 180, 128, 164, 175, 2, 103, 147, 78, 156, 43, 225, 204, 136, 248, 86, 161, 182, 38, 44, 146, 3, 129, 237, 128, 127, 182, 21, 71, 135, 93, 62, 203, 4, 32, 34, 238, 32, 101, 174, 165, 50, 168, 73, 192, 225, 146, 126, 32, 105, 165, 66, 109, 102, 145, 180, 164, 164, 175, 145, 182, 248, 45, 153, 157, 31, 17, 17, 191, 43, 216, 158, 153, 53, 172, 26, 193, 251, 113, 193, 38, 159, 15, 156, 47, 233, 179, 85, 173, 81, 235, 36, 109, 66, 218, 255, 165, 228, 188, 249, 221, 192, 187, 10, 182, 55, 176, 136, 56, 21, 216, 24, 184, 165, 237, 88, 58, 228, 41, 224, 148, 217, 206, 73, 69, 196, 41, 164, 161, 176, 146, 94, 11, 92, 39, 233, 152, 182, 206, 209, 150, 52, 191, 164, 3, 128, 27, 129, 93, 11, 55, 255, 83, 70, 224, 96, 16, 179, 17, 241, 86, 210, 247, 68, 41, 147, 128, 15, 145, 118, 101, 219, 180, 96, 187, 19, 34, 105, 81, 73, 71, 147, 14, 231, 89, 161, 112, 243, 239, 138, 136, 123, 10, 183, 57, 176, 136, 184, 18, 254, 191, 189, 251, 121, 253, 172, 170, 227, 56, 254, 58, 144, 184, 47, 114, 180, 159, 132, 11, 13, 162, 133, 104, 148, 137, 73, 4, 42, 65, 78, 186, 105, 39, 73, 255, 129, 45, 90, 21, 4, 17, 141, 52, 155, 182, 66, 214, 214, 141, 69, 81, 42, 186, 73, 41, 161, 54, 137, 32, 152, 17, 169, 211, 12, 66, 3, 25, 204, 52, 17, 167, 197, 185, 126, 157, 25, 149, 249, 126, 191, 159, 123, 63, 247, 251, 153, 247, 227, 1, 151, 129, 97, 230, 115, 15, 12, 243, 189, 207, 207, 189, 247, 156, 147, 155, 51, 238, 232, 252, 115, 229, 225, 28, 5, 39, 123, 239, 47, 188, 231, 58, 0, 151, 155, 222, 96, 125, 60, 201, 3, 11, 12, 228, 173, 36, 143, 36, 249, 241, 180, 20, 231, 162, 166, 213, 14, 191, 149, 241, 120, 99, 137, 185, 162, 175, 38, 185, 173, 247, 126, 118, 129, 207, 6, 86, 48, 77, 137, 251, 67, 198, 163, 204, 185, 189, 144, 228, 68, 198, 45, 243, 197, 119, 10, 109, 173, 125, 42, 99, 105, 243, 135, 50, 118, 49, 156, 219, 99, 189, 247, 77, 119, 12, 92, 204, 52, 53, 253, 59, 25, 51, 61, 142, 244, 59, 25, 11, 249, 125, 146, 47, 247, 222, 207, 239, 43, 0, 146, 189, 141, 50, 158, 207, 216, 197, 104, 9, 255, 200, 152, 122, 247, 203, 140, 77, 115, 102, 253, 143, 208, 90, 251, 108, 146, 251, 50, 54, 59, 90, 234, 241, 195, 91, 73, 190, 208, 123, 223, 207, 46, 77, 192, 14, 105, 173, 221, 151, 49, 61, 122, 169, 41, 125, 175, 36, 57, 153, 177, 106, 232, 185, 43, 253, 225, 131, 154, 54, 243, 249, 118, 198, 23, 185, 77, 87, 54, 125, 63, 47, 37, 185, 189, 247, 254, 175, 133, 62, 127, 54, 211, 254, 6, 119, 39, 57, 158, 228, 171, 217, 108, 39, 220, 93, 112, 33, 227, 165, 200, 31, 77, 171, 254, 102, 223, 1, 144, 36, 173, 181, 143, 103, 188, 37, 127, 108, 145, 225, 189, 227, 205, 36, 191, 74, 242, 139, 36, 79, 31, 230, 206, 192, 180, 123, 223, 157, 25, 23, 253, 175, 37, 249, 228, 172, 35, 124, 183, 158, 228, 254, 222, 251, 19, 11, 159, 7, 88, 73, 107, 237, 187, 25, 63, 68, 151, 116, 62, 201, 115, 73, 158, 153, 142, 63, 29, 230, 11, 81, 107, 237, 88, 198, 90, 38, 95, 153, 142, 79, 204, 57, 200, 247, 240, 114, 146, 187, 122, 239, 103, 22, 62, 207, 236, 166, 133, 223, 238, 200, 248, 114, 248, 209, 139, 142, 235, 178, 92, 44, 109, 195, 127, 50, 222, 239, 248, 99, 146, 103, 122, 239, 151, 60, 202, 58, 80, 0, 36, 73, 107, 237, 246, 140, 57, 162, 215, 206, 53, 194, 43, 56, 159, 177, 193, 195, 27, 23, 29, 167, 166, 95, 207, 36, 249, 96, 46, 253, 7, 123, 251, 248, 116, 54, 219, 214, 243, 160, 126, 158, 228, 135, 91, 60, 31, 176, 125, 45, 201, 79, 51, 223, 84, 225, 253, 56, 155, 228, 119, 73, 254, 158, 241, 51, 239, 76, 198, 75, 118, 103, 146, 156, 75, 242, 225, 140, 47, 101, 199, 50, 46, 88, 199, 50, 118, 127, 251, 76, 150, 187, 91, 113, 185, 191, 36, 249, 82, 239, 253, 212, 150, 206, 199, 12, 14, 28, 0, 73, 210, 90, 123, 48, 201, 99, 179, 143, 6, 128, 93, 243, 183, 36, 119, 246, 222, 95, 91, 123, 32, 28, 204, 161, 86, 166, 154, 86, 89, 250, 70, 70, 125, 2, 80, 211, 107, 25, 47, 148, 185, 248, 239, 160, 67, 221, 1, 216, 251, 203, 173, 221, 146, 241, 156, 254, 99, 179, 141, 8, 128, 93, 112, 42, 227, 182, 255, 156, 83, 36, 217, 162, 141, 214, 166, 158, 230, 86, 222, 150, 49, 61, 6, 128, 26, 94, 204, 120, 225, 207, 197, 127, 135, 109, 188, 57, 69, 239, 253, 116, 146, 187, 50, 94, 130, 3, 224, 234, 246, 147, 140, 181, 78, 94, 89, 123, 32, 108, 102, 163, 71, 0, 239, 250, 176, 214, 30, 206, 88, 208, 98, 39, 118, 189, 2, 96, 223, 222, 76, 242, 205, 222, 251, 175, 215, 30, 8, 243, 152, 53, 0, 146, 164, 181, 118, 111, 198, 12, 129, 85, 150, 248, 5, 96, 118, 79, 37, 121, 112, 186, 227, 203, 85, 98, 246, 111, 234, 189, 247, 223, 36, 185, 49, 201, 247, 51, 223, 78, 130, 0, 108, 223, 133, 140, 213, 3, 239, 113, 241, 191, 250, 204, 126, 7, 224, 146, 15, 111, 237, 250, 36, 223, 203, 88, 123, 255, 3, 139, 157, 8, 128, 57, 253, 47, 99, 135, 212, 31, 244, 222, 95, 94, 123, 48, 44, 99, 209, 0, 216, 59, 73, 107, 55, 101, 172, 146, 247, 245, 197, 79, 6, 192, 97, 93, 72, 242, 179, 140, 245, 226, 95, 93, 123, 48, 44, 107, 43, 1, 176, 119, 178, 177, 140, 240, 137, 36, 95, 220, 218, 73, 1, 184, 146, 115, 73, 30, 77, 114, 162, 247, 254, 250, 218, 131, 97, 59, 182, 26, 0, 123, 39, 109, 237, 243, 25, 59, 48, 29, 79, 114, 211, 214, 7, 0, 64, 146, 156, 206, 152, 194, 125, 114, 23, 55, 241, 97, 51, 171, 4, 192, 37, 3, 104, 237, 230, 188, 19, 3, 159, 203, 246, 54, 175, 0, 168, 230, 191, 25, 219, 186, 255, 118, 58, 254, 220, 215, 190, 8, 176, 154, 213, 3, 224, 98, 173, 181, 27, 50, 182, 239, 61, 158, 228, 214, 36, 31, 90, 119, 68, 0, 59, 239, 175, 25, 23, 251, 39, 147, 60, 219, 123, 255, 247, 202, 227, 225, 136, 56, 82, 1, 112, 185, 214, 218, 181, 73, 110, 72, 242, 145, 203, 142, 183, 127, 239, 250, 36, 215, 172, 54, 64, 128, 117, 157, 207, 216, 22, 248, 244, 251, 29, 189, 247, 179, 235, 13, 143, 163, 236, 72, 7, 0, 0, 176, 12, 75, 246, 2, 64, 65, 2, 0, 0, 10, 18, 0, 0, 80, 144, 0, 0, 128, 130, 4, 0, 0, 20, 36, 0, 0, 160, 32, 1, 0, 0, 5, 9, 0, 0, 40, 72, 0, 0, 64, 65, 2, 0, 0, 10, 18, 0, 0, 80, 144, 0, 0, 128, 130, 4, 0, 0, 20, 36, 0, 0, 160, 32, 1, 0, 0, 5, 9, 0, 0, 40, 72, 0, 0, 64, 65, 2, 0, 0, 10, 18, 0, 0, 80, 144, 0, 0, 128, 130, 4, 0, 0, 20, 36, 0, 0, 160, 32, 1, 0, 0, 5, 9, 0, 0, 40, 72, 0, 0, 64, 65, 2, 0, 0, 10, 18, 0, 0, 80, 144, 0, 0, 128, 130, 4, 0, 0, 20, 36, 0, 0, 160, 32, 1, 0, 0, 5, 9, 0, 0, 40, 72, 0, 0, 64, 65, 2, 0, 0, 10, 18, 0, 0, 80, 144, 0, 0, 128, 130, 4, 0, 0, 20, 36, 0, 0, 160, 32, 1, 0, 0, 5, 9, 0, 0, 40, 72, 0, 0, 64, 65, 2, 0, 0, 10, 18, 0, 0, 80, 144, 0, 0, 128, 130, 4, 0, 0, 20, 36, 0, 0, 160, 32, 1, 0, 0, 5, 9, 0, 0, 40, 72, 0, 0, 64, 65, 2, 0, 0, 10, 18, 0, 0, 80, 144, 0, 0, 128, 130, 4, 0, 0, 20, 36, 0, 0, 160, 32, 1, 0, 0, 5, 9, 0, 0, 40, 72, 0, 0, 64, 65, 2, 0, 0, 10, 18, 0, 0, 80, 144, 0, 0, 128, 130, 4, 0, 0, 20, 36, 0, 0, 160, 32, 1, 0, 0, 5, 9, 0, 0, 40, 72, 0, 0, 64, 65, 2, 0, 0, 10, 18, 0, 0, 80, 144, 0, 0, 128, 130, 4, 0, 0, 20, 36, 0, 0, 160, 32, 1, 0, 0, 5, 9, 0, 0, 40, 72, 0, 0, 64, 65, 2, 0, 0, 10, 18, 0, 0, 80, 144, 0, 0, 128, 130, 4, 0, 0, 20, 36, 0, 0, 160, 32, 1, 0, 0, 5, 9, 0, 0, 40, 72, 0, 0, 64, 65, 2, 0, 0, 10, 18, 0, 0, 80, 208, 255, 1, 21, 189, 72, 128, 100, 137, 252, 122, 0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130 }; public static Texture2D GetIconTexture(string spriteName) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_007b: 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_0091: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(48, 48); ((Object)val).name = spriteName; if (ImageConversion.LoadImage(val, pngBytes, false)) { Texture2D val2 = new Texture2D(((Texture)val).width, ((Texture)val).height, (TextureFormat)4, false); Color val3 = default(Color); ((Color)(ref val3))..ctor(1f, 1f, 1f, 1f); Color val4 = default(Color); ((Color)(ref val4))..ctor(0f, 0f, 0f, 0f); for (int i = 0; i < ((Texture)val).width; i++) { for (int j = 0; j < ((Texture)val).height; j++) { if (val.GetPixel(i, j).a != 0f) { val2.SetPixel(i, j, val3); } else { val2.SetPixel(i, j, val4); } } } val2.Apply(true); return val2; } return null; } } [BepInPlugin("semarware.dysonsphereprogram.bulldozer", "Bulldozer", "1.1.12")] [BepInProcess("DSPGAME.exe")] public class BulldozerPlugin : BaseUnityPlugin { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Action <>9__26_1; public static Response <>9__26_2; internal void b__26_1() { GameMain.mainPlayer.SetHandItems(0, 0, 0); ((BuildTool)GameMain.mainPlayer.controller.actionBuild.reformTool)._Close(); } internal void b__26_2() { Log.LogAndPopupMessage("Canceled"); } } public const string PluginGuid = "semarware.dysonsphereprogram.bulldozer"; private const int EnvironmentModificationCategory = 9; private const int FoundationChildIndex = 1; private const float UiInitRetrySeconds = 1f; private static int _soilToDeduct; public static BulldozerPlugin instance; private ReformIndexInfoProvider _reformIndexInfoProvider; private bool _flattenRequested; private Harmony _harmony; private UIElements _ui; private float _nextUiInitAttemptTime; private string _lastUiInitializationFailure; private void Awake() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown Log.logger = ((BaseUnityPlugin)this).Logger; GuideMarker.logger = ((BaseUnityPlugin)this).Logger; instance = this; _harmony = new Harmony("semarware.dysonsphereprogram.bulldozer"); _harmony.PatchAll(typeof(BulldozerPlugin)); _harmony.PatchAll(typeof(WreckingBall)); _harmony.PatchAll(typeof(PluginConfigWindow)); PluginConfig.InitConfig(((BaseUnityPlugin)this).Config); Log.Debug("Bulldozer Plugin Loaded"); } private void Update() { if (!GameMain.isRunning || DSPGame.IsMenuDemo || GameMain.localPlanet == null || GameMain.localPlanet.factory == null || GameMain.localPlanet.factory.platformSystem == null) { return; } PlatformSystem platformSystem = GameMain.localPlanet.factory.platformSystem; if (_reformIndexInfoProvider == null) { _reformIndexInfoProvider = new ReformIndexInfoProvider(platformSystem); } _reformIndexInfoProvider.DoInitWork(GameMain.localPlanet); if ((Object)(object)_ui != (Object)null && _ui.IsShowing()) { if (PluginConfig.NeedReformIndexProvider()) { _ui.ReadyForAction = _reformIndexInfoProvider?.Initted ?? false; _ui.initPercent = _reformIndexInfoProvider.InitPercentComplete(); } else { _ui.ReadyForAction = true; } } Player mainPlayer = GameMain.mainPlayer; WreckingBall.DoWorkItems((mainPlayer != null) ? mainPlayer.factory : null); DoPaveUpdate(); if ((Object)(object)_ui != (Object)null && (Object)(object)_ui.countText != (Object)null) { _ui.countText.text = $"{WreckingBall.RemainingTaskCount()}"; } } private void LateUpdate() { UIBuildMenu val = UIRoot.instance?.uiGame?.buildMenu; if (GameMain.sandboxToolsEnabled && val != null && val.currentCategory == 9 && (Object)(object)val.reformAllButton != (Object)null) { ((Component)val.reformAllButton).gameObject.SetActive(false); } if ((Object)(object)val == (Object)null || val.currentCategory != 9) { _nextUiInitAttemptTime = 0f; return; } if ((Object)(object)_ui != (Object)null && !_ui.IsUsable) { ReleaseUi(); } if ((Object)(object)_ui != (Object)null || Time.unscaledTime < _nextUiInitAttemptTime) { return; } try { if (TryInitUi(val)) { _ui.Show(inittedThisTime: true); } } catch (Exception exception) { RecordUiInitializationFailure("Unexpected exception while retrying UI initialization.", exception); } } private void OnDestroy() { WreckingBall.Stop(); ReleaseUi(); _reformIndexInfoProvider?.PlanetChanged(null); PluginConfigWindow.NeedReinit = true; _harmony.UnpatchSelf(); } public void OnGUI() { if (PluginConfigWindow.visible) { PluginConfigWindow.OnGUI(); } } private void DoPaveUpdate() { if (!_flattenRequested) { return; } ((BaseUnityPlugin)this).Logger.LogDebug((object)"repaint requested"); SetFlattenRequestedFlag(value: false); try { if (GameMain.mainPlayer.planetData.UpdateDirtyMeshes()) { GameMain.mainPlayer.factory.RenderLocalPlanetHeightmap(); } Decorate(); Log.LogAndPopupMessage("Bulldozer done adding foundation"); } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogWarning((object)$"exception painting {arg}"); Log.LogAndPopupMessage("Failure while painting. Check logs"); } } private void Decorate() { Player mainPlayer = GameMain.mainPlayer; PlatformSystem val = ((mainPlayer == null) ? null : mainPlayer.factory?.platformSystem); Player mainPlayer2 = GameMain.mainPlayer; PlayerAction_Build val2 = ((mainPlayer2 != null) ? mainPlayer2.controller.actionBuild : null); if (val == null || val2 == null || (!PluginConfig.guideLinesOnly.Value && PlanetPainter.PaintPlanet(val, _reformIndexInfoProvider))) { return; } ReformIndexInfoProvider reformIndexInfoProvider = _reformIndexInfoProvider; if (reformIndexInfoProvider == null || !reformIndexInfoProvider.Initted || _reformIndexInfoProvider.platformSystem != GameMain.localPlanet?.factory?.platformSystem) { if (_reformIndexInfoProvider.platformSystem != GameMain.localPlanet?.factory?.platformSystem) { _reformIndexInfoProvider.PlanetChanged(GameMain.localPlanet); } Log.LogAndPopupMessage("not initted"); } else { SelectiveDecorationBuilder.Build(_reformIndexInfoProvider).Decorate(); } } private void InvokePavePlanet() { if (PluginConfig.alterVeinState.Value) { InvokePaveWithVeinAlteration(); } else { InvokePavePlanetNoBury(); } } private void InvokePavePlanetNoBury() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Invalid comparison between Unknown and I4 //IL_00b1: Unknown result type (might be due to invalid IL or missing references) Player mainPlayer = GameMain.mainPlayer; PlayerAction_Build obj = ((mainPlayer != null) ? mainPlayer.controller.actionBuild : null); Player mainPlayer2 = GameMain.mainPlayer; PlatformSystem val = ((mainPlayer2 == null) ? null : mainPlayer2.factory?.platformSystem); PlanetFactory factory = GameMain.localPlanet.factory; if (obj == null || val == null || factory == null) { Log.LogAndPopupMessage("invalid state"); return; } if (GameMain.localPlanet == null || (int)GameMain.localPlanet.type == 5) { Log.LogAndPopupMessage("Bulldozer doesn't work on gas giants"); return; } if (PluginConfig.removeVegetation.Value) { for (int i = 0; i < factory.vegePool.Length; i++) { if (factory.vegePool[i].protoId != 9999 && (!PluginConfig.IsLatConstrained() || !PluginConfig.LatitudeOutOfBounds(GeoUtil.GetLatitudeDegForPosition(factory.vegePool[i].pos)))) { factory.RemoveVegeWithComponents(i); } } } else { PlanetAlterer.UpdateVegeHeight(factory); } GameMain.gpuiManager.SyncAllGPUBuffer(); int num = 0; int num2 = -1; int num3 = -1; int num4 = -1; if (!PluginConfig.guideLinesOnly.Value) { for (int j = 0; j < GameMain.localPlanet.modData.Length << 1; j++) { if (PluginConfig.IsLatConstrained()) { LatLon forModIndex = _reformIndexInfoProvider.GetForModIndex(j); if (forModIndex.Equals(LatLon.Empty)) { Log.LogNTimes("No coord mapped to data index for {0}", 15, j); continue; } if (PluginConfig.LatitudeOutOfBounds(forModIndex.Lat)) { continue; } if (num2 < 0) { num2 = (int)forModIndex.Lat; num3 = (int)forModIndex.Long; num4 = j; } } num++; GameMain.localPlanet.AddHeightMapModLevel(j, 3); } } Log.Debug($"leveled {num} points for {PluginConfig.minLatitude.Value} {PluginConfig.maxLatitude.Value}. First ({num2}, {num3}) ndx: {num4}"); bool flag = false; if (_soilToDeduct != 0 && PluginConfig.soilPileConsumption.Value != OperationMode.FullCheat) { flag = GameMain.mainPlayer.sandCount - _soilToDeduct <= 0; GameMain.mainPlayer.SetSandCount(Math.Max(GameMain.mainPlayer.sandCount - _soilToDeduct, 0L), (ESandSource)0); _soilToDeduct = 0; } if (GameMain.localPlanet.UpdateDirtyMeshes()) { GameMain.localPlanet.factory.RenderLocalPlanetHeightmap(); } factory.planet.landPercentDirtyFlag = true; if (!flag || PluginConfig.soilPileConsumption.Value != OperationMode.Honest) { Log.LogAndPopupMessage("Adding foundation"); val.EnsureReformData(); Decorate(); } else { Log.LogAndPopupMessage("not adding foundation failed to level everything"); } Log.LogAndPopupMessage("Bulldozer done adding foundation"); } private void InvokePaveWithVeinAlteration() { Log.LogAndPopupMessage("Altering veins"); PlanetAlterer.RaiseLowerVeins(); } private void SetFlattenRequestedFlag(bool value) { ((BaseUnityPlugin)this).Logger.LogDebug((object)$"setting flatten requested to {value}"); _flattenRequested = value; } [HarmonyPostfix] [HarmonyPatch(typeof(GameScenarioLogic), "NotifyOnUnlockTech")] public static void GameScenarioLogic_NotifyOnUnlockTech_Postfix(int techId) { if (!((Object)(object)instance._ui == (Object)null) && !instance._ui.TechUnlockedState) { TechProto val = ((ProtoSet)(object)LDB.techs).Select(techId); if (val.Level == 3 && ((Proto)val).Name.Contains("宇宙探索")) { instance._ui.TechUnlockedState = true; } Log.logger.LogDebug((object)("tech proto not matched " + JsonUtility.ToJson((object)val))); } } [HarmonyPostfix] [HarmonyPatch(typeof(UIBuildMenu), "OnCategoryButtonClick")] public static void UIBuildMenu_OnCategoryButtonClick_Postfix(UIBuildMenu __instance) { if (Log.logger == null || (Object)(object)instance == (Object)null) { Console.WriteLine(Resources.BulldozerPlugin_Not_Initialized, Log.logger, instance); return; } try { instance.HandleBuildMenuCategoryChanged(__instance); } catch (Exception exception) { instance.RecordUiInitializationFailure("Unexpected exception while handling a build-menu category change.", exception); } } private void HandleBuildMenuCategoryChanged(UIBuildMenu uiBuildMenu) { if ((Object)(object)uiBuildMenu == (Object)null) { return; } if (uiBuildMenu.currentCategory != 9) { _nextUiInitAttemptTime = 0f; if ((Object)(object)_ui != (Object)null && _ui.IsUsable) { _ui.Hide(); } return; } if ((Object)(object)_ui != (Object)null && !_ui.IsUsable) { ReleaseUi(); } bool inittedThisTime = (Object)(object)_ui == (Object)null && TryInitUi(uiBuildMenu); if (!((Object)(object)_ui == (Object)null)) { RefreshUiState(); _ui.Show(inittedThisTime); } } private bool TryInitUi(UIBuildMenu uiBuildMenu) { if (!TryResolveUiParts(uiBuildMenu, out var containerRect, out var foundationButton, out var failureReason)) { RecordUiInitializationFailure(failureReason); return false; } UIElements uIElements = null; try { uIElements = ((Component)containerRect).gameObject.AddComponent(); UIElements.logger = Log.logger; if (!uIElements.TryAddBulldozeComponents(containerRect, foundationButton, delegate { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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) //IL_00cf: Expected O, but got Unknown ((MonoBehaviour)this).StartCoroutine(InvokeAction(1, delegate { GameMain.mainPlayer.SetHandItems(0, 0, 0); ((BuildTool)GameMain.mainPlayer.controller.actionBuild.reformTool)._Close(); })); if (WreckingBall.IsRunning()) { WreckingBall.Stop(); Log.LogAndPopupMessage("Stopping..."); if ((Object)(object)_ui?.countText != (Object)null) { _ui.countText.text = "0"; } } else { string text = ConstructPopupMessage(GameMain.localPlanet); string obj = (PluginConfig.IsLatConstrained() ? "Bulldoze selected latitudes" : "Bulldoze planet"); string text2 = Localization.Translate(text); Response val = InvokePluginCommands; object obj2 = <>c.<>9__26_2; if (obj2 == null) { Response val2 = delegate { Log.LogAndPopupMessage("Canceled"); }; <>c.<>9__26_2 = val2; obj2 = (object)val2; } UIMessageBox.Show(obj, text2, "Ok", "Cancel", 0, val, (Response)obj2); } }, out failureReason)) { uIElements.Unload(); Object.Destroy((Object)(object)uIElements); RecordUiInitializationFailure(failureReason); return false; } _ui = uIElements; RefreshUiState(); _lastUiInitializationFailure = null; _nextUiInitAttemptTime = 0f; return true; } catch (Exception exception) { if ((Object)(object)uIElements != (Object)null) { uIElements.Unload(); Object.Destroy((Object)(object)uIElements); } RecordUiInitializationFailure("Unexpected exception while creating Bulldozer UI.", exception); return false; } } private static bool TryResolveUiParts(UIBuildMenu uiBuildMenu, out RectTransform containerRect, out GameObject foundationButton, out string failureReason) { containerRect = null; foundationButton = null; failureReason = null; if ((Object)(object)uiBuildMenu == (Object)null) { failureReason = "Unable to initialize Bulldozer UI: UIBuildMenu is null."; return false; } GameObject childGroup = uiBuildMenu.childGroup; containerRect = ((childGroup != null) ? childGroup.GetComponent() : null); UIButton[] childButtons = uiBuildMenu.childButtons; UIButton val = null; if (childButtons != null && childButtons.Length > 1) { val = childButtons[1]; } Transform val2 = ((childGroup != null) ? childGroup.transform.Find("button-1") : null); foundationButton = (((Object)(object)val != (Object)null) ? ((Component)val).gameObject : ((val2 != null) ? ((Component)val2).gameObject : null)); GameObject obj = foundationButton; UIButton val3 = ((obj != null) ? obj.GetComponentInChildren() : null); if ((Object)(object)containerRect != (Object)null && (Object)(object)foundationButton != (Object)null && (Object)(object)val3 != (Object)null && (Object)(object)val3.button != (Object)null) { return true; } string arg = ((childButtons == null) ? "null" : childButtons.Length.ToString()); failureReason = "Unable to initialize Bulldozer UI: Environment Modification template was not found " + $"(childGroup={(Object)(object)childGroup != (Object)null}, containerRect={(Object)(object)containerRect != (Object)null}, " + $"childButtonsLength={arg}, childButton1={(Object)(object)val != (Object)null}, " + $"relativeButton1={(Object)(object)val2 != (Object)null}, actionButton={(Object)(object)val3 != (Object)null})."; return false; } private void RefreshUiState() { if (!((Object)(object)_ui == (Object)null) && _ui.IsUsable) { _ui.TechUnlockedState = CheckResearchedTech() || PluginConfig.disableTechRequirement.Value; if (_reformIndexInfoProvider != null && PluginConfig.NeedReformIndexProvider()) { _ui.ReadyForAction = _reformIndexInfoProvider.Initted; _ui.initPercent = _reformIndexInfoProvider.InitPercentComplete(); } else { _ui.ReadyForAction = true; } } } private void ReleaseUi() { if (!((Object)(object)_ui == (Object)null)) { _ui.Unload(); Object.Destroy((Object)(object)_ui); _ui = null; } } private void RecordUiInitializationFailure(string reason, Exception exception = null) { string text = reason ?? "Unable to initialize Bulldozer UI for an unknown reason."; if (_lastUiInitializationFailure != text) { Log.logger.LogWarning((object)text); if (exception != null) { Log.logger.LogWarning((object)exception); } _lastUiInitializationFailure = text; } else { Log.logger.LogDebug((object)text); } _nextUiInitAttemptTime = Time.unscaledTime + 1f; } private string ConstructPopupMessage(PlanetData localPlanet) { if (localPlanet == null) { return "No local planet to bulldoze found."; } string text = "Please confirm the following actions: "; if (PluginConfig.IsLatConstrained()) { text = text + "\r\n\t[For Selected Latitude Range " + PluginConfig.GetLatRangeString() + "]"; } if (PluginConfig.destroyFactoryAssemblers.Value) { string text2 = (PluginConfig.skipDestroyingStations.Value ? "(assemblers, belts, but not stations)" : "(assemblers, belts, stations, etc)"); if (PluginConfig.IsLatConstrained()) { text = text + "\nDestroy factory machines " + text2; text += "\nNote: this can be much slower than tearing down the entire factory"; } else { text = text + "\nDestroy all factory machines " + text2; } int num = WreckingBall.CountBuildGhosts(GameMain.mainPlayer.factory); if (num > 0) { text += $". Including {num} not yet built machines"; } if (PluginConfig.deleteFactoryTrash.Value) { text += "\nDelete all littered factory items (existing litter should not be affected)"; } if (!PluginConfig.deleteFactoryTrash.Value && Utils.IsOtherAssemblyLoaded("PersonalLogistics")) { text += "\nNote: Personal Logistics is also installed. Be aware that by default\r\n it will try and send littered items to your logistics stations.\r\n"; } } else if (PluginConfig.alterVeinState.Value) { text = ((!PluginConfig.IsLatConstrained()) ? (text + "\nAttempt to " + PluginConfig.GetCurrentVeinsRaiseState() + " all veins on planet.") : (text + "\nAttempt to " + PluginConfig.GetCurrentVeinsRaiseState() + " veins in Selected Latitudes")); } else { text = (PluginConfig.IsLatConstrained() ? (text + "\nAdd foundation to locations in Selected Latitudes") : ((!PluginConfig.guideLinesOnly.Value) ? (text + "\nAdd foundation to all locations on planet") : (text + "\nAdd foundation needed to paint guidelines"))); text = ((!PluginConfig.removeVegetation.Value) ? (text + Localization.Translate("\r\nSkip removing plants trees and rocks")) : ((!PluginConfig.IsLatConstrained()) ? (text + "\r\nRemove all plants trees and rocks") : (text + "\r\nRemove all plants trees and rocks in the Selected Latitudes"))); if (PluginConfig.addGuideLines.Value) { SelectivePlanetPainter selectivePlanetPainter = SelectiveDecorationBuilder.Build(_reformIndexInfoProvider); text = text + "\n" + selectivePlanetPainter.BuildActionSummary(); } if (PluginConfig.soilPileConsumption.Value != OperationMode.FullCheat || PluginConfig.foundationConsumption.Value != OperationMode.FullCheat) { var (num2, num3) = GridExplorer.CountNeededResources(GameMain.localPlanet.factory.platformSystem, _reformIndexInfoProvider); if (PluginConfig.soilPileConsumption.Value != OperationMode.FullCheat && num3 != 0) { string arg = ((num3 < 0) ? "Gain" : "Consume"); text += $"\n{arg} {Math.Abs(num3)} soil pile. (Current amount: {GameMain.mainPlayer.sandCount})"; if (num3 > GameMain.mainPlayer.sandCount) { text = ((PluginConfig.soilPileConsumption.Value != OperationMode.Honest) ? (text + ". All of your soil pile will be consumed but the process will continue.") : (text + ". Be aware that this process will halt after your soil pile is consumed.")); } _soilToDeduct = num3; } if (PluginConfig.foundationConsumption.Value != OperationMode.FullCheat) { text += $"\nConsume {num2} foundation\n"; (string message, bool hasEnoughCapacity, int remainingToRemove) tuple2 = StorageSystemManager.BuildRemovalMessage(1131, num2); string item = tuple2.message; bool item2 = tuple2.hasEnoughCapacity; int item3 = tuple2.remainingToRemove; text += item; if (!item2) { text = ((OperationMode.HalfCheat != PluginConfig.foundationConsumption.Value) ? (text + $"\nProcess will halt after all available foundation ({num2 - item3}) is used up.") : (text + $"\nProcess will continue after all available foundation ({num2 - item3}) is used up.")); } } } } return text; } private bool CheckResearchedTech() { //IL_007b: Unknown result type (might be due to invalid IL or missing references) TechProto val = null; foreach (TechProto item in new List(((ProtoSet)(object)LDB.techs).dataArray)) { if (((Proto)item).Name.Contains("宇宙探索") && item.Level == 3) { val = item; } } if (val == null) { Log.logger.LogWarning((object)"did not find universe exploration tech item, assuming unlocked"); return true; } return GameMain.history.techStates[((Proto)val).ID].unlocked; } private IEnumerator InvokeAction(int delay, Action action) { Log.logger.LogDebug((object)"pre yield"); if (delay > 0) { yield return (object)new WaitForSeconds((float)delay); } else if (delay == -2) { yield return (object)new WaitForFixedUpdate(); } else { yield return (object)new WaitForEndOfFrame(); } Log.logger.LogDebug((object)"Performing action"); action(); } private void InvokePluginCommands() { try { if (PluginConfig.destroyFactoryAssemblers.Value) { WreckingBall.Init(GameMain.mainPlayer.factory, GameMain.mainPlayer); } else { InvokePavePlanet(); } } catch (Exception arg) { Log.logger.LogWarning((object)$"InvokePlugin failed {arg}"); } } [HarmonyPostfix] [HarmonyPatch(typeof(GameData), "NewGame")] private static void EnterGame() { Log.Debug("Starting new game"); if ((Object)(object)instance != (Object)null && instance._reformIndexInfoProvider != null) { instance._reformIndexInfoProvider.PlanetChanged(null); } } [HarmonyPostfix] [HarmonyPatch(typeof(GameSave), "LoadCurrentGame")] private static void LoadCurrentGame(bool __result, string saveName) { if ((Object)(object)instance != (Object)null && instance._reformIndexInfoProvider != null) { instance._reformIndexInfoProvider.PlanetChanged(null); } } [HarmonyPostfix] [HarmonyPatch(typeof(GameMain), "End")] public static void OnGameEnd() { if ((Object)(object)instance != (Object)null && (Object)(object)instance._ui != (Object)null) { instance._ui.Hide(); instance._reformIndexInfoProvider?.PlanetChanged(null); } } } public class CheckboxControl : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler, IPointerClickHandler { private GameObject _hoverText; public string HoverText = ""; public Text textObject; public event Action onClick; public void Start() { if ((Object)(object)textObject != (Object)null) { _hoverText = ((Component)textObject).gameObject; _hoverText.SetActive(false); textObject.text = HoverText; } } public void OnPointerEnter(PointerEventData eventData) { if ((Object)(object)_hoverText == (Object)null) { Console.WriteLine("hovertext not initialized"); Start(); } else { _hoverText.SetActive(true); } } public void OnPointerExit(PointerEventData eventData) { if ((Object)(object)_hoverText == (Object)null) { Console.WriteLine("hovertext not initialized"); Start(); } else { _hoverText.SetActive(false); } } public void OnPointerClick(PointerEventData eventData) { this.onClick?.Invoke(eventData); } } public static class GeoUtil { public static int GetLatitudeDegForPosition(Vector3 pos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) int num = default(int); int num2 = default(int); int num3 = default(int); int num4 = default(int); bool flag = default(bool); bool flag2 = default(bool); bool flag3 = default(bool); bool flag4 = default(bool); Maths.GetLatitudeLongitude(pos, ref num, ref num2, ref num3, ref num4, ref flag, ref flag2, ref flag3, ref flag4); if (flag2) { return -num; } return num; } public static Vector3 LatLonToPosition(float lat, float lon, float earthRadius) { //IL_0034: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) float num = (float)Math.PI / 180f * lat; float num2 = (float)Math.PI / 180f * lon; float num3 = Mathf.Sin(num); float num4 = Mathf.Cos(num); float num5 = Mathf.Sin(num2); float num6 = Mathf.Cos(num2); Vector3 val = new Vector3(num4 * num5, num3, num4 * (0f - num6)); return ((Vector3)(ref val)).normalized * earthRadius; } } public class SnapArgs { public int[] indices = new int[100]; public Vector3[] points = (Vector3[])(object)new Vector3[100]; } public class GridExplorer { public delegate void PostComputeReformAction(SnapArgs snapArgs, Vector3 center, float radius, int reformSize, int neededSoilPile, bool timeExpired = false, float lastLat = 0f, float lastLon = 0f); private static int _soilNeeded; public static void IterateReform(BuildTool_Reform reformTool, PostComputeReformAction postComputeFn, int maxExecutionMs, float startLat = -89.9f, float startLon = -179.9f) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) HashSet hashSet = new HashSet(); HashSet hashSet2 = new HashSet(); PlatformSystem platformSystem = ((BuildTool)reformTool).planet.factory.platformSystem; if (platformSystem.IsAllReformed()) { return; } float num = 9.90946f; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); Vector3 val2 = default(Vector3); for (float num2 = startLat; num2 < 90f; num2 += 0.25f) { if (PluginConfig.LatitudeOutOfBounds(num2)) { continue; } for (float num3 = -179.9f; num3 < 180f; num3 += 0.25f) { Vector3 val = GeoUtil.LatLonToPosition(num2, 0f, ((BuildTool)reformTool).planet.radius); ((Vector3)(ref val)).Normalize(); int reformIndexForPosition = platformSystem.GetReformIndexForPosition(val); if (reformIndexForPosition < 0 || hashSet.Contains(reformIndexForPosition)) { continue; } hashSet.Add(reformIndexForPosition); if (platformSystem.IsTerrainReformed(platformSystem.GetReformType(reformIndexForPosition))) { continue; } SnapArgs snapArgs = new SnapArgs(); int num4 = ((BuildTool)reformTool).planet.aux.ReformSnap(val, 10, 1, 1, snapArgs.points, snapArgs.indices, platformSystem, ref val2); int item = ((BuildTool)reformTool).planet.data.QueryIndex(val2); if (!hashSet2.Contains(item)) { hashSet2.Add(item); Vector3[] points = snapArgs.points; foreach (Vector3 val3 in points) { hashSet2.Add(((BuildTool)reformTool).planet.data.QueryIndex(val3)); } int num5 = 0; int num6 = 0; ((BuildTool)reformTool).factory.ComputeFlattenTerrainReform(snapArgs.points, val2, num, num4, ref num5, ref num6, 3f, 1f); postComputeFn?.Invoke(snapArgs, val2, num, 10, num5 - num6); if (stopwatch.ElapsedMilliseconds > maxExecutionMs) { Log.LogAndPopupMessage($"cancel after running ${stopwatch.ElapsedMilliseconds} lat={num2} / lon={num3}"); stopwatch.Stop(); postComputeFn?.Invoke(snapArgs, val2, num, 10, 0, timeExpired: true, num2, num3); break; } } } } } public static int GetNeededFoundation(PlatformSystem platformSystem, ReformIndexInfoProvider reformIndexInfoProvider) { SelectivePlanetPainter selectivePlanetPainter = SelectiveDecorationBuilder.Build(reformIndexInfoProvider); int num = 0; for (int i = 0; i < platformSystem.maxReformCount; i++) { if (PluginConfig.IsLatConstrained()) { LatLon forIndex = reformIndexInfoProvider.GetForIndex(i); if (!forIndex.IsEmpty() && PluginConfig.LatitudeOutOfBounds(forIndex.Lat)) { continue; } } if (PluginConfig.guideLinesOnly.Value) { LatLon forIndex2 = reformIndexInfoProvider.GetForIndex(i); if (!forIndex2.IsEmpty() && selectivePlanetPainter.DecoratorForLocation(forIndex2).IsNone()) { continue; } } num += ((!platformSystem.IsTerrainReformed(platformSystem.GetReformType(i))) ? 1 : 0); } return num; } public static (int foundation, int soilPile) CountNeededResources(PlatformSystem platformSystem, ReformIndexInfoProvider indexInfoProvider) { Log.logger.LogInfo((object)$"player current soil pile {GameMain.mainPlayer.sandCount}"); if (platformSystem?.planet == null) { Log.logger.LogWarning((object)"null platform system passed in"); return (foundation: int.MaxValue, soilPile: int.MaxValue); } platformSystem.EnsureReformData(); int item = 0; int item2 = 0; if (PluginConfig.foundationConsumption.Value != OperationMode.FullCheat) { item = GetNeededFoundation(platformSystem, indexInfoProvider); } if (PluginConfig.soilPileConsumption.Value != OperationMode.FullCheat && !PluginConfig.guideLinesOnly.Value) { _soilNeeded = 0; IterateReform(GameMain.mainPlayer.controller.actionBuild.reformTool, SumReform, 5000); item2 = _soilNeeded; } return (foundation: item, soilPile: item2); } public static void SumReform(SnapArgs snapArgs, Vector3 center, float radius, int reformSize, int neededSoilPile, bool timeExpired = false, float lastLat = 0f, float lastLon = 0f) { _soilNeeded += neededSoilPile; } } [Flags] public enum GuideMarkTypes { None = 0, Equator = 1, Meridian = 2, Tropic = 4, MinorMeridian = 8, Pole = 0x10 } public class GuideMarker { public static ManualLogSource logger; private static readonly float[] TropicLats = new float[10] { 86.183334f, 84.5f, 82.5f, 79.1f, 75.25f, 70.183334f, 64.75f, 55.483334f, 46.75f, 28.75f }; private static int GetCustomColorIndex(GuideMarkTypes guideMarkType) { switch (guideMarkType) { case GuideMarkTypes.Equator: return PluginConfig.guideLinesEquatorColor.Value; case GuideMarkTypes.Meridian: return PluginConfig.guideLinesMeridianColor.Value; case GuideMarkTypes.MinorMeridian: return PluginConfig.guideLinesMinorMeridianColor.Value; case GuideMarkTypes.Tropic: return PluginConfig.guideLinesTropicColor.Value; case GuideMarkTypes.Pole: return PluginConfig.guideLinesPoleColor.Value; default: Log.logger.LogWarning((object)$"no defined plugin config to get custom color for GuideMarkType {guideMarkType}"); return 7; } } public static void AddGuideMarks(PlatformSystem platformSystem, GuideMarkTypes types) { if (types != GuideMarkTypes.None) { if ((types & GuideMarkTypes.Tropic) == GuideMarkTypes.Tropic) { PaintTropics(platformSystem); } if ((types & GuideMarkTypes.MinorMeridian) == GuideMarkTypes.MinorMeridian) { PaintMinorMeridians(platformSystem); } if ((types & GuideMarkTypes.Meridian) == GuideMarkTypes.Meridian) { PaintMeridians(platformSystem); } if ((types & GuideMarkTypes.Equator) == GuideMarkTypes.Equator) { PaintEquator(platformSystem); } if ((types & GuideMarkTypes.Pole) == GuideMarkTypes.Pole) { PaintPoles(platformSystem); } } } private static void PaintEquator(PlatformSystem platformSystem) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) float coordLineOffset = GetCoordLineOffset(platformSystem.planet); List list = new List(); for (float num = -179.9f; num < 180f; num += 0.25f) { for (int i = -1; i < 1; i++) { Vector3 val = GeoUtil.LatLonToPosition(0f + (float)i * coordLineOffset, num, platformSystem.planet.radius); int reformIndexForPosition = platformSystem.GetReformIndexForPosition(val); if (reformIndexForPosition >= platformSystem.reformData.Length || reformIndexForPosition < 0) { logger.LogWarning((object)$"reformIndex = {reformIndexForPosition} is out of bounds, apparently"); } else { list.Add(reformIndexForPosition); } } } list.Sort(); InterpolateMissingIndexes(list); int customColorIndex = GetCustomColorIndex(GuideMarkTypes.Equator); Console.WriteLine($"custom color index for equator {customColorIndex}"); foreach (int item in list) { int num2 = Math.Max(0, item); try { platformSystem.SetReformType(num2, 1); platformSystem.SetReformColor(num2, customColorIndex); } catch (Exception ex) { logger.LogWarning((object)$"exception while setting reform at index {item} max={platformSystem.reformData.Length} {ex.Message}"); } } } private static void PaintMeridians(PlatformSystem platformSystem) { //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) float radius = platformSystem.planet.radius; float coordLineOffset = GetCoordLineOffset(platformSystem.planet); List list = new List(); float[] array = ((Math.Abs(platformSystem.planet.radius - 200f) < 0.01f) ? TropicLats : GetTropicLatitudes(platformSystem)); for (float num = -90f; num < 90f; num += coordLineOffset) { if (PluginConfig.LatitudeOutOfBounds(num)) { continue; } for (int i = 0; i < 4; i++) { int num2 = -1; if (Math.Abs(num) > array[5]) { num2 = -3; } if (Math.Abs(num) > array[4]) { num2 = -3; } if (Math.Abs(num) > array[2]) { num2 -= 2; } if (Math.Abs(num) > array[1]) { num2 -= 5; } int num3 = 2; HashSet hashSet = new HashSet(); for (int j = num2; j < num3; j++) { float lon = coordLineOffset * (float)j + (float)i * 90f; Vector3 val = GeoUtil.LatLonToPosition(num, lon, radius); int reformIndexForPosition = platformSystem.GetReformIndexForPosition(val); list.Add(reformIndexForPosition); hashSet.Add(reformIndexForPosition); } } } list.Sort(); InterpolateMissingIndexes(list); int customColorIndex = GetCustomColorIndex(GuideMarkTypes.Meridian); foreach (int item in list) { int num4 = Math.Max(0, item); try { platformSystem.SetReformType(num4, 1); platformSystem.SetReformColor(num4, customColorIndex); } catch (Exception ex) { logger.LogWarning((object)$"exception while setting reform at index {num4} max={platformSystem.reformData.Length} {ex.Message}"); } } } private static void PaintMinorMeridians(PlatformSystem platformSystem) { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: 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) float radius = platformSystem.planet.radius; float coordLineOffset = GetCoordLineOffset(platformSystem.planet); List list = new List(); int value = PluginConfig.minorMeridianInterval.Value; float[] array = ((Math.Abs(platformSystem.planet.radius - 200f) < 0.01f) ? TropicLats : GetTropicLatitudes(platformSystem)); for (float num = -90f; num < 90f; num += coordLineOffset) { if (Math.Abs(num) > Math.Abs(array[3]) || PluginConfig.LatitudeOutOfBounds(num)) { continue; } for (int i = -180; i < 180; i += value) { int num2 = 2; HashSet hashSet = new HashSet(); for (int j = -1; j < num2; j++) { float lon = coordLineOffset * (float)j + (float)i; Vector3 val = GeoUtil.LatLonToPosition(num, lon, radius); int reformIndexForPosition = platformSystem.GetReformIndexForPosition(val); list.Add(reformIndexForPosition); hashSet.Add(reformIndexForPosition); } } } list.Sort(); InterpolateMissingIndexes(list); int customColorIndex = GetCustomColorIndex(GuideMarkTypes.MinorMeridian); foreach (int item in list) { int num3 = Math.Max(0, item); try { platformSystem.SetReformType(num3, 1); platformSystem.SetReformColor(num3, customColorIndex); } catch (Exception ex) { logger.LogWarning((object)$"exception while setting reform at index {num3} max={platformSystem.reformData.Length} {ex.Message}"); } } } private static void PaintTropics(PlatformSystem platformSystem) { //IL_0094: 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_009c: Unknown result type (might be due to invalid IL or missing references) float[] array = ((Math.Abs(platformSystem.planet.radius - 200f) < 0.01f) ? TropicLats : GetTropicLatitudes(platformSystem)); int[] array2 = new int[2] { 1, -1 }; List list = new List(); float coordLineOffset = GetCoordLineOffset(platformSystem.planet); float[] array3 = array; foreach (float num in array3) { if (PluginConfig.LatitudeOutOfBounds(num)) { continue; } int[] array4 = array2; foreach (int num2 in array4) { for (float num3 = -179.9f; num3 < 180f; num3 += coordLineOffset) { Vector3 val = GeoUtil.LatLonToPosition(num * (float)num2, num3, platformSystem.planet.radius); int reformIndexForPosition = platformSystem.GetReformIndexForPosition(val); if (reformIndexForPosition >= 0) { list.Add(reformIndexForPosition); } } } } foreach (int item in list) { platformSystem.SetReformType(item, 1); platformSystem.SetReformColor(item, GetCustomColorIndex(GuideMarkTypes.Tropic)); } } private static void PaintPoles(PlatformSystem platformSystem) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) float[] array = ((Math.Abs(platformSystem.planet.radius - 200f) < 0.01f) ? TropicLats : GetTropicLatitudes(platformSystem)); List list = new List(); float coordLineOffset = GetCoordLineOffset(platformSystem.planet); for (float num = -90f; num < 90f; num += coordLineOffset) { if (Math.Abs(num) <= Math.Abs(array[0]) + coordLineOffset || PluginConfig.LatitudeOutOfBounds(num)) { continue; } for (float num2 = -179.9f; num2 < 180f; num2 += coordLineOffset) { Vector3 val = GeoUtil.LatLonToPosition(num, num2, platformSystem.planet.radius); int reformIndexForPosition = platformSystem.GetReformIndexForPosition(val); if (reformIndexForPosition >= 0) { list.Add(reformIndexForPosition); } } } int customColorIndex = GetCustomColorIndex(GuideMarkTypes.Pole); foreach (int item in list) { platformSystem.SetReformType(item, 1); platformSystem.SetReformColor(item, customColorIndex); } } private static float[] GetTropicLatitudes(PlatformSystem platformSystem) { //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_0043: Unknown result type (might be due to invalid IL or missing references) int num = 0; List list = new List(); float coordLineOffset = GetCoordLineOffset(platformSystem.planet); for (float num2 = -89.9f; num2 < 90f; num2 += coordLineOffset) { Vector3 val = GeoUtil.LatLonToPosition(num2, 0f, platformSystem.planet.radius); ((Vector3)(ref val)).Normalize(); int num3 = PlatformSystem.DetermineLongitudeSegmentCount(Mathf.FloorToInt(Mathf.Abs((float)((double)Mathf.Asin(val.y) / 6.28318548202515) * (float)platformSystem.segment)), platformSystem.segment); if (num != num3) { logger.LogDebug((object)$"at lat = {num2} length is {num3}, previous len was {num}"); list.Add(num2); } num = num3; } return list.ToArray(); } public static float GetCoordLineOffset(PlanetData planet, float baseRate = 0.25f) { float num = baseRate; if (planet.radius > 201f) { num /= planet.radius / 200f; } return num; } public static void InterpolateMissingIndexes(List indexes) { List list = new List(); for (int i = 1; i < indexes.Count; i++) { int num = indexes[i]; int num2 = indexes[i - 1]; if (num2 != num - 1 && num - num2 < 8) { for (int j = num2 + 1; j < num; j++) { list.Add(j); } } } indexes.AddRange(list); } } public readonly struct LatLon : IEquatable { private readonly int _lat; private readonly int _lng; private static readonly Dictionary> PoolLatToLonToInstance = new Dictionary>(); public readonly int Precision; public float Lat { get { if (Precision != 1) { return (float)_lat / (float)Precision; } return _lat; } } public float Long { get { if (Precision != 1) { return (float)_lng / (float)Precision; } return _lng; } } public static LatLon Empty => new LatLon(-1000, -1000, 1); private LatLon(int lat, int lng, int precision) { _lat = lat; _lng = lng; Precision = precision; } public int RawLat() { return _lat; } public int RawLon() { return _lng; } public static LatLon FromCoords(double lat, double lon, int precisionMultiple = 1) { if (precisionMultiple != 1) { if (precisionMultiple < 1) { throw new InvalidDataException("Invalid precision multiple " + precisionMultiple); } if (precisionMultiple % 10 != 0) { throw new InvalidDataException("Invalid precision multiple " + precisionMultiple); } } int num = ((lat < 0.0) ? Mathf.CeilToInt((float)lat * (float)precisionMultiple) : Mathf.FloorToInt((float)lat * (float)precisionMultiple)); int num2 = ((lon < 0.0) ? Mathf.CeilToInt((float)lon * (float)precisionMultiple) : Mathf.FloorToInt((float)lon * (float)precisionMultiple)); if (!PoolLatToLonToInstance.TryGetValue(num, out var value)) { value = new Dictionary(); PoolLatToLonToInstance[num] = value; } if (!value.TryGetValue(num2, out var value2)) { value2 = (value[num2] = new LatLon(num, num2, precisionMultiple)); } return value2; } public bool Equals(LatLon other) { if (_lat == other._lat) { return _lng == other._lng; } return false; } public override bool Equals(object obj) { if (obj == null) { return false; } if (obj.GetType() != GetType()) { return false; } return Equals((LatLon)obj); } public override int GetHashCode() { return (_lat * 397) ^ _lng; } public bool IsEmpty() { if (Precision != 0) { if (_lat == Empty._lat) { return _lng == Empty._lng; } return false; } return true; } public override string ToString() { return $"{Lat},{Long}"; } public LatLon Offset(int latOffset, int lonOffset) { return FromCoords(Lat + (float)latOffset, Long + (float)lonOffset, Precision); } public static HashSet GetKnownValues() { HashSet hashSet = new HashSet(); foreach (Dictionary value in PoolLatToLonToInstance.Values) { foreach (LatLon value2 in value.Values) { hashSet.Add(value2); } } return hashSet; } } public class Log { public static ManualLogSource logger; private static Dictionary _logCount = new Dictionary(); public static void LogAndPopupMessage(string message, bool playSound = false) { UIRealtimeTip.Popup(message, playSound, 0); logger.LogWarning((object)("Popped up message " + message)); } public static void Debug(string message) { logger.LogDebug((object)$"[{DateTime.Now:HH:mm:ss.fff}] {message}"); } public static void Warn(string message) { logger.LogWarning((object)$"[{DateTime.Now:HH:mm:ss.fff}] {message}"); } public static void LogNTimes(string msg, int maxTimes, params object[] args) { if (!_logCount.ContainsKey(msg) || maxTimes < 0) { _logCount[msg] = 0; } else if (_logCount[msg] > maxTimes) { return; } _logCount[msg]++; Debug(string.Format(msg, args)); } public static void Trace(string msg) { } } public class Pager { public List _items; public int PageNum; public int PageSize = 25; public int Count => _items.Count; public Pager(List items, int pageSize = 10) { PageSize = pageSize; _items = new List(items); } public void Reset() { PageNum = 0; } public void Next() { PageNum++; } public bool IsFirst() { return PageNum == 0; } public (int startIndex, int endIndex) GetIndexes() { int num = PageNum * PageSize; return (startIndex: PageNum * PageSize, endIndex: Math.Min(num + PageSize, _items.Count)); } public List GetPage() { var (num, num2) = GetIndexes(); return _items.GetRange(num, num2 - num); } public bool HasNext() { return _items.Count > GetIndexes().endIndex; } public bool IsEmpty() { return _items.Count == 0; } public void Previous() { PageNum--; } } public class PaveWorkItem { public PlanetFactory Factory; public Player Player; public Vector3 Position; } public static class PlanetAlterer { public static void RaiseLowerVeins() { //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_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: 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_0104: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) PlanetFactory factory = GameMain.mainPlayer.factory; PlatformSystem val = factory?.platformSystem; if (val == null) { return; } val.EnsureReformData(); if (val.reformData == null) { Log.logger.LogWarning((object)"no reform data skipping pave"); return; } PlanetData planet = factory.planet; PlanetPhysics physics = planet.physics; float num = 50f; BuildTool_Reform reformTool = GameMain.mainPlayer.controller.actionBuild.reformTool; bool flag = ((PluginConfig.buryVeinMode.Value == BuryVeinMode.Tool) ? reformTool.buryVeins : (PluginConfig.buryVeinMode.Value == BuryVeinMode.Bury)); float num2 = planet.realRadius + (flag ? (0f - num) : num); VeinData[] veinPool = factory.veinPool; for (int i = 1; i < factory.veinCursor; i++) { Vector3 pos = veinPool[i].pos; if (!PluginConfig.IsLatConstrained() || !PluginConfig.LatitudeOutOfBounds(GeoUtil.GetLatitudeDegForPosition(pos))) { int colliderId = veinPool[i].colliderId; ColliderData colliderData = physics.GetColliderData(colliderId); Vector3 pos2 = ((Vector3)(ref colliderData.pos)).normalized * (num2 + 0.4f); int num3 = colliderId >> 20; int num4 = colliderId & 0xFFFFF; physics.colChunks[num3].colliderPool[num4].pos = pos2; veinPool[i].pos = ((Vector3)(ref pos)).normalized * num2; GameMain.gpuiManager.AlterModel((int)veinPool[i].modelIndex, veinPool[i].modelId, i, veinPool[i].pos, false); physics.SetPlanetPhysicsColliderDirty(); } } GameMain.gpuiManager.SyncAllGPUBuffer(); } public static void UpdateVegeHeight(PlanetFactory factory) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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) VegeData[] vegePool = factory.vegePool; int vegeCursor = factory.vegeCursor; float num = factory.planet.realRadius + 0.2f; for (int i = 1; i < vegeCursor; i++) { Vector3 pos = vegePool[i].pos; if (!PluginConfig.IsLatConstrained() || !PluginConfig.LatitudeOutOfBounds(GeoUtil.GetLatitudeDegForPosition(pos))) { vegePool[i].pos = ((Vector3)(ref pos)).normalized * num; GameMain.gpuiManager.AlterModel((int)vegePool[i].modelIndex, vegePool[i].modelId, i, vegePool[i].pos, vegePool[i].rot, false); } } GameMain.gpuiManager.SyncAllGPUBuffer(); } } public static class PlanetPainter { public static bool PaintPlanet(PlatformSystem platformSystem, ReformIndexInfoProvider reformInfoProvider) { int maxReformCount = platformSystem.maxReformCount; Player mainPlayer = GameMain.mainPlayer; PlayerAction_Build val = ((mainPlayer != null) ? mainPlayer.controller.actionBuild : null); if (val == null) { return true; } int num = 1; switch (PluginConfig.foundationDecorationMode.Value) { case FoundationDecorationMode.Tool: num = val.reformTool.brushType; break; case FoundationDecorationMode.Paint: num = 1; break; case FoundationDecorationMode.Decorate: num = 2; break; case FoundationDecorationMode.Clear: num = 7; break; default: Log.Warn($"unexpected brush type requested {PluginConfig.foundationDecorationMode.Value}"); break; } int num2 = 0; bool result = false; bool flag = false; for (int i = 0; i < maxReformCount; i++) { if (PluginConfig.IsLatConstrained() && PluginConfig.LatitudeOutOfBounds(reformInfoProvider.GetForIndex(i).Lat)) { continue; } int num3 = ((!platformSystem.IsTerrainReformed(platformSystem.GetReformType(i))) ? 1 : 0); if (num3 > 0 && PluginConfig.foundationConsumption.Value != OperationMode.FullCheat) { num2 += num3; if (!StorageSystemManager.RemoveItems(1131, num3).successful) { if (PluginConfig.foundationConsumption.Value == OperationMode.Honest) { Log.LogAndPopupMessage("Out of foundation, halting."); result = true; break; } if (!flag) { flag = true; Log.LogAndPopupMessage("All foundation used, continuing"); } } } platformSystem.SetReformType(i, num); platformSystem.SetReformColor(i, val.reformTool.brushColor); } GameMain.mainPlayer.mecha.AddConsumptionStat(1131, num2, GameMain.mainPlayer.nearestFactory); return result; } } public enum BuryVeinMode { [Description("Use game setting for raise/lower. Note that the raise/lower checkbox must be enabled for this to have an impact")] Tool, [Description("Always bury veins, ignoring game setting. Note that the raise/lower checkbox must be enabled for this to have an impact")] Bury, [Description("Always raise veins, ignoring game setting. Note that the raise/lower checkbox must be enabled for this to have an impact")] Raise } public enum FoundationDecorationMode { [Description("Use game setting for brushType (whatever selected in game is what will be used)")] Tool, [Description("Ignore game setting, always use painted foundation (brushType: 1)")] Paint, [Description("Ignore game setting, always use painted foundation (brushType: 2)")] Decorate, [Description("Ignore game setting, always use 'no decoration' mode (brushType: 7)")] Clear } public enum OperationMode { [Description("Full cheat mode, resource not consumed")] FullCheat, [Description("Consume available resource and continue")] HalfCheat, [Description("Consume available resources, halt when empty")] Honest } public static class PluginConfig { public static ConfigEntry workItemsPerFrame; public static ConfigEntry maxInitMsPerFrame; public static ConfigEntry useActionBuildTearDown; public static ConfigEntry factoryTeardownRunTimePerFrame; public static ConfigEntry soilPileConsumption; public static ConfigEntry foundationConsumption; public static ConfigEntry maxLatitude; public static ConfigEntry minLatitude; public static ConfigEntry addGuideLines; public static ConfigEntry alterVeinState; public static ConfigEntry destroyFactoryAssemblers; public static ConfigEntry addGuideLinesEquator; public static ConfigEntry addGuideLinesMeridian; public static ConfigEntry addGuideLinesTropic; public static ConfigEntry addGuideLinesPoles; public static ConfigEntry minorMeridianInterval; public static ConfigEntry guideLinesEquatorColor; public static ConfigEntry guideLinesTropicColor; public static ConfigEntry guideLinesMeridianColor; public static ConfigEntry guideLinesMinorMeridianColor; public static ConfigEntry guideLinesPoleColor; public static ConfigEntry enableRegionColor; public static ConfigEntry regionColors; public static ConfigEntry buryVeinMode; public static ConfigEntry foundationDecorationMode; public static ConfigEntry guideLinesOnly; public static ConfigEntry removeVegetation; public static ConfigEntry deleteFactoryTrash; public static ConfigEntry disableTechRequirement; public static ConfigEntry skipDestroyingStations; public static ConfigEntry featureFastDelete; public static ConfigEntry originalReformButtonPosition; public static ConfigFile PluginConfigFile; public static void InitConfig(ConfigFile configFile) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Expected O, but got Unknown //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Expected O, but got Unknown //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Expected O, but got Unknown //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Expected O, but got Unknown //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Expected O, but got Unknown //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Expected O, but got Unknown //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Expected O, but got Unknown //IL_0399: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Expected O, but got Unknown //IL_0489: Unknown result type (might be due to invalid IL or missing references) //IL_0493: Expected O, but got Unknown //IL_04b8: Unknown result type (might be due to invalid IL or missing references) //IL_04c2: Expected O, but got Unknown PluginConfigFile = configFile; minLatitude = configFile.Bind("Control", "Min Latitude", -90, new ConfigDescription("Minimum latitude to work on. Set equal to Max Latitude to apply to entire planet", (AcceptableValueBase)(object)new AcceptableValueRange(-90, 90), Array.Empty())); maxLatitude = configFile.Bind("Control", "Max Latitude", 90, new ConfigDescription("Max latitude to work on, set min and max to the same value to apply to entire planet", (AcceptableValueBase)(object)new AcceptableValueRange(-90, 90), Array.Empty())); minLatitude.SettingChanged += OnMinLatitudeChange; maxLatitude.SettingChanged += OnMaxLatitudeChange; workItemsPerFrame = configFile.Bind("Performance", "WorkItemsPerFrame", 1, new ConfigDescription("Number of actions attempted per Frame. Default value is 1 (minimum since 0 would not do anything other than queue up work). Larger values might make the job complete more quickly, but will also slow your system down noticeably", (AcceptableValueBase)(object)new AcceptableValueRange(1, 25), new object[1] { "configEditOnly" })); maxInitMsPerFrame = configFile.Bind("Performance", "MaxInitMsPerFrame", 50, new ConfigDescription("How long to let init run per frame", (AcceptableValueBase)(object)new AcceptableValueRange(5, 250), new object[1] { "configEditOnly" })); useActionBuildTearDown = configFile.Bind("Performance", "UseActionBuildTearDown", true, new ConfigDescription("Method to use for teardown. Disabled causes exceptions sometimes but might run a little faster", (AcceptableValueBase)null, new object[1] { "configEditOnly" })); factoryTeardownRunTimePerFrame = configFile.Bind("Performance", "Teardown MS Per Frame", 500, new ConfigDescription("How long in ms to let the teardown task run per update. Note that 1000 ms means your game will be running at 1 UPS, but at 1 UPS the UI should still let you halt the task (click button again)\r\nLarger values might make the job complete more quickly, but will also slow your system down noticeably", (AcceptableValueBase)(object)new AcceptableValueRange(20, 3000), new object[1] { "configEditOnly" })); soilPileConsumption = configFile.Bind("Cheatiness", "SoilPileConsumption", OperationMode.FullCheat, "Controls whether bulldozing consumes and or requires available soil pile"); foundationConsumption = configFile.Bind("Cheatiness", "FoundationConsumption", OperationMode.Honest, "Controls whether bulldozing consumes and or requires available foundation pile"); disableTechRequirement = configFile.Bind("Cheatiness", "DisableTechRequirement", false, "Enable/disable tech requirement for using mod"); buryVeinMode = configFile.Bind("Veins", "BuryVeinMode", BuryVeinMode.Tool, "No impact if raise/lower checkbox is not set"); addGuideLinesEquator = configFile.Bind("Decoration", "AddGuideLinesEquator", true, "Enable/disable equator guideline individually. No effect if AddGuideLines is disabled"); addGuideLinesMeridian = configFile.Bind("Decoration", "AddGuideLinesMeridian", true, "Enable/disable of the meridian guidelines individually. No effect if AddGuideLines is disabled"); addGuideLinesTropic = configFile.Bind("Decoration", "AddGuideLinesTropic", true, "Enable/disable of the tropic guidelines individually. No effect if AddGuideLines is disabled"); addGuideLinesPoles = configFile.Bind("Decoration", "AddGuideLinesPoles", false, "Enable/disable painting polar areas. No effect if AddGuideLines is disabled. Poles are considered first 2 tropics"); minorMeridianInterval = configFile.Bind("Decoration", "MinorMeridianInterval", 0, new ConfigDescription("Paint meridians starting at 0 and incrementing by this value. E.g., a value of 10 would add a meridian line every 10 degrees 18, 36 total. 0 to disable", (AcceptableValueBase)(object)new AcceptableValueRange(0, 89), new object[1] { "meridians" })); guideLinesEquatorColor = configFile.Bind("CustomColors", "Equator Color", 7, new ConfigDescription("Index of color in palette to paint equator. Default is green", (AcceptableValueBase)(object)new AcceptableValueRange(0, 31), new object[1] { "color" })); guideLinesMeridianColor = configFile.Bind("CustomColors", "Meridian Color", 12, new ConfigDescription("Index of color in palette to paint major meridian lines", (AcceptableValueBase)(object)new AcceptableValueRange(0, 31), new object[1] { "color" })); guideLinesMinorMeridianColor = configFile.Bind("CustomColors", "Minor Meridian Color", 3, new ConfigDescription("Index of color in palette to paint minor meridian lines", (AcceptableValueBase)(object)new AcceptableValueRange(0, 31), new object[1] { "color" })); guideLinesTropicColor = configFile.Bind("CustomColors", "Tropic Color", 2, new ConfigDescription("Index of color in palette to paint tropic lines", (AcceptableValueBase)(object)new AcceptableValueRange(0, 31), new object[1] { "color" })); guideLinesPoleColor = configFile.Bind("CustomColors", "Pole Color", 1, new ConfigDescription("Index of color in palette to paint poles", (AcceptableValueBase)(object)new AcceptableValueRange(0, 31), new object[1] { "color" })); enableRegionColor = configFile.Bind("CustomColors", "Enable Region Color", false, "Enable painting colors based on coordinates"); regionColors = configFile.Bind("UIOnly", "Region Colors JSON", "", "Not for editing, use UI to define values"); guideLinesOnly = configFile.Bind("Decoration", "GuideLinesOnly", false, "Only add guidelines, don't pave entire planet"); foundationDecorationMode = configFile.Bind("Decoration", "FoundationDecorationMode", FoundationDecorationMode.Tool, "Change to have a permanent setting instead of tracking the game's current config"); deleteFactoryTrash = configFile.Bind("Destruction", "DeleteFactoryTrash", false, "Erase all items littered while destroying factory items"); removeVegetation = configFile.Bind("Destruction", "RemoveVegetation", true, "Erase vegetation"); skipDestroyingStations = configFile.Bind("Destruction", "SkipDestroyingStations", false, "Enable/disable teardown of logistics stations"); featureFastDelete = configFile.Bind("Destruction", "Enable Fast Delete", true, new ConfigDescription("Enable Raptor's fast delete for factory teardown", (AcceptableValueBase)null, new object[1] { "configEditOnly" })); alterVeinState = configFile.Bind("UIOnly", "AlterVeinState", false, new ConfigDescription("Don't edit, use UI checkbox. By default, veins will not be lowered or raised. Enabling takes much longer", (AcceptableValueBase)null, new object[1] { "uiEditOnly" })); destroyFactoryAssemblers = configFile.Bind("UIOnly", "DestroyFactoryAssemblers", false, "Don't edit, use UI checkbox. Destroy all factory machines (labs, assemblers, etc). It can be very slow so if you get bored waiting and want to delete stuff yourself, make sure to stop the bulldoze process."); addGuideLines = configFile.Bind("UIOnly", "AddGuideLines", true, "Don't edit, this property backs the checkbox in the UI. If enabled painted lines at certain points on planet will be added"); originalReformButtonPosition = configFile.Bind("UIOnly", "OriginalReformButtonPosition", "0,0", "Track where the button was before we started messing with it"); originalReformButtonPosition.Value = "0,0"; } private static void OnMaxLatitudeChange(object sender, EventArgs e) { if (sender is ConfigEntry val && minLatitude.Value > val.Value) { minLatitude.Value = maxLatitude.Value; } } private static void OnMinLatitudeChange(object sender, EventArgs e) { if (sender is ConfigEntry val && maxLatitude.Value < val.Value) { maxLatitude.Value = val.Value; } } public static string GetCurrentVeinsRaiseState() { Player mainPlayer = GameMain.mainPlayer; BuildTool_Reform val = ((mainPlayer != null) ? mainPlayer.controller.actionBuild.reformTool : null); if (val == null) { return "UNKNOWN"; } if (!((buryVeinMode.Value == BuryVeinMode.Tool) ? val.buryVeins : (buryVeinMode.Value == BuryVeinMode.Bury))) { return "restore"; } return "bury"; } public static void ResetConfigWindowOptionsToDefault() { foreach (ConfigDefinition key in PluginConfigFile.Keys) { if (!(key.Section == "UIOnly")) { ConfigEntryBase val = PluginConfigFile[key]; if (!((IList)val.Description.Tags).Contains((object?)"configEditOnly")) { val.BoxedValue = val.DefaultValue; } } } } public static bool LatitudeOutOfBounds(float latInDegrees) { if (!IsLatConstrained()) { return false; } if (!((float)maxLatitude.Value <= latInDegrees)) { return (float)minLatitude.Value >= latInDegrees; } return true; } public static bool IsLatConstrained() { if (maxLatitude.Value == minLatitude.Value) { return false; } if (maxLatitude.Value == 90) { return minLatitude.Value != -90; } return true; } public static bool NeedReformIndexProvider() { if (IsLatConstrained()) { return true; } if (enableRegionColor.Value) { return true; } if (guideLinesOnly.Value) { return true; } if (!addGuideLines.Value) { return false; } if (!addGuideLinesEquator.Value && !addGuideLinesMeridian.Value && !addGuideLinesPoles.Value && !addGuideLinesTropic.Value) { return minorMeridianInterval.Value > 0; } return true; } public static string GetLatRangeString() { int num = minLatitude.Value; string text = "° N"; if (num < 0) { num = -num; text = "° S"; } else if (num == 0) { text = "° "; } int num2 = maxLatitude.Value; string text2 = "° N"; if (num2 < 0) { num2 = -num2; text2 = "° S"; } else if (num2 == 0) { text2 = "° "; } return $"{num}{text} - {num2}{text2}"; } } public class PluginConfigWindow { [CompilerGenerated] private static class <>O { public static WindowFunction <0>__WindowFn; } public static bool visible; private static Rect _windowRect = new Rect((float)(Screen.width / 3 * 2), 100f, 500f, 820f); private static int _leftColumnWidth; public static bool NeedReinit; private static Texture2D _tooltipBg; private static Dictionary _customColorTextures = new Dictionary(); private static readonly Dictionary previousSelections = new Dictionary(); private static string _savedGUISkin; private static GUISkin _savedGUISkinObj; private static Color _savedColor; private static Color _savedBackgroundColor; private static Color _savedContentColor; private static GUISkin _mySkin; public static void OnOpen() { visible = true; } public static void OnClose() { visible = false; RestoreGuiSkinOptions(); } public static void OnGUI() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown if (RegionColorWindow.visible) { RegionColorWindow.OnGUI(); } if (Input.GetKeyDown((KeyCode)27)) { visible = false; return; } Init(); Rect windowRect = _windowRect; object obj = <>O.<0>__WindowFn; if (obj == null) { WindowFunction val = WindowFn; <>O.<0>__WindowFn = val; obj = (object)val; } _windowRect = GUILayout.Window(1297895555, windowRect, (WindowFunction)obj, "Bulldozer options", Array.Empty()); } private static void SaveCurrentGuiOptions() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) _savedBackgroundColor = GUI.backgroundColor; _savedContentColor = GUI.contentColor; _savedColor = GUI.color; GUI.backgroundColor = Color.white; GUI.contentColor = Color.white; GUI.color = Color.white; if ((Object)(object)_mySkin == (Object)null || NeedReinit) { _savedGUISkin = JsonUtility.ToJson((object)GUI.skin); _savedGUISkinObj = GUI.skin; _mySkin = ScriptableObject.CreateInstance(); JsonUtility.FromJsonOverwrite(_savedGUISkin, (object)_mySkin); GUI.skin = _mySkin; GUI.skin.button.normal.textColor = Color.white; GUI.skin.textArea.normal.textColor = Color.white; GUI.skin.textField.normal.textColor = Color.white; GUI.skin.toggle.normal.textColor = Color.white; GUI.skin.toggle.onNormal.textColor = Color.white; GUI.skin.button.normal.textColor = Color.white; GUI.skin.button.onNormal.textColor = Color.white; GUI.skin.button.onActive.textColor = Color.white; GUI.skin.button.active.textColor = Color.white; GUI.skin.label.hover.textColor = Color.white; GUI.skin.label.onNormal.textColor = Color.white; GUI.skin.label.normal.textColor = Color.white; } else { _savedGUISkinObj = GUI.skin; GUI.skin = _mySkin; } } private static void RestoreGuiSkinOptions() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) GUI.skin = _savedGUISkinObj; GUI.backgroundColor = _savedBackgroundColor; GUI.contentColor = _savedContentColor; GUI.color = _savedColor; } private static void Init() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown if (!((Object)(object)_tooltipBg == (Object)null) || NeedReinit) { Texture2D val = new Texture2D(1, 1, (TextureFormat)3, false); val.SetPixel(0, 0, Color.white); val.Apply(); _tooltipBg = val; InitWindowRect(); NeedReinit = false; } } private static void WindowFn(int id) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Expected O, but got Unknown //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Expected O, but got Unknown //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Expected O, but got Unknown //IL_01f7: Unknown result type (might be due to invalid IL or missing references) SaveCurrentGuiOptions(); GUILayout.BeginArea(new Rect(((Rect)(ref _windowRect)).width - 25f, 0f, 25f, 30f)); if (GUILayout.Button("X", Array.Empty())) { OnClose(); return; } GUILayout.EndArea(); GUILayout.BeginVertical(GUI.skin.box, Array.Empty()); DrawCenteredLabel("Hover over labels to see descriptions"); DrawResetAllButton(); string text = ""; foreach (ConfigDefinition key in PluginConfig.PluginConfigFile.Keys) { if (key.Section == "UIOnly") { continue; } ConfigEntryBase val = PluginConfig.PluginConfigFile[key]; if (!val.Description.Tags.Contains("configEditOnly")) { if (key.Section != text && key.Section == "CustomColors") { DrawCenteredLabel("0-15 are built in colors, 16-31 are user defined"); } if (text == "CustomColors" && key.Section != text && GUILayout.Button("Edit Regional Colors", Array.Empty())) { RegionColorWindow.Toggle(); } DrawSetting(val); text = key.Section; } } GUILayout.EndVertical(); if (GUI.tooltip != null) { GUI.skin = null; GUIStyle val2 = new GUIStyle { normal = new GUIStyleState { textColor = Color.white }, wordWrap = true, alignment = (TextAnchor)4, stretchHeight = true, stretchWidth = true }; float num = val2.CalcHeight(new GUIContent(GUI.tooltip), ((Rect)(ref _windowRect)).width) + 10f; int num2 = (int)((double)((Rect)(ref _windowRect)).height - (double)num * 1.25); GUI.Box(new Rect(0f, (float)num2, ((Rect)(ref _windowRect)).width, num * 1.25f), GUI.tooltip, val2); } GUI.DragWindow(); RestoreGuiSkinOptions(); } private static void DrawResetAllButton() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown GUILayout.BeginVertical(Array.Empty()); if (GUILayout.Button(new GUIContent("Reset", "Reset all settings to their default values"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MaxWidth(((Rect)(ref _windowRect)).width / 5f) })) { PluginConfig.ResetConfigWindowOptionsToDefault(); previousSelections.Clear(); } GUILayout.EndVertical(); } private static void DrawSetting(ConfigEntryBase configEntry) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown GUILayout.BeginHorizontal(Array.Empty()); DrawSettingName(configEntry); bool flag = false; if (configEntry.SettingType.IsEnum) { flag = AddPicker(configEntry, configEntry.SettingType, configEntry.BoxedValue); } if (!flag && configEntry.SettingType == typeof(bool)) { flag = DrawBoolField(configEntry); } if (!flag && configEntry.SettingType == typeof(int)) { flag = DrawRangeField(configEntry); } if (!flag) { GUILayout.Label(new GUIContent(configEntry.BoxedValue.ToString(), "Current setting"), Array.Empty()); } GUILayout.EndHorizontal(); } private static bool DrawRangeField(ConfigEntryBase configEntry) { //IL_0107: Unknown result type (might be due to invalid IL or missing references) bool flag = configEntry.Description.Tags.Contains("color"); if (!(configEntry.Description.AcceptableValues is AcceptableValueRange val)) { return false; } GUILayout.BeginHorizontal(Array.Empty()); float num = (float)Convert.ToDouble(configEntry.BoxedValue, CultureInfo.InvariantCulture); float num2 = (float)Convert.ToDouble(val.MinValue, CultureInfo.InvariantCulture); float num3 = (float)Convert.ToDouble(val.MaxValue, CultureInfo.InvariantCulture); float num4 = GUILayout.HorizontalSlider(num, num2, num3, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MinWidth(200f) }); if (Math.Abs(num4 - num) > Mathf.Abs(num3 - num2) / 1000f) { object boxedValue = Convert.ChangeType(num4, configEntry.SettingType, CultureInfo.InvariantCulture); configEntry.BoxedValue = boxedValue; } string text = configEntry.BoxedValue.ToString(); string text2 = GUILayout.TextField(text, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); if (flag) { GUILayout.Label((Texture)(object)GetTextureForColor(GetColorByIndex((int)configEntry.BoxedValue)), Array.Empty()); } GUILayout.EndHorizontal(); if (text2 != text) { try { float num5 = Mathf.Clamp((float)Convert.ToDouble(text2, CultureInfo.InvariantCulture), num2, num3); configEntry.BoxedValue = (int)num5; } catch (FormatException) { } } return true; } public static Color GetColorByIndex(int index) { //IL_0056: 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) if (index < 0 || index > 31) { Log.logger.LogWarning((object)$"color index out of bounds {index}"); index = 3; } Color[] reformColors = Configs.builtin.reformColors; if (index < 16) { return reformColors[index]; } return GameMain.mainPlayer.factory.platformSystem.reformCustomColors[index - 16]; } public static Texture2D GetTextureForColor(Color color) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0012: 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_003f: 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) if (_customColorTextures.ContainsKey(color)) { return _customColorTextures[color]; } Texture2D val = new Texture2D(15, 15, (TextureFormat)3, false); Color[] array = (Color[])(object)new Color[((Texture)val).width * ((Texture)val).height]; for (int i = 0; i < array.Length; i++) { array[i] = color; } val.SetPixels(0, 0, ((Texture)val).width, ((Texture)val).height, array); val.Apply(); _customColorTextures[color] = val; return val; } private static void DrawSettingName(ConfigEntryBase setting) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown GUILayout.Label(new GUIContent(setting.Definition.Key, setting.Description.Description), (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width((float)_leftColumnWidth), GUILayout.MaxWidth((float)_leftColumnWidth) }); GUILayout.FlexibleSpace(); } private static bool AddPicker(ConfigEntryBase entry, Type enumType, object currentValue) { if (!enumType.IsEnum) { Debug.LogWarning((object)"picker must only be used with enums"); return false; } string[] names = Enum.GetNames(enumType); string selectedName = Enum.GetName(enumType, currentValue); int num = -1; for (int i = 0; i < names.Length; i++) { string text = names[i]; if (selectedName == text) { num = i; } } if (num == -1) { Console.WriteLine($"did not find index of {currentValue} for {enumType}"); return false; } IEnumerable source = names.Select((string n) => GetGuiContent(enumType, n, entry.Description.Description, selectedName == n)); GUILayout.BeginVertical(GUIStyle.op_Implicit("Box"), Array.Empty()); if (!previousSelections.ContainsKey(entry.Definition.Key)) { previousSelections[entry.Definition.Key] = num; } num = GUILayout.Toolbar(previousSelections[entry.Definition.Key], source.ToArray(), Array.Empty()); if (previousSelections[entry.Definition.Key] != num) { object boxedValue = Enum.Parse(enumType, names[num], ignoreCase: true); entry.BoxedValue = boxedValue; previousSelections[entry.Definition.Key] = num; } GUILayout.EndVertical(); return true; } private static GUIContent GetGuiContent(Type enumType, string sourceValue, string parentDescription, bool currentlySelected) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown DescriptionAttribute descriptionAttribute = enumType.GetMember(sourceValue).FirstOrDefault()?.GetCustomAttributes(typeof(DescriptionAttribute), inherit: false).Cast().FirstOrDefault(); string text = (currentlySelected ? "(selected) " : ""); string text2 = (currentlySelected ? ("" + sourceValue + "") : sourceValue); if (descriptionAttribute == null) { return new GUIContent(text2); } return new GUIContent(text2, "" + parentDescription + "\n\n" + text + descriptionAttribute.Description); } private static bool DrawBoolField(ConfigEntryBase setting) { if (setting.SettingType != typeof(bool)) { return false; } bool flag = (bool)setting.BoxedValue; GUILayout.BeginHorizontal(Array.Empty()); bool flag2 = GUILayout.Toggle(flag, flag ? "Enabled" : "Disabled", Array.Empty()); if (flag2 != flag) { setting.BoxedValue = flag2; } GUILayout.EndHorizontal(); return true; } private static void InitWindowRect() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Min(Screen.width, 650); int num2 = ((Screen.height < 560) ? Screen.height : 560); int num3 = Mathf.RoundToInt((float)(Screen.width - num) / 2f); int num4 = Mathf.RoundToInt((float)(Screen.height - num2) / 2f); _windowRect = new Rect((float)num3, (float)num4, (float)num, (float)num2); _leftColumnWidth = Mathf.RoundToInt(((Rect)(ref _windowRect)).width / 2.5f); } public static void DrawCenteredLabel(string text, params GUILayoutOption[] options) { GUILayout.BeginHorizontal(options); GUILayout.FlexibleSpace(); GUILayout.Label(text, Array.Empty()); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); } [HarmonyPrefix] [HarmonyPatch(typeof(UIGame), "On_E_Switch")] public static bool UIGame_On_E_Switch_Prefix() { if (visible) { visible = false; } return true; } } public class UIElements : MonoBehaviour { private const string DEFAULT_TIP_MESSAGE_PT1 = "Adds foundation to entire planet. Any existing foundation decoration will be lost.\n"; private const string DEFAULT_TIP_MESSAGE_LAT_PT1 = "Adds foundation to all locations in selected latitude range.\n"; private const string DEFAULT_TIP_MESSAGE_VEINS_NO_ALTER = "Veins will not be raised or lowered"; private const string DEFAULT_TIP_MESSAGE_DESTROY_FACTORY = "Destroy all factory machines"; private const string DEFAULT_TIP_MESSAGE_DESTROY_FACTORY_IN_LAT = "Destroy all factory machines in selected latitude range"; public static ManualLogSource logger; private readonly List gameObjectsToDestroy = new List(); public GameObject DrawEquatorCheck; public Sprite spriteChecked; public Sprite spriteUnChecked; public UIButton PaveActionButton; public RectTransform BulldozeButton; public Text countText; public Text buttonHotkeyTextComponent; public Transform CountTransform; public CheckboxControl drawEquatorCheckboxButton; private bool _alterVeinsField; private Transform _bulldozeIcon; private bool _destroyFactoryMachines; private bool _drawEquatorField = true; private Image _iconImage; private bool _techUnlocked; private bool _readyToGo; [NonSerialized] public Image AlterVeinsCheckBoxImage; [NonSerialized] public Image CheckBoxImage; [NonSerialized] public Image ConfigIconImage; private bool currentTipMessageIsDefault = true; [NonSerialized] public Image DestroyMachinesCheckBoxImage; private Text hover; private UIButton mainActionButton; public int initPercent; private RectTransform buttonOneRectTransform; private GameObject AlterVeinsCheck; private GameObject DestroyMachinesCheck; private GameObject ConfigButton; private bool _initialized; public bool IsUsable { get { if (_initialized && (Object)(object)BulldozeButton != (Object)null && (Object)(object)PaveActionButton != (Object)null && (Object)(object)PaveActionButton.button != (Object)null && (Object)(object)mainActionButton != (Object)null) { return (Object)(object)mainActionButton.button != (Object)null; } return false; } } public bool TechUnlockedState { get { return _techUnlocked; } set { _techUnlocked = value; if (!((Object)(object)mainActionButton == (Object)null) && !((Object)(object)mainActionButton.button == (Object)null)) { if (!_techUnlocked) { ((Selectable)mainActionButton.button).interactable = false; mainActionButton.tips.tipText = "Research Universe Exploration 3 to Unlock"; } else { ((Selectable)mainActionButton.button).interactable = true; mainActionButton.tips.tipText = ConstructTipMessageDependentOnConfig(); } } } } public bool ReadyForAction { set { _readyToGo = value; if (!((Object)(object)mainActionButton == (Object)null) && !((Object)(object)mainActionButton.button == (Object)null)) { if (_techUnlocked && !_readyToGo) { ((Selectable)mainActionButton.button).interactable = false; mainActionButton.tips.tipText = $"Initializing ({initPercent}% complete)"; } else if (_readyToGo && _techUnlocked) { ((Selectable)mainActionButton.button).interactable = true; mainActionButton.tips.tipText = ConstructTipMessageDependentOnConfig(); } } } } public void Update() { if (!IsUsable) { return; } if (_drawEquatorField != PluginConfig.addGuideLines.Value) { if ((Object)(object)CheckBoxImage != (Object)null) { CheckBoxImage.sprite = (PluginConfig.addGuideLines.Value ? spriteChecked : spriteUnChecked); } _drawEquatorField = PluginConfig.addGuideLines.Value; } if (_alterVeinsField != PluginConfig.alterVeinState.Value) { if ((Object)(object)AlterVeinsCheckBoxImage != (Object)null) { AlterVeinsCheckBoxImage.sprite = (PluginConfig.alterVeinState.Value ? spriteChecked : spriteUnChecked); } _alterVeinsField = PluginConfig.alterVeinState.Value; } if (_destroyFactoryMachines != PluginConfig.destroyFactoryAssemblers.Value) { if ((Object)(object)DestroyMachinesCheckBoxImage != (Object)null) { DestroyMachinesCheckBoxImage.sprite = (PluginConfig.destroyFactoryAssemblers.Value ? spriteChecked : spriteUnChecked); } _destroyFactoryMachines = PluginConfig.destroyFactoryAssemblers.Value; } if (!_techUnlocked && PluginConfig.disableTechRequirement.Value) { TechUnlockedState = true; } if (_destroyFactoryMachines) { if ((Object)(object)mainActionButton != (Object)null && currentTipMessageIsDefault) { currentTipMessageIsDefault = false; if (PluginConfig.IsLatConstrained()) { mainActionButton.tips.tipText = "Destroy all factory machines in selected latitude range"; } else { mainActionButton.tips.tipText = "Destroy all factory machines"; } } } else if ((Object)(object)mainActionButton != (Object)null && !currentTipMessageIsDefault) { currentTipMessageIsDefault = true; mainActionButton.tips.tipText = ConstructTipMessageDependentOnConfig(); } } private string ConstructTipMessageDependentOnConfig() { string text = "Will attempt to " + PluginConfig.GetCurrentVeinsRaiseState() + " all veins for planet."; if (PluginConfig.IsLatConstrained()) { text = "Will attempt to " + PluginConfig.GetCurrentVeinsRaiseState() + " veins in selected latitude range (" + PluginConfig.GetLatRangeString() + ")"; } string text2 = (PluginConfig.alterVeinState.Value ? text : "Veins will not be raised or lowered"); currentTipMessageIsDefault = !PluginConfig.alterVeinState.Value; if (PluginConfig.IsLatConstrained()) { return "Adds foundation to all locations in selected latitude range.\n" + text2; } return "Adds foundation to entire planet. Any existing foundation decoration will be lost.\n" + text2; } private static void ResetButtonPos(RectTransform rectTransform) { //IL_0006: 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_00c7: Unknown result type (might be due to invalid IL or missing references) string text = $"{rectTransform.anchoredPosition.x},{rectTransform.anchoredPosition.y}"; if (PluginConfig.originalReformButtonPosition.Value == "0,0") { PluginConfig.originalReformButtonPosition.Value = text; } else { if (!(text != PluginConfig.originalReformButtonPosition.Value)) { return; } string[] array = PluginConfig.originalReformButtonPosition.Value.Split(new char[1] { ',' }); try { if (float.TryParse(array[0].Trim(), out var result)) { if (float.TryParse(array[1].Trim(), out var result2)) { Log.Debug($"Setting button back to original {PluginConfig.originalReformButtonPosition.Value} {result}, {result2}"); rectTransform.anchoredPosition = new Vector2(result, result2); } else { Log.Debug("Failed to parse yvalue " + array[1]); } } else { Log.Debug("Failed to parse xvalue " + array[0]); } } catch (Exception) { } } } public bool TryAddBulldozeComponents(RectTransform environmentModificationContainer, GameObject foundationButton, Action action, out string failureReason) { failureReason = null; try { Unload(); if ((Object)(object)environmentModificationContainer == (Object)null) { failureReason = "Unable to initialize Bulldozer UI: Environment Modification container is null."; return false; } if (!InitOnOffSprites(out failureReason) || !InitActionButton(foundationButton, action, out failureReason)) { Unload(); return false; } InitDrawEquatorCheckbox(environmentModificationContainer, foundationButton); InitAlterVeinsCheckbox(environmentModificationContainer); InitDestroyMachinesCheckbox(environmentModificationContainer); InitConfigButton(environmentModificationContainer); if ((Object)(object)CheckBoxImage == (Object)null || (Object)(object)AlterVeinsCheckBoxImage == (Object)null || (Object)(object)DestroyMachinesCheckBoxImage == (Object)null || (Object)(object)ConfigIconImage == (Object)null) { failureReason = "Unable to initialize Bulldozer UI: one or more custom controls could not be created."; Unload(); return false; } _initialized = true; return true; } catch (Exception ex) { failureReason = "Unable to initialize Bulldozer UI controls: " + ex.Message; Unload(); return false; } } private bool InitActionButton(GameObject buttonToCopy, Action action, out string failureReason) { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_009a: Unknown result type (might be due to invalid IL or missing references) failureReason = null; if ((Object)(object)buttonToCopy == (Object)null) { failureReason = "Unable to initialize Bulldozer UI: foundation button is null."; return false; } buttonOneRectTransform = buttonToCopy.gameObject.GetComponent(); if ((Object)(object)buttonOneRectTransform == (Object)null) { failureReason = "Unable to initialize Bulldozer UI: foundation button has no RectTransform."; return false; } countText = null; ResetButtonPos(buttonOneRectTransform); if (GameMain.sandboxToolsEnabled) { buttonOneRectTransform.anchoredPosition = new Vector2((float)((double)buttonOneRectTransform.anchoredPosition.x - (double)buttonOneRectTransform.sizeDelta.x / 1.5), buttonOneRectTransform.anchoredPosition.y); } BulldozeButton = CopyButton(buttonOneRectTransform, Vector2.right * buttonOneRectTransform.sizeDelta.x, out countText, Helper.GetSprite("bulldoze"), action); if ((Object)(object)BulldozeButton == (Object)null || (Object)(object)mainActionButton == (Object)null || (Object)(object)mainActionButton.button == (Object)null) { failureReason = "Unable to initialize Bulldozer UI: foundation button does not contain the expected action control."; return false; } gameObjectsToDestroy.Add(((Component)BulldozeButton).gameObject); PaveActionButton = mainActionButton; if ((Object)(object)countText != (Object)null) { gameObjectsToDestroy.Add(((Component)countText).gameObject); } return true; } private bool InitOnOffSprites(out string failureReason) { //IL_004e: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) failureReason = null; Texture2D val = Resources.Load("ui/textures/sprites/icons/checkbox-off"); Texture2D val2 = Resources.Load("ui/textures/sprites/icons/checkbox-on"); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { failureReason = "Unable to initialize Bulldozer UI: checkbox sprites could not be loaded."; return false; } spriteChecked = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f)); spriteUnChecked = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); return true; } private void InitDrawEquatorCheckbox(RectTransform environmentModificationContainer, GameObject button1) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: 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_018d: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) DrawEquatorCheck = new GameObject("Draw equator line"); gameObjectsToDestroy.Add(DrawEquatorCheck); RectTransform val = DrawEquatorCheck.AddComponent(); ((Transform)val).SetParent(((Component)environmentModificationContainer).transform, false); val.anchorMax = new Vector2(0f, 1f); val.anchorMin = new Vector2(0f, 1f); val.sizeDelta = new Vector2(20f, 20f); val.pivot = new Vector2(0f, 0.5f); val.anchoredPosition = new Vector2(GetCheckBoxXValue(), -90f); drawEquatorCheckboxButton = ((Component)val).gameObject.AddComponent(); drawEquatorCheckboxButton.HoverText = "Add painted guidelines at various locations (equator, tropics, meridians configurable)"; drawEquatorCheckboxButton.onClick += OnDrawEquatorCheckClick; gameObjectsToDestroy.Add(((Component)drawEquatorCheckboxButton).gameObject); if ((Object)(object)countText != (Object)null) { hover = Object.Instantiate(countText, ((Component)environmentModificationContainer).transform, true); gameObjectsToDestroy.Add(((Component)hover).gameObject); RectTransform component = ((Component)hover).GetComponent(); RectTransform component2 = ((Component)environmentModificationContainer).GetComponent(); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(0f, 1f); component.sizeDelta = new Vector2(500f, 20f); component.anchoredPosition = new Vector2(620f, ((Component)component2).transform.position.y - 115f); drawEquatorCheckboxButton.textObject = hover; } gameObjectsToDestroy.Add(((Component)drawEquatorCheckboxButton).gameObject); CheckBoxImage = ((Component)drawEquatorCheckboxButton).gameObject.AddComponent(); ((Graphic)CheckBoxImage).color = new Color(0.8f, 0.8f, 0.8f, 1f); gameObjectsToDestroy.Add(((Component)CheckBoxImage).gameObject); CheckBoxImage.sprite = (PluginConfig.addGuideLines.Value ? spriteChecked : spriteUnChecked); } private void InitAlterVeinsCheckbox(RectTransform environmentModificationContainer) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0044: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) AlterVeinsCheck = new GameObject("Repave"); gameObjectsToDestroy.Add(AlterVeinsCheck); RectTransform obj = AlterVeinsCheck.AddComponent(); ((Transform)obj).SetParent(((Component)environmentModificationContainer).transform, false); obj.anchorMax = new Vector2(0f, 1f); obj.anchorMin = new Vector2(0f, 1f); obj.sizeDelta = new Vector2(20f, 20f); obj.pivot = new Vector2(0f, 0.5f); obj.anchoredPosition = new Vector2(GetCheckBoxXValue(), -105f); CheckboxControl checkboxControl = ((Component)obj).gameObject.AddComponent(); checkboxControl.HoverText = "Check to attempt to raise or lower all veins. No foundation will be placed"; if ((Object)(object)countText != (Object)null) { Text val = Object.Instantiate(countText, ((Component)environmentModificationContainer).transform, true); gameObjectsToDestroy.Add(((Component)val).gameObject); RectTransform component = ((Component)val).GetComponent(); RectTransform component2 = ((Component)environmentModificationContainer).GetComponent(); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(0f, 1f); component.sizeDelta = new Vector2(500f, 20f); component.anchoredPosition = new Vector2(700f, ((Component)component2).transform.position.y - 115f); checkboxControl.textObject = val; } gameObjectsToDestroy.Add(((Component)checkboxControl).gameObject); AlterVeinsCheckBoxImage = ((Component)checkboxControl).gameObject.AddComponent(); ((Graphic)AlterVeinsCheckBoxImage).color = new Color(0.8f, 0.8f, 0.8f, 1f); gameObjectsToDestroy.Add(((Component)AlterVeinsCheckBoxImage).gameObject); AlterVeinsCheckBoxImage.sprite = (PluginConfig.alterVeinState.Value ? spriteChecked : spriteUnChecked); checkboxControl.onClick += OnAlterVeinCheckClick; } private void InitDestroyMachinesCheckbox(RectTransform environmentModificationContainer) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0044: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) DestroyMachinesCheck = new GameObject("DestroyMachines"); gameObjectsToDestroy.Add(DestroyMachinesCheck); RectTransform obj = DestroyMachinesCheck.AddComponent(); ((Transform)obj).SetParent(((Component)environmentModificationContainer).transform, false); obj.anchorMax = new Vector2(0f, 1f); obj.anchorMin = new Vector2(0f, 1f); obj.sizeDelta = new Vector2(20f, 20f); obj.pivot = new Vector2(0f, 0.5f); obj.anchoredPosition = new Vector2(GetCheckBoxXValue(), -120f); CheckboxControl checkboxControl = ((Component)obj).gameObject.AddComponent(); checkboxControl.HoverText = "Clear all factory machines. Skip adding foundation."; if ((Object)(object)countText != (Object)null) { Text val = Object.Instantiate(countText, ((Component)environmentModificationContainer).transform, true); gameObjectsToDestroy.Add(((Component)val).gameObject); RectTransform component = ((Component)val).GetComponent(); RectTransform component2 = ((Component)environmentModificationContainer).GetComponent(); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(0f, 1f); component.sizeDelta = new Vector2(800f, 20f); component.anchoredPosition = new Vector2(700f, ((Component)component2).transform.position.y - 115f); checkboxControl.textObject = val; } gameObjectsToDestroy.Add(((Component)checkboxControl).gameObject); DestroyMachinesCheckBoxImage = ((Component)checkboxControl).gameObject.AddComponent(); ((Graphic)DestroyMachinesCheckBoxImage).color = new Color(0.8f, 0.8f, 0.8f, 1f); gameObjectsToDestroy.Add(((Component)DestroyMachinesCheckBoxImage).gameObject); DestroyMachinesCheckBoxImage.sprite = (PluginConfig.destroyFactoryAssemblers.Value ? spriteChecked : spriteUnChecked); checkboxControl.onClick += OnDestroyMachinesCheckClick; } private float GetCheckBoxXValue() { if ((Object)(object)BulldozeButton != (Object)null && GameMain.sandboxToolsEnabled) { return 310f; } return 350f; } private void InitConfigButton(RectTransform environmentModificationContainer) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0044: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: 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_014b: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) ConfigButton = new GameObject("Config"); gameObjectsToDestroy.Add(ConfigButton); RectTransform obj = ConfigButton.AddComponent(); ((Transform)obj).SetParent(((Component)environmentModificationContainer).transform, false); obj.anchorMax = new Vector2(0f, 1f); obj.anchorMin = new Vector2(0f, 1f); obj.sizeDelta = new Vector2(20f, 20f); obj.pivot = new Vector2(0f, 0.5f); obj.anchoredPosition = new Vector2(GetCheckBoxXValue() + 18f, -120f); CheckboxControl checkboxControl = ((Component)obj).gameObject.AddComponent(); checkboxControl.HoverText = "Open config"; if ((Object)(object)countText != (Object)null) { Text val = Object.Instantiate(countText, ((Component)environmentModificationContainer).transform, true); gameObjectsToDestroy.Add(((Component)val).gameObject); RectTransform component = ((Component)val).GetComponent(); RectTransform component2 = ((Component)environmentModificationContainer).GetComponent(); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(0f, 1f); component.sizeDelta = new Vector2(800f, 20f); component.anchoredPosition = new Vector2(400f, ((Component)component2).transform.position.y - 115f); checkboxControl.textObject = val; } gameObjectsToDestroy.Add(((Component)checkboxControl).gameObject); ConfigIconImage = ((Component)checkboxControl).gameObject.AddComponent(); ((Graphic)ConfigIconImage).color = new Color(0.8f, 0.8f, 0.8f, 1f); gameObjectsToDestroy.Add(((Component)ConfigIconImage).gameObject); ConfigIconImage.sprite = Helper.GetSprite("bulldoze"); checkboxControl.onClick += delegate { PluginConfigWindow.visible = !PluginConfigWindow.visible; }; } public void Unload() { _initialized = false; if ((Object)(object)buttonOneRectTransform != (Object)null) { ResetButtonPos(buttonOneRectTransform); } try { while (gameObjectsToDestroy.Count > 0) { Object.Destroy((Object)(object)gameObjectsToDestroy[0]); gameObjectsToDestroy.RemoveAt(0); } } catch (Exception ex) { logger.LogWarning((object)("failed to do unload " + ex.Message)); logger.LogWarning((object)ex.StackTrace); } BulldozeButton = null; PaveActionButton = null; mainActionButton = null; countText = null; buttonOneRectTransform = null; CheckBoxImage = null; AlterVeinsCheckBoxImage = null; DestroyMachinesCheckBoxImage = null; ConfigIconImage = null; } public RectTransform CopyButton(RectTransform rectTransform, Vector2 positionDelta, out Text countComponent, Sprite newIcon, Action action) { //IL_0060: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Expected O, but got Unknown countComponent = null; if ((Object)(object)rectTransform == (Object)null || (Object)(object)newIcon == (Object)null || action == null) { return null; } RectTransform val = Object.Instantiate(rectTransform, ((Component)rectTransform).transform.parent, false); RectTransform component = ((Component)val).GetComponent(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); return null; } component.anchorMin = rectTransform.anchorMin; component.anchorMax = rectTransform.anchorMax; component.sizeDelta = rectTransform.sizeDelta; component.anchoredPosition = rectTransform.anchoredPosition + positionDelta; _bulldozeIcon = ((Component)component).transform.Find("icon"); if ((Object)(object)_bulldozeIcon != (Object)null) { gameObjectsToDestroy.Add(((Component)_bulldozeIcon).gameObject); _iconImage = ((Component)_bulldozeIcon).GetComponentInChildren(); if ((Object)(object)_iconImage != (Object)null) { _iconImage.sprite = newIcon; gameObjectsToDestroy.Add(((Component)_iconImage).gameObject); } } Transform val2 = ((Component)component).transform.Find("text"); if ((Object)(object)val2 != (Object)null) { buttonHotkeyTextComponent = ((Component)val2).GetComponentInChildren(); if ((Object)(object)buttonHotkeyTextComponent != (Object)null) { buttonHotkeyTextComponent.text = ""; } } mainActionButton = ((Component)component).GetComponentInChildren(); if ((Object)(object)mainActionButton == (Object)null || (Object)(object)mainActionButton.button == (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); return null; } mainActionButton.tips.tipTitle = "Bulldoze"; mainActionButton.tips.tipText = ConstructTipMessageDependentOnConfig(); mainActionButton.tips.offset = new Vector2(mainActionButton.tips.offset.x, mainActionButton.tips.offset.y + 100f); ((UnityEventBase)mainActionButton.button.onClick).RemoveAllListeners(); ((UnityEvent)mainActionButton.button.onClick).AddListener((UnityAction)delegate { action(1); }); CountTransform = ((Component)component).transform.Find("count"); if ((Object)(object)CountTransform != (Object)null) { countComponent = ((Component)CountTransform).GetComponentInChildren(); if ((Object)(object)countComponent != (Object)null) { countComponent.text = "0"; return val; } } return val; } public void Show(bool inittedThisTime = false) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: 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_00d4: 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_003e: 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_0065: Unknown result type (might be due to invalid IL or missing references) if (!IsUsable) { return; } if (GameMain.sandboxToolsEnabled && (Object)(object)buttonOneRectTransform != (Object)null) { if (!inittedThisTime) { buttonOneRectTransform.anchoredPosition = new Vector2((float)((double)buttonOneRectTransform.anchoredPosition.x - (double)buttonOneRectTransform.sizeDelta.x / 1.5), buttonOneRectTransform.anchoredPosition.y); } RepositionElements(); } else if ((Object)(object)buttonOneRectTransform != (Object)null && (Object)(object)BulldozeButton != (Object)null) { ResetButtonPos(buttonOneRectTransform); BulldozeButton.anchoredPosition = buttonOneRectTransform.anchoredPosition + Vector2.right * (5f + ((Component)buttonOneRectTransform).GetComponent().sizeDelta.x); RepositionElements(); } if ((Object)(object)BulldozeButton != (Object)null) { ((Component)BulldozeButton).gameObject.SetActive(true); } if ((Object)(object)PaveActionButton != (Object)null) { ((Component)PaveActionButton).gameObject.SetActive(true); } if ((Object)(object)CheckBoxImage != (Object)null) { ((Component)CheckBoxImage).gameObject.SetActive(true); } if ((Object)(object)AlterVeinsCheckBoxImage != (Object)null) { ((Component)AlterVeinsCheckBoxImage).gameObject.SetActive(true); } if ((Object)(object)DestroyMachinesCheckBoxImage != (Object)null) { ((Component)DestroyMachinesCheckBoxImage).gameObject.SetActive(true); } if ((Object)(object)ConfigIconImage != (Object)null) { ((Component)ConfigIconImage).gameObject.SetActive(true); } } private void RepositionElements() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)BulldozeButton == (Object)null || (Object)(object)buttonOneRectTransform == (Object)null) { return; } BulldozeButton.anchoredPosition = buttonOneRectTransform.anchoredPosition + Vector2.right * (5f + ((Component)buttonOneRectTransform).GetComponent().sizeDelta.x); if ((Object)(object)DrawEquatorCheck != (Object)null) { RectTransform component = DrawEquatorCheck.GetComponent(); if ((Object)(object)component != (Object)null) { component.anchoredPosition = new Vector2(GetCheckBoxXValue(), component.anchoredPosition.y); } } if ((Object)(object)AlterVeinsCheck != (Object)null) { RectTransform component2 = AlterVeinsCheck.GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.anchoredPosition = new Vector2(GetCheckBoxXValue(), -105f); } } if ((Object)(object)DestroyMachinesCheck != (Object)null) { RectTransform component3 = DestroyMachinesCheck.GetComponent(); if ((Object)(object)component3 != (Object)null) { component3.anchoredPosition = new Vector2(GetCheckBoxXValue(), -120f); } } if ((Object)(object)ConfigButton != (Object)null) { RectTransform component4 = ConfigButton.GetComponent(); if ((Object)(object)component4 != (Object)null) { component4.anchoredPosition = new Vector2(GetCheckBoxXValue() + 19f, -120f); } } } public void Hide() { if (IsUsable) { if (GameMain.sandboxToolsEnabled && (Object)(object)buttonOneRectTransform != (Object)null) { ResetButtonPos(buttonOneRectTransform); } if ((Object)(object)BulldozeButton != (Object)null) { ((Component)BulldozeButton).gameObject.SetActive(false); } if ((Object)(object)PaveActionButton != (Object)null) { ((Component)PaveActionButton).gameObject.SetActive(false); } if ((Object)(object)CheckBoxImage != (Object)null) { ((Component)CheckBoxImage).gameObject.SetActive(false); } if ((Object)(object)AlterVeinsCheckBoxImage != (Object)null) { ((Component)AlterVeinsCheckBoxImage).gameObject.SetActive(false); } if ((Object)(object)DestroyMachinesCheckBoxImage != (Object)null) { ((Component)DestroyMachinesCheckBoxImage).gameObject.SetActive(false); } if ((Object)(object)ConfigIconImage != (Object)null) { ((Component)ConfigIconImage).gameObject.SetActive(false); } } } public bool IsShowing() { if (!IsUsable || !Object.op_Implicit((Object)(object)((Component)BulldozeButton).gameObject)) { return false; } return ((Component)BulldozeButton).gameObject.activeSelf; } private void OnDrawEquatorCheckClick(PointerEventData data) { OnDrawEquatorCheckClickImpl(); } private void OnDrawEquatorCheckClickImpl(bool explicitDisable = false) { if (!IsUsable || (Object)(object)CheckBoxImage == (Object)null) { return; } if (explicitDisable) { PluginConfig.addGuideLines.Value = false; } else { PluginConfig.addGuideLines.Value = !PluginConfig.addGuideLines.Value; } CheckBoxImage.sprite = (PluginConfig.addGuideLines.Value ? spriteChecked : spriteUnChecked); _drawEquatorField = PluginConfig.addGuideLines.Value; if (PluginConfig.addGuideLines.Value) { if (PluginConfig.alterVeinState.Value) { OnAlterVeinCheckClickImpl(explicitDisable: true); } if (PluginConfig.destroyFactoryAssemblers.Value) { OnDestroyMachinesCheckClickImpl(explicitDisable: true); } } } private void OnAlterVeinCheckClick(PointerEventData obj) { OnAlterVeinCheckClickImpl(); } private void OnAlterVeinCheckClickImpl(bool explicitDisable = false) { if (!IsUsable || (Object)(object)AlterVeinsCheckBoxImage == (Object)null) { return; } if (explicitDisable) { PluginConfig.alterVeinState.Value = false; } else { PluginConfig.alterVeinState.Value = !PluginConfig.alterVeinState.Value; } AlterVeinsCheckBoxImage.sprite = (PluginConfig.alterVeinState.Value ? spriteChecked : spriteUnChecked); _alterVeinsField = PluginConfig.alterVeinState.Value; if (PluginConfig.alterVeinState.Value) { if (PluginConfig.addGuideLines.Value) { OnDrawEquatorCheckClickImpl(explicitDisable: true); } if (PluginConfig.destroyFactoryAssemblers.Value) { OnDestroyMachinesCheckClickImpl(explicitDisable: true); } } } private void OnDestroyMachinesCheckClick(PointerEventData obj) { OnDestroyMachinesCheckClickImpl(); } private void OnDestroyMachinesCheckClickImpl(bool explicitDisable = false) { if (!IsUsable || (Object)(object)DestroyMachinesCheckBoxImage == (Object)null) { return; } if (explicitDisable) { PluginConfig.destroyFactoryAssemblers.Value = false; } else { PluginConfig.destroyFactoryAssemblers.Value = !PluginConfig.destroyFactoryAssemblers.Value; } DestroyMachinesCheckBoxImage.sprite = (PluginConfig.destroyFactoryAssemblers.Value ? spriteChecked : spriteUnChecked); _destroyFactoryMachines = PluginConfig.destroyFactoryAssemblers.Value; if (PluginConfig.destroyFactoryAssemblers.Value) { if (PluginConfig.addGuideLines.Value) { OnDrawEquatorCheckClickImpl(explicitDisable: true); } if (PluginConfig.alterVeinState.Value) { OnAlterVeinCheckClickImpl(explicitDisable: true); } } } } public class Helper { public static Sprite GetSprite(string spriteName) { //IL_0020: 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) Texture2D iconTexture = BulldozeIcon.GetIconTexture(spriteName); return Sprite.Create(iconTexture, new Rect(0f, 0f, (float)((Texture)iconTexture).width, (float)((Texture)iconTexture).height), new Vector2((float)((Texture)iconTexture).width, (float)((Texture)iconTexture).height), 1000f); } } public static class RaptorFastDelete { public static void Execute() { if (GameMain.mainPlayer != null) { FastDeleteEntities(); } } private static void FastDeleteEntities() { //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Expected O, but got Unknown Player mainPlayer = GameMain.mainPlayer; if (mainPlayer.factory == null) { return; } PlanetFactory factory = mainPlayer.factory; FactorySystem factorySystem = factory.factorySystem; CargoTraffic cargoTraffic = factory.cargoTraffic; PowerSystem powerSystem = factory.powerSystem; BuildTool[] tools = mainPlayer.controller.actionBuild.tools; for (int i = 0; i < tools.Length; i++) { tools[i]._Close(); } mainPlayer.controller.actionInspect.InspectNothing(); Dictionary takeBackCount = new Dictionary(); Dictionary takeBackInc = new Dictionary(); Dictionary> powerConRemoval = new Dictionary>(); for (int j = 0; j < powerSystem.netCursor; j++) { powerConRemoval[j] = new HashSet(); } ItemProto[] dataArray = ((ProtoSet)(object)LDB.items).dataArray; foreach (ItemProto val in dataArray) { takeBackCount[((Proto)val).ID] = 0; takeBackInc[((Proto)val).ID] = 0; } HighStopwatch val2 = new HighStopwatch(); val2.Begin(); DeleteBelts(); DeleteInserters(); foreach (KeyValuePair item in takeBackCount) { mainPlayer.TryAddItemToPackage(item.Key, item.Value, takeBackInc[item.Key], true, 0, false); } Log.Debug($"Took {val2.duration} to fast delete belts"); void DeleteBelts() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) BeltComponent[] beltPool = cargoTraffic.beltPool; TakeBackItemsOptimized(); for (int k = 1; k < cargoTraffic.beltCursor; k++) { ref BeltComponent reference = ref beltPool[k]; int entityId = reference.entityId; if (entityId != 0) { EntityData val3 = factory.entityPool[reference.entityId]; takeBackCount[val3.protoId]++; if (reference.id != 0) { cargoTraffic.RemoveBeltRenderer(k); cargoTraffic.RemoveCargoPath(reference.segPathId); ((BeltComponent)(ref reference)).SetEmpty(); cargoTraffic.RemoveBeltComponent(k); } factory.RemoveEntityWithComponents(entityId, false); } } } void DeleteInserters() { //IL_005e: 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_006b: Unknown result type (might be due to invalid IL or missing references) InserterComponent[] inserterPool = factorySystem.inserterPool; EntityData[] entityPool = factory.entityPool; PowerConsumerComponent[] consumerPool = powerSystem.consumerPool; for (int k = 1; k < factorySystem.inserterCursor; k++) { ref InserterComponent reference = ref inserterPool[k]; int entityId = reference.entityId; if (entityId != 0) { if (reference.id == k) { EntityData val3 = factory.entityPool[entityId]; takeBackCount[val3.protoId]++; TakeBackItemsOptimized2(ref reference); } RemoveConsumerComponent(entityPool[entityId].powerConId); factory.RemoveEntityWithComponents(entityId, false); } } for (int l = 0; l < powerSystem.netCursor; l++) { PowerNetwork val4 = powerSystem.netPool[l]; if (val4 != null && val4.id == l) { HashSet consumersToRemove = powerConRemoval[val4.id]; foreach (Node node in val4.nodes) { node.consumers.RemoveAll((int x) => consumersToRemove.Contains(x)); } val4.consumers.RemoveAll((int x) => consumersToRemove.Contains(x)); } } if ((Object)(object)factory.planet.factoryModel != (Object)null) { factory.planet.factoryModel.RefreshPowerConsumers(); } void RemoveConsumerComponent(int id) { ref PowerConsumerComponent reference2 = ref consumerPool[id]; if (reference2.id != 0) { powerConRemoval[reference2.networkId].Add(id); powerSystem.RemoveConsumerComponent(id); } } } void TakeBackItemsOptimized() { CargoContainer container = cargoTraffic.container; Cargo[] cargoPool = container.cargoPool; int cursor = container.cursor; for (int k = 0; k < cursor; k++) { ref Cargo reference = ref cargoPool[k]; if (reference.item != 0) { if (!takeBackCount.ContainsKey(reference.item)) { Log.Warn($"found cargo item not in LDB.items.dataArray: {reference.item}"); takeBackCount[reference.item] = 0; takeBackInc[reference.item] = 0; } takeBackCount[reference.item] += reference.stack; takeBackInc[reference.item] += reference.inc; container.RemoveCargo(k); } } } void TakeBackItemsOptimized2(ref InserterComponent inserter) { if (inserter.itemId > 0 && inserter.stackCount > 0) { takeBackCount[inserter.itemId] += inserter.itemCount; takeBackInc[inserter.itemId] += inserter.itemInc; } } } } public class ReformIndexInfoProvider { private const int LatitudesPerPass = 10; private readonly Dictionary _llLookup = new Dictionary(); private readonly LatLon[] _llModLookup = new LatLon[GameMain.localPlanet.data.modData.Length * 2]; private readonly HashSet _tropicsLatitudes = new HashSet(); private readonly LatLon[] _equatorLatitudes = new LatLon[2] { LatLon.Empty, LatLon.Empty }; private readonly HashSet _meridians = new HashSet(); public PlatformSystem platformSystem; private bool _lookupsCreated; private float _latLookupWorkItemIndex = -89.9f; private int _initUpdateCounter; private int _planetId; private int prevLength = -1; public int PlanetId => _planetId; public bool Initted => _lookupsCreated; public ReformIndexInfoProvider(PlatformSystem platformSystem) { this.platformSystem = platformSystem; _planetId = platformSystem.planet.id; } private void SetInitValues(PlatformSystem newPlatformSystem, int planetId) { _llLookup.Clear(); Array.Clear(_llModLookup, 0, _llLookup.Count); _tropicsLatitudes.Clear(); _equatorLatitudes[0] = LatLon.Empty; _equatorLatitudes[1] = LatLon.Empty; _meridians.Clear(); _lookupsCreated = false; _planetId = planetId; platformSystem = newPlatformSystem; _latLookupWorkItemIndex = -89.9f; _initUpdateCounter = 0; } public void PlanetChanged(PlanetData planetData) { if (planetData == null) { Log.Debug("planet changed, initting"); SetInitValues(null, -1); } else { Log.Debug("Index provider detected planet changed"); SetInitValues(planetData.factory?.platformSystem, planetData.id); } } public LatLon GetForIndex(int index) { if (!_lookupsCreated) { return LatLon.Empty; } _llLookup.TryGetValue(index, out var value); return value; } public HashSet GetTropicsLatitudes() { return _tropicsLatitudes; } public (LatLon above, LatLon below) GetEquatorLatitudes() { return (above: _equatorLatitudes[0], below: _equatorLatitudes[1]); } public HashSet GetMeridianPoints() { return _meridians; } public LatLon GetForModIndex(int index) { if (!_lookupsCreated) { return LatLon.Empty; } if (_llModLookup[index].IsEmpty()) { return LatLon.Empty; } return _llModLookup[index]; } public void DoInitWork(PlanetData planetData) { //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_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) if (planetData == null) { return; } if (planetData.id != _planetId) { PlanetChanged(planetData); } if (_lookupsCreated) { return; } if (platformSystem == null) { Log.Warn($"plat system null for planet {planetData.id}"); return; } _initUpdateCounter++; if (_initUpdateCounter > 2000) { return; } float num = Math.Min(_latLookupWorkItemIndex + 10f, 90f); PlanetRawData data = platformSystem.planet.data; DateTime now = DateTime.Now; int maxRuntimeMS = GetMaxRuntimeMS(); int precisionMultiple = ((planetData.realRadius < 250f) ? 10 : 10); int latitudeCount = platformSystem.latitudeCount; float num2 = 180f / (float)latitudeCount; int num3 = -5; while (_latLookupWorkItemIndex <= num) { var (num4, num5) = GetReformIndexesForLatitude(_latLookupWorkItemIndex); if (num4 != num3) { num3 = num4; int num6 = num5 - num4; if (num6 != prevLength) { _tropicsLatitudes.Add(LatLon.FromCoords(_latLookupWorkItemIndex, 0.0, precisionMultiple)); } LatLon latLon = LatLon.FromCoords(_latLookupWorkItemIndex, 0.0, precisionMultiple); if (_latLookupWorkItemIndex <= 0f) { if (_equatorLatitudes[1].IsEmpty()) { _equatorLatitudes[1] = latLon; } else if (_equatorLatitudes[1].Lat < latLon.Lat) { _equatorLatitudes[1] = latLon; } } if (_latLookupWorkItemIndex >= 0f) { if (_equatorLatitudes[0].IsEmpty()) { _equatorLatitudes[0] = latLon; } else if (_equatorLatitudes[0].Lat > latLon.Lat) { _equatorLatitudes[0] = latLon; } } prevLength = num6; if (num4 < num5) { int num7 = num5 - num4; int num8 = (num5 + num4) / 2; int num9 = num7 / 2; float num10 = 180f / (float)num9; int num11 = num7 / 4; for (int i = num4; i < num5; i++) { if (i > num8) { float num12 = num10 * (float)(i - num8); _llLookup[i] = LatLon.FromCoords(_latLookupWorkItemIndex, 0f - num12, precisionMultiple); Vector3 val = GeoUtil.LatLonToPosition(_latLookupWorkItemIndex, 0f - num12, platformSystem.planet.realRadius); int num13 = data.QueryIndex(val); _llModLookup[num13] = _llLookup[i]; } else { float num14 = num10 * (float)(i - num4); _llLookup[i] = LatLon.FromCoords(_latLookupWorkItemIndex, num14, precisionMultiple); Vector3 val2 = GeoUtil.LatLonToPosition(_latLookupWorkItemIndex, num14, platformSystem.planet.realRadius); int num15 = data.QueryIndex(val2); _llModLookup[num15] = _llLookup[i]; } if ((i - num4) % num11 == 0 || i + 1 == num5) { _meridians.Add(_llLookup[i]); } else if ((i - num4 + 1) % num11 == 0) { _meridians.Add(_llLookup[i]); } } } if ((DateTime.Now - now).TotalMilliseconds > (double)maxRuntimeMS) { break; } } _latLookupWorkItemIndex += num2; } if (_latLookupWorkItemIndex > 89f) { _lookupsCreated = true; } if (_lookupsCreated) { int maxReformCount = platformSystem.maxReformCount; int dataLength = data.dataLength; Log.Debug($"Completed position computations for {_llLookup.Count}/{maxReformCount}, {_llModLookup.Length}/{dataLength} indices. Updates required: {_initUpdateCounter}. Found {_tropicsLatitudes.Count} tropics. {_meridians.Count} meridian points"); } } private static int GetMaxRuntimeMS() { if (!PluginConfig.NeedReformIndexProvider()) { return Math.Min(10, PluginConfig.maxInitMsPerFrame.Value); } return PluginConfig.maxInitMsPerFrame.Value; } public int InitPercentComplete() { return (int)((_latLookupWorkItemIndex + 90f) / 180f * 100f); } public (int offsetStartIndex, int offsetEndIndex) GetReformIndexesForLatitude(float latDegrees) { float num = Mathf.Round((float)((double)((float)Math.PI / 180f * latDegrees) / 6.2831854820251465) * (float)platformSystem.segment * 10f); float num2 = Mathf.Abs(num); float num3 = (((double)num >= 0.0) ? num2 : (0f - num2)) / 10f; int num4 = (((double)num3 > 0.0) ? Mathf.CeilToInt(num3 * 5f) : Mathf.FloorToInt(num3 * 5f)); int num5 = platformSystem.latitudeCount / 2; int num6 = ((num4 > 0) ? (num4 - 1) : (num5 - num4 - 1)); int num7 = platformSystem.reformOffsets[num6]; int num8 = PlatformSystem.DetermineLongitudeSegmentCount(Mathf.FloorToInt(Mathf.Abs(num3)), platformSystem.segment); int item = num7 + num8 * 5; return (offsetStartIndex: num7, offsetEndIndex: item); } } public class RegionColorConfig { public int minLatitude; public int maxLatitude; public int minLongitude; public int maxLongitude; public bool mirror; public int colorIndex; public bool ContainsPosition(float lat, float lng) { bool flag = minLatitude == maxLatitude; bool flag2 = minLongitude == maxLongitude; if (flag && flag2) { return true; } if (!flag && flag2) { if ((float)minLatitude <= lat && (float)maxLatitude >= lat) { return true; } if (mirror) { if ((float)(-minLatitude) >= lat) { return (float)(-maxLatitude) <= lat; } return false; } return false; } if (flag && !flag2) { if ((float)minLongitude <= lng && (float)maxLongitude >= lng) { return true; } return false; } if ((float)minLatitude <= lat && (float)maxLatitude >= lat && (float)minLongitude <= lng && (float)maxLongitude >= lng) { return true; } if (!mirror) { return false; } if ((float)(-minLatitude) >= lat && (float)(-maxLatitude) <= lat && (float)minLongitude <= lng) { return (float)maxLongitude >= lng; } return false; } } public class RegionalColors { private static RegionalColors _instance; private List _regionColorConfigs; public static RegionalColors Instance { get { if (_instance == null) { _instance = DeserializeFromConfigProperty(); } return _instance; } private set { _instance = value; } } public int Count => _regionColorConfigs.Count; public RegionalColors() { _regionColorConfigs = new List(); } public void Save() { if (_regionColorConfigs.Count == 0) { PluginConfig.regionColors.Value = ""; return; } StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < _regionColorConfigs.Count; i++) { stringBuilder.Append(JsonUtility.ToJson((object)_regionColorConfigs[i])); if (i + 1 < _regionColorConfigs.Count) { stringBuilder.Append("$"); } } Log.Debug($"Added {_regionColorConfigs.Count} values to plugin config"); PluginConfig.regionColors.Value = stringBuilder.ToString(); } private static RegionalColors DeserializeFromConfigProperty() { string value = PluginConfig.regionColors.Value; if (value.Trim().Length == 0) { RegionColorConfig regionColorConfig = new RegionColorConfig(); regionColorConfig.colorIndex = 2; regionColorConfig.minLatitude = -89; regionColorConfig.maxLatitude = -70; regionColorConfig.minLongitude = 0; regionColorConfig.maxLongitude = 0; return new RegionalColors { _regionColorConfigs = { regionColorConfig } }; } RegionalColors regionalColors = new RegionalColors(); string[] array = value.Split(new char[1] { '$' }); Log.Debug($"Loading region color config from json {array.Length} {value}"); string[] array2 = array; foreach (string text in array2) { try { RegionColorConfig item = JsonUtility.FromJson(text.Trim()); regionalColors._regionColorConfigs.Add(item); } catch (Exception ex) { Log.Warn("Failed to parse " + text + " into color config " + ex.Message); } } return regionalColors; } public RegionColorConfig GetForPosition(float lat, float lng) { foreach (RegionColorConfig regionColorConfig in _regionColorConfigs) { if (regionColorConfig.ContainsPosition(lat, lng)) { return regionColorConfig; } } return null; } public List GetRegions() { return _regionColorConfigs; } public void Remove(RegionColorConfig regionalColor) { _regionColorConfigs.Remove(regionalColor); } public void Create() { RegionColorConfig item = new RegionColorConfig(); _regionColorConfigs.Add(item); } public static int RegionCountDefined() { if (Instance == null) { return 0; } return Instance._regionColorConfigs.Count; } } public class RegionColorWindow { [CompilerGenerated] private static class <>O { public static WindowFunction <0>__DrawRegionColorSection; } public static bool visible; private static Rect _windowRect = new Rect((float)(Screen.width / 3), 100f, 500f, 820f); private static int _leftColumnWidth; public static bool NeedReinit; private static Texture2D _tooltipBg; private static RegionalColors _regionalColors = RegionalColors.Instance; private static Pager _pager; private static bool lastOverLapCheckFailed; private static bool _overlapCheckDirty; private static bool _windowStateDirty; private static DateTime _lastOverlapCheck = DateTime.Now; public static void OnOpen() { visible = true; } public static void OnClose() { visible = false; _windowStateDirty = true; } public static void Toggle() { if (visible) { OnClose(); } else { OnOpen(); } } public static void OnGUI() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_0040: Expected O, but got Unknown if (Input.GetKeyDown((KeyCode)27)) { visible = false; _windowStateDirty = true; return; } Init(); Rect windowRect = _windowRect; object obj = <>O.<0>__DrawRegionColorSection; if (obj == null) { WindowFunction val = DrawRegionColorSection; <>O.<0>__DrawRegionColorSection = val; obj = (object)val; } _windowRect = GUILayout.Window(1297895055, windowRect, (WindowFunction)obj, "Region Colors", Array.Empty()); } private static void Init() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown if (!((Object)(object)_tooltipBg == (Object)null) || NeedReinit) { Texture2D val = new Texture2D(1, 1, (TextureFormat)3, false); val.SetPixel(0, 0, Color.white); val.Apply(); _tooltipBg = val; InitWindowRect(); NeedReinit = false; } } public static void DrawRegionColorSection(int id) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Expected O, but got Unknown //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0160: 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_016f: Expected O, but got Unknown //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Expected O, but got Unknown //IL_01c2: Unknown result type (might be due to invalid IL or missing references) if (_pager == null) { _pager = new Pager(RegionalColors.Instance.GetRegions(), 3); } else if (_windowStateDirty) { _windowStateDirty = false; _pager = new Pager(RegionalColors.Instance.GetRegions(), 3); } GUILayout.BeginArea(new Rect(((Rect)(ref _windowRect)).width - 25f, 0f, 25f, 30f)); if (GUILayout.Button("X", Array.Empty())) { OnClose(); return; } GUILayout.EndArea(); GUILayout.BeginVertical(GUI.skin.box, Array.Empty()); DrawCenteredLabel(new GUIContent("Regions", "Set min equal to max to include all longitude values")); DrawPreviousButton(); foreach (RegionColorConfig item in _pager.GetPage()) { DrawColorConfig(item); GUILayout.Space(25f); } DrawNextButton(); DrawAddButton(); GUILayout.EndVertical(); CheckOverlap(); if (lastOverLapCheckFailed) { GUI.tooltip += "\r\nSome regions are overlapping. The first region in list will determine color for overlapping points"; } if (GUI.tooltip != null) { GUI.skin = null; GUIStyle val = new GUIStyle { normal = new GUIStyleState { textColor = Color.white }, wordWrap = true, alignment = (TextAnchor)4, stretchHeight = true, stretchWidth = true }; float num = val.CalcHeight(new GUIContent(GUI.tooltip), ((Rect)(ref _windowRect)).width) + 10f; int num2 = (int)((double)((Rect)(ref _windowRect)).height - (double)num * 1.25); GUI.Box(new Rect(0f, (float)num2, ((Rect)(ref _windowRect)).width, num * 1.25f), GUI.tooltip, val); } GUI.DragWindow(); } private static void DrawPreviousButton() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button(new GUIContent("Previous", "Load previous page"), Array.Empty()) && !_pager.IsFirst()) { _pager.Previous(); } GUILayout.EndHorizontal(); } private static void DrawNextButton() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button(new GUIContent("Next", "Load next page"), Array.Empty()) && _pager.HasNext()) { _pager.Next(); } GUILayout.EndHorizontal(); } private static void CheckOverlap() { if ((!_overlapCheckDirty || !((DateTime.Now - _lastOverlapCheck).TotalSeconds > 2.0)) && !((DateTime.Now - _lastOverlapCheck).TotalSeconds > 15.0)) { return; } _overlapCheckDirty = false; lastOverLapCheckFailed = false; for (int i = -90; i < 90; i++) { for (int j = -180; j < 180; j++) { int num = 0; List list = new List(); List regions = _regionalColors.GetRegions(); for (int k = 0; k < regions.Count; k++) { if (regions[k].ContainsPosition(i, j)) { num++; list.Add(k); } } if (num > 1) { lastOverLapCheckFailed = true; } } } _lastOverlapCheck = DateTime.Now; } private static void DrawAddButton() { if (GUILayout.Button("Add New Region", Array.Empty())) { _regionalColors.Create(); _regionalColors.Save(); _windowStateDirty = true; } } private static void DrawColorConfig(RegionColorConfig regionalColor) { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown GUILayout.BeginVertical(Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); DrawSetting("Min Latitude", -90, 90, ref regionalColor.minLatitude); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); DrawSetting("Max Latitude", -90, 90, ref regionalColor.maxLatitude, regionalColor.minLatitude); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); DrawSetting("Min Longitude", -180, 180, ref regionalColor.minLongitude); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); DrawSetting("Max Longitude", -180, 180, ref regionalColor.maxLongitude, regionalColor.minLongitude); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(new GUIContent("Current Color"), (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width((float)_leftColumnWidth), GUILayout.MaxWidth((float)_leftColumnWidth) }); GUILayout.FlexibleSpace(); DrawCustomColor(regionalColor.colorIndex, ref regionalColor.colorIndex); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); DrawMirrorToggle(regionalColor); DrawDeleteButton(regionalColor); GUILayout.EndHorizontal(); GUILayout.EndVertical(); } private static void DrawMirrorToggle(RegionColorConfig regionalColor) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown int num = Math.Min(regionalColor.minLatitude, regionalColor.maxLatitude); int num2 = Math.Max(regionalColor.minLatitude, regionalColor.maxLatitude); string text = $"Enable latitude mirroring. So the above would also include from [{-num2} - {-num}]"; if (num > 0) { num = Math.Min(-regionalColor.minLatitude, -regionalColor.maxLatitude); num2 = Math.Max(-regionalColor.minLatitude, -regionalColor.maxLatitude); text = $"Enable latitude mirroring. So the above would also include from [{num2} - {num}]"; } bool flag = GUILayout.Toggle(regionalColor.mirror, new GUIContent("Mirror", text), Array.Empty()); if (flag != regionalColor.mirror) { regionalColor.mirror = flag; _regionalColors.Save(); _overlapCheckDirty = true; } } private static void DrawDeleteButton(RegionColorConfig regionalColor) { if (GUILayout.Button("Delete Color", Array.Empty())) { _regionalColors.Remove(regionalColor); _regionalColors.Save(); _windowStateDirty = true; } } private static void DrawCustomColor(int regionalColorColorIndex, ref int currentVal) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginHorizontal(Array.Empty()); float num = (float)Convert.ToDouble(regionalColorColorIndex, CultureInfo.InvariantCulture); float num2 = (float)Convert.ToDouble(0, CultureInfo.InvariantCulture); float num3 = (float)Convert.ToDouble(31, CultureInfo.InvariantCulture); float num4 = GUILayout.HorizontalSlider(num, num2, num3, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MinWidth(200f) }); int num5 = regionalColorColorIndex; if (Math.Abs(num4 - num) > Mathf.Abs(num3 - num2) / 1000f) { num5 = (int)num4; } string text = num5.ToString(); string text2 = GUILayout.TextField(text, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); GUILayout.Label((Texture)(object)PluginConfigWindow.GetTextureForColor(PluginConfigWindow.GetColorByIndex(num5)), Array.Empty()); GUILayout.EndHorizontal(); if (text2 != text) { try { num5 = (int)Mathf.Clamp((float)Convert.ToDouble(text2, CultureInfo.InvariantCulture), num2, num3); } catch (FormatException) { } } if (num5 != currentVal) { currentVal = num5; _regionalColors.Save(); } } private static void DrawSetting(string title, int minVal, int maxVal, ref int current, int actualMin = -1) { GUILayout.Label(title, Array.Empty()); float num = (float)Convert.ToDouble(current, CultureInfo.InvariantCulture); float num2 = (float)Convert.ToDouble(minVal, CultureInfo.InvariantCulture); float num3 = (float)Convert.ToDouble(maxVal, CultureInfo.InvariantCulture); float num4 = GUILayout.HorizontalSlider(num, num2, num3, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MinWidth(200f) }); int num5 = current; if (Math.Abs(num4 - num) > Mathf.Abs(num3 - num2) / 1000f) { num5 = (int)num4; } string s = GUILayout.TextField(num5.ToString(CultureInfo.CurrentCulture), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }); try { int num6 = int.Parse(s, NumberStyles.Any); if (num6 >= minVal && num6 <= maxVal) { num5 = num6; } } catch (Exception ex) { Log.Debug("invalid text entered " + ex.Message); } if (actualMin > num5 && actualMin != -1) { num5 = actualMin; } if (num5 != current) { current = num5; RegionalColors.Instance.Save(); _overlapCheckDirty = true; } } private static void InitWindowRect() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Min(Screen.width, 650); int num2 = ((Screen.height < 560) ? Screen.height : 560); int num3 = Mathf.RoundToInt((float)(Screen.width - num) / 2f); int num4 = Mathf.RoundToInt((float)(Screen.height - num2) / 2f); _windowRect = new Rect((float)num3, (float)num4, (float)num, (float)num2); _leftColumnWidth = Mathf.RoundToInt(((Rect)(ref _windowRect)).width / 2.5f); } public static void DrawCenteredLabel(GUIContent text, params GUILayoutOption[] options) { GUILayout.BeginHorizontal(options); GUILayout.FlexibleSpace(); GUILayout.Label(text, Array.Empty()); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); } } public class StorageSystemManager { private readonly PlanetFactory _factory; private readonly Player _player; private StorageSystemManager(PlanetFactory factory, Player player) { _factory = factory; _player = player; } private static StorageSystemManager GetInstance() { return new StorageSystemManager(GameMain.mainPlayer.factory, GameMain.mainPlayer); } private int CountLocalStationItems(int itemId) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) int num = 0; for (int i = 1; i < _factory.transport.stationCursor; i++) { StationComponent val = _factory.transport.stationPool[i]; if (val == null || val.id != i) { continue; } StationStore[] storage = val.storage; foreach (StationStore val2 in storage) { if (val2.itemId == itemId && val2.itemId == itemId) { num += val2.count; } } } return num; } private int CountLocalStorageItems(int itemId) { int num = 0; if (_factory.factoryStorage?.storagePool == null) { return num; } for (int i = 0; i < _factory.factoryStorage.storageCursor; i++) { StorageComponent val = _factory.factoryStorage.storagePool[i]; if (val != null && val.id > 0) { num += val.GetItemCount(itemId); } } return num; } public static (int itemsRemoved, bool successful) RemoveItems(int itemId, int count) { int num = GetInstance().DoRemove(itemId, count); return (itemsRemoved: num, successful: num >= count); } private int DoRemove(int itemId, int count) { int num = 0; (int, bool) tuple = RemoveFromPlayer(itemId, count); int num2; (num2, _) = tuple; if (tuple.Item2) { return num2; } num += num2; (int, bool successful) tuple3 = RemoveFromStorage(itemId, count - num); (num2, _) = tuple3; if (tuple3.successful) { return count; } num += num2; num2 = RemoveFromStations(itemId, count - num).removed; return num + num2; } private (int, bool successful) RemoveFromStorage(int itemId, int count) { int num = 0; int num5 = default(int); for (int i = 0; i < _factory.factoryStorage.storageCursor; i++) { StorageComponent val = _factory.factoryStorage.storagePool[i]; if (val != null && val.id == i) { int num2 = count - num; int num3 = itemId; int num4 = num2; val.TakeTailItems(ref num3, ref num4, ref num5, false); num += num4; if (num >= count) { return (num, successful: true); } } } return (num, successful: num >= count); } private (int removed, bool successful) RemoveFromStations(int itemId, int count) { int num = 0; int num4 = default(int); for (int i = 0; i < _factory.transport.stationCursor; i++) { StationComponent val = _factory.transport.stationPool[i]; if (val == null || val.id != i) { continue; } int num2 = itemId; int num3 = count - num; val.TakeItem(ref num2, ref num3, ref num4); if (num3 > 0) { num += num3; if (num >= count) { return (removed: num, successful: true); } } } return (removed: num, successful: num >= count); } private (int, bool) RemoveFromPlayer(int itemId, int count) { int num = count; int num2 = itemId; int num3 = default(int); GameMain.mainPlayer.package.TakeTailItems(ref num2, ref num, ref num3, false); if (num != count) { return (num, false); } return (num, true); } public static (string message, bool hasEnoughCapacity, int remainingToRemove) BuildRemovalMessage(int itemId, int count) { (string, int) tuple = GetInstance().DoBuildRemovalMessage(itemId, count); return (message: tuple.Item1.Trim(), hasEnoughCapacity: Math.Max(0, tuple.Item2) <= 0, remainingToRemove: tuple.Item2); } private (string, int) DoBuildRemovalMessage(int itemId, int count) { Player player = _player; if (((player != null) ? player.package : null) == null) { Log.logger.LogWarning((object)"player not set"); return ("Failure while counting items", count); } int itemCount = _player.package.GetItemCount(itemId); string itemName = GetItemName(itemId); if (itemCount >= count) { return ($"{count} of {itemName} will be removed from your inventory (leaving {itemCount - count})", 0); } string text = ""; int num = count; if (itemCount > 0) { text += $"{itemCount} of {itemName} will be removed from your inventory ({count - itemCount} needed after). "; num -= itemCount; } int num2 = 0; try { num2 = CountLocalStorageItems(itemId); } catch (Exception ex) { Log.logger.LogWarning((object)("failure while trying to count items from local storage " + ex.Message)); Log.logger.LogWarning((object)ex.StackTrace); } if (num2 > num) { text += $"\n{num} of {itemName} will be removed from storage ({num2} total). "; num -= num2; return (text, num); } if (num2 > 0) { text += $"\nAll {num2} of {itemName} will be removed from storage."; num -= num2; } if (num <= 0) { return (text, num); } int num3 = 0; try { num3 = CountLocalStationItems(itemId); } catch (Exception ex2) { Log.logger.LogWarning((object)("failure while trying to count items from local logistics " + ex2.Message)); Log.logger.LogWarning((object)ex2.StackTrace); } if (num3 > num) { text += $"\n{num} of {itemName} will be removed from local logistics stations ({num3} total). "; num -= num3; return (text, num); } if (num3 > 0) { text += $"\nAll {num3} of {itemName} will be removed from local logistics stations."; num -= num3; } return (text, num); } private static string GetItemName(int itemId) { return Localization.Translate(((Proto)((ProtoSet)(object)LDB.items).Select(itemId)).Name); } } public static class Utils { public static bool IsOtherAssemblyLoaded(string otherAssemblyStringMatcher) { if (AppDomain.CurrentDomain.GetAssemblies().ToList().FindAll((Assembly ass) => !string.IsNullOrEmpty(ass.FullName) && ass.FullName.ToLower().Contains(otherAssemblyStringMatcher.ToLower())) .ToList() .Count == 0) { Log.Debug("No '" + otherAssemblyStringMatcher + "' found"); return false; } return true; } } public class WreckingBallWorkItem { public int ItemId; public ItemDestructionPhase Phase; } public enum ItemDestructionPhase { Inserters, Belts, Assemblers, Stations, Other, Done } public class WreckingBall { private static WreckingBall _instance; private readonly Stopwatch _clearStopWatch = new Stopwatch(); private readonly PlanetFactory _factory; private readonly Player _player; private readonly Queue _wreckingBallWork = new Queue(); private ItemDestructionPhase _previousPhase = ItemDestructionPhase.Done; private int _itemsDestroyed; private long _msTakenTotal; private int _updatesRun; private bool _running; private WreckingBall(PlanetFactory factory, Player player) { _factory = factory; _player = player; } public static void Init(PlanetFactory factory, Player player) { Stop(); _instance = new WreckingBall(factory, player); _instance.Start(); } public static int RemainingTaskCount() { if (_instance != null) { return _instance._wreckingBallWork.Count; } return 0; } public static void DoWorkItems(PlanetFactory factory) { if (_instance != null) { if (_instance._factory != factory) { Log.logger.LogWarning((object)"Factory has changed since task start. Halting"); Stop(); } else { _instance.Update(); } } } public static bool IsRunning() { if (_instance != null) { return _instance._running; } return false; } public static void Stop() { _instance?.LogRateMessage(); _instance?._wreckingBallWork.Clear(); _instance = null; } private void Update() { if (_wreckingBallWork.Count > 0) { WreckingBallWorkItem wreckingBallWorkItem = null; try { DateTime now = DateTime.Now; int num = 0; while (_wreckingBallWork.Count > 0) { wreckingBallWorkItem = _wreckingBallWork.Dequeue(); if (wreckingBallWorkItem.Phase != _previousPhase) { Log.LogAndPopupMessage($"Starting phase {wreckingBallWorkItem.Phase} {wreckingBallWorkItem.ItemId}"); Log.logger.LogDebug((object)("next phase started " + Enum.GetName(typeof(ItemDestructionPhase), wreckingBallWorkItem.Phase))); _previousPhase = wreckingBallWorkItem.Phase; } RemoveBuild(wreckingBallWorkItem.ItemId); num++; if ((DateTime.Now - now).TotalMilliseconds > (double)PluginConfig.factoryTeardownRunTimePerFrame.Value) { break; } } _itemsDestroyed += num; _msTakenTotal += (long)(DateTime.Now - now).TotalMilliseconds; _updatesRun++; } catch (Exception ex) { Log.Warn("got exception while removing component. Re-adding task to front of queue " + ex.Message); lock (_wreckingBallWork) { _wreckingBallWork.Enqueue(wreckingBallWorkItem); } } if (Time.frameCount % 60 * 10 * 10 == 0) { LogRateMessage(); } } if (_running && _wreckingBallWork.Count < 1) { _clearStopWatch.Stop(); long elapsedMilliseconds = _clearStopWatch.ElapsedMilliseconds; string arg = (PluginConfig.useActionBuildTearDown.Value ? "actionBuild.DoDismantleObject mode" : "RemoveEntityWithComponents mode"); Log.logger.LogInfo((object)$"wreckingBall {elapsedMilliseconds} ms to complete in {arg}, {_updatesRun} frames"); Log.LogAndPopupMessage("Done destroying factory"); LogRateMessage(); _running = false; } } private void LogRateMessage() { if (_updatesRun != 0 && _msTakenTotal != 0L && _clearStopWatch.ElapsedMilliseconds >= 1) { int num = _itemsDestroyed / _updatesRun; long num2 = _msTakenTotal / _updatesRun; double num3 = (double)(1000 * _itemsDestroyed) / (double)_msTakenTotal; long num4 = 1000 * _itemsDestroyed / _clearStopWatch.ElapsedMilliseconds; Log.logger.LogInfo((object)($"(perFrameValue={PluginConfig.factoryTeardownRunTimePerFrame.Value}) Destroyed: {_itemsDestroyed} in {_clearStopWatch.ElapsedMilliseconds / 1000} seconds over {_updatesRun} updates. " + $"Average destroyed per update {num}. Average time per update (aka lag added) {num2}. \r\n" + $"Local rate of destruction: {num3} entities / second\r\n" + $"Absolute rate of destruction: {num4} entities / second")); } } private void RemoveBuild(int objId) { if (PluginConfig.useActionBuildTearDown.Value) { _player.controller.actionBuild.DoDismantleObject(objId); } else if (objId > 0) { _player.factory.RemoveEntityWithComponents(objId, false); } else if (objId < 0) { _player.factory.RemovePrebuildWithComponents(-objId); } } private void Start() { Log.LogAndPopupMessage("Bulldozing factory belts, inserters, assemblers, labs, stations, you name it"); _clearStopWatch.Start(); _running = true; _msTakenTotal = 0L; _updatesRun = 0; _itemsDestroyed = 0; if (PluginConfig.featureFastDelete.Value && !PluginConfig.IsLatConstrained()) { RaptorFastDelete.Execute(); } ItemDestructionPhase itemDestructionPhase = ItemDestructionPhase.Inserters; if (_factory == null) { Log.logger.LogDebug((object)"no current factory found"); _running = false; return; } Dictionary dictionary = new Dictionary(); HashSet hashSet = new HashSet(); List list = new List(); for (int i = 1; i < _factory.entityCursor; i++) { if (_factory.entityPool[i].protoId > 0 && !EntityOutOfLatRange(i, _factory)) { list.Add(i); } } for (; itemDestructionPhase < ItemDestructionPhase.Done; itemDestructionPhase++) { foreach (int item in list) { if (_factory.entityPool[item].protoId <= 0 || hashSet.Contains(item)) { continue; } bool flag = false; switch (itemDestructionPhase) { case ItemDestructionPhase.Inserters: flag = _factory.entityPool[item].inserterId > 0; break; case ItemDestructionPhase.Assemblers: flag = _factory.entityPool[item].assemblerId > 0; break; case ItemDestructionPhase.Belts: flag = _factory.entityPool[item].beltId > 0; break; case ItemDestructionPhase.Stations: flag = _factory.entityPool[item].stationId > 0; break; case ItemDestructionPhase.Other: flag = true; break; } bool flag2 = PluginConfig.skipDestroyingStations.Value && _factory.entityPool[item].stationId > 0; if (flag && !flag2) { if (!dictionary.ContainsKey(itemDestructionPhase)) { dictionary[itemDestructionPhase] = 0; } dictionary[itemDestructionPhase]++; hashSet.Add(item); _wreckingBallWork.Enqueue(new WreckingBallWorkItem { Phase = itemDestructionPhase, ItemId = item }); } } } AddTasksForBluePrintGhosts(_factory); Log.logger.LogDebug((object)$"added {_wreckingBallWork.Count} items to delete {dictionary}"); } public static int CountBuildGhosts(PlanetFactory currentPlanetFactory) { return currentPlanetFactory.prebuildPool.Count((PrebuildData prebuildData) => prebuildData.id >= 1); } private void AddTasksForBluePrintGhosts(PlanetFactory currentPlanetFactory) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) int num = 0; PrebuildData[] prebuildPool = currentPlanetFactory.prebuildPool; foreach (PrebuildData val in prebuildPool) { if (val.id >= 1) { _wreckingBallWork.Enqueue(new WreckingBallWorkItem { Phase = ItemDestructionPhase.Other, ItemId = -val.id }); num++; } } if (num > 0) { Log.LogAndPopupMessage($"Found {num} build ghosts"); } else { Log.logger.LogDebug((object)"no ghosts found"); } } [HarmonyPrefix] [HarmonyPatch(typeof(Player), "ThrowTrash")] public static bool Player_ThrowTrash_Prefix() { if (_instance == null || !_instance._running) { return true; } if (PluginConfig.deleteFactoryTrash.Value) { return false; } return true; } [HarmonyPrefix] [HarmonyPatch(typeof(VFAudio), "Create", new Type[] { typeof(string), typeof(Transform), typeof(Vector3), typeof(bool), typeof(int), typeof(int), typeof(long) })] public static bool VFAudio_Create_Prefix(string _name) { WreckingBall instance = _instance; if (instance == null || !instance._running) { return true; } if (!string.Equals(_name, "knock-0")) { return true; } return false; } public static bool EntityOutOfLatRange(int entityId, PlanetFactory factory) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (PluginConfig.IsLatConstrained() && PluginConfig.LatitudeOutOfBounds(GeoUtil.GetLatitudeDegForPosition(factory.entityPool[entityId].pos))) { return true; } return false; } } public static class PluginInfo { public const string PLUGIN_GUID = "Bulldozer"; public const string PLUGIN_NAME = "Bulldozer"; public const string PLUGIN_VERSION = "1.1.12"; } } namespace Bulldozer.SelectiveDecoration { public class DebugBackgroundPainter : ISelectivePlanetDecorator { public DecorationConfig GetDecorationForLocation(LatLon location) { return DecorationConfig.None; } public string ActionSummary() { return "DEBUG BACKGROUND"; } } public readonly struct DecorationConfig : IEquatable { public readonly int ReformType; public readonly int ColorIndex; public static DecorationConfig None = new DecorationConfig(-1, -1); public DecorationConfig(int reformType, int colorIndex) { ReformType = reformType; ColorIndex = colorIndex; } public DecorationConfig(int colorIndex) { ColorIndex = colorIndex; Player mainPlayer = GameMain.mainPlayer; PlayerAction_Build val = ((mainPlayer != null) ? mainPlayer.controller.actionBuild : null); if (val == null) { ReformType = 1; return; } int num = 1; switch (PluginConfig.foundationDecorationMode.Value) { case FoundationDecorationMode.Tool: num = val.reformTool.brushType; if (num > 2) { num = 1; } break; case FoundationDecorationMode.Paint: num = 1; break; case FoundationDecorationMode.Decorate: num = 2; break; case FoundationDecorationMode.Clear: num = 1; break; default: Log.Warn($"unexpected brush type requested {PluginConfig.foundationDecorationMode.Value}"); break; } ReformType = num; } public bool Equals(DecorationConfig other) { if (ReformType == other.ReformType) { return ColorIndex == other.ColorIndex; } return false; } public override bool Equals(object obj) { if (obj is DecorationConfig other) { return Equals(other); } return false; } public override int GetHashCode() { return (ReformType * 397) ^ ColorIndex; } public bool IsNone() { return Equals(None); } } public class EquatorPainter : ISelectivePlanetDecorator { private static DecorationConfig _decorationConfig; private readonly ReformIndexInfoProvider _infoProvider; public EquatorPainter(ReformIndexInfoProvider infoProvider) { _infoProvider = infoProvider; _decorationConfig = new DecorationConfig(PluginConfig.guideLinesEquatorColor.Value); } public DecorationConfig GetDecorationForLocation(LatLon location) { var (latLon, latLon2) = _infoProvider.GetEquatorLatitudes(); if (latLon.RawLat() == location.RawLat() || latLon2.RawLat() == location.RawLat()) { return _decorationConfig; } return DecorationConfig.None; } public string ActionSummary() { return "Equator"; } } public interface ISelectivePlanetDecorator { DecorationConfig GetDecorationForLocation(LatLon location); string ActionSummary(); } public class MajorMeridianPainter : ISelectivePlanetDecorator { private static DecorationConfig _majorMeridianConfig; private readonly ReformIndexInfoProvider infoProvider; public MajorMeridianPainter(ReformIndexInfoProvider reformIndexInfoProvider) { infoProvider = reformIndexInfoProvider; _majorMeridianConfig = new DecorationConfig(PluginConfig.guideLinesMeridianColor.Value); } public DecorationConfig GetDecorationForLocation(LatLon location) { if (PluginConfig.addGuideLinesMeridian.Value && infoProvider.GetMeridianPoints().Contains(location)) { return _majorMeridianConfig; } return DecorationConfig.None; } public string ActionSummary() { return "Major Meridians"; } } public class MinorMeridianPainter : ISelectivePlanetDecorator { private readonly HashSet _minorMeridianLongitudes = new HashSet(); private static DecorationConfig _minorMeridianConfig; private LatLon _lastRequest = LatLon.Empty; private bool _lastResult; public MinorMeridianPainter() { _minorMeridianConfig = new DecorationConfig(PluginConfig.guideLinesMinorMeridianColor.Value); InitMeridianLongitudes(); } public DecorationConfig GetDecorationForLocation(LatLon location) { if (Math.Abs(location.Lat) > (float)SelectiveDecorationBuilder.POLE_LATITUDE_START) { return DecorationConfig.None; } if (DistanceFromMajorMeridian(location.Long) < 5) { return DecorationConfig.None; } if (location.Long < 0f) { if (_minorMeridianLongitudes.Contains(Mathf.CeilToInt(location.Long))) { _lastRequest = location; _lastResult = true; return _minorMeridianConfig; } } else if (_minorMeridianLongitudes.Contains(Mathf.FloorToInt(location.Long))) { _lastRequest = location; _lastResult = true; return _minorMeridianConfig; } if (_lastRequest.RawLat() == location.RawLat() && !_lastResult) { float num = Mathf.Abs(_lastRequest.Long - location.Long) / 3f; for (int i = 1; i <= 3; i++) { float num2 = Mathf.MoveTowards(_lastRequest.Long, location.Long, num * (float)i); if (_minorMeridianLongitudes.Contains((int)num2)) { _lastRequest = location; _lastResult = true; return _minorMeridianConfig; } } } _lastRequest = location; _lastResult = false; return DecorationConfig.None; } private int DistanceFromMajorMeridian(float lon) { if (lon >= -5f) { if (lon <= 5f) { return (int)Mathf.Abs(lon); } if (lon >= 85f) { if (lon <= 95f) { return (int)Mathf.Abs(90f - lon); } if (lon >= 175f) { return (int)Mathf.Abs(180f - lon); } } } else if (lon <= -85f && lon >= -95f) { return (int)Mathf.Abs(-90f - lon); } return (int)Mathf.Abs(-180f - lon); } private void InitMeridianLongitudes() { int value = PluginConfig.minorMeridianInterval.Value; for (int i = 0; i < 180; i += value) { _minorMeridianLongitudes.Add(i); } for (int num = -value; num > -180; num -= value) { _minorMeridianLongitudes.Add(num); } string arg = string.Join(",", _minorMeridianLongitudes); Log.Debug($"minor meridians for {value} are {arg}"); } public string ActionSummary() { return $"Minor Meridians (interval = {PluginConfig.minorMeridianInterval.Value}°)"; } } public class PolePainter : ISelectivePlanetDecorator { public DecorationConfig GetDecorationForLocation(LatLon location) { if (Math.Abs(location.Lat) < (float)SelectiveDecorationBuilder.POLE_LATITUDE_START) { return DecorationConfig.None; } return new DecorationConfig(PluginConfig.guideLinesPoleColor.Value); } public string ActionSummary() { return "Poles"; } } public static class SelectiveDecorationBuilder { public static readonly int POLE_LATITUDE_START = 85; public static SelectivePlanetPainter Build(ReformIndexInfoProvider reformIndexInfoProvider) { SelectivePlanetPainter selectivePlanetPainter = new SelectivePlanetPainter(reformIndexInfoProvider); if (PluginConfig.addGuideLinesPoles.Value) { selectivePlanetPainter.Register(new PolePainter()); } if (PluginConfig.addGuideLinesEquator.Value) { selectivePlanetPainter.Register(new EquatorPainter(reformIndexInfoProvider)); } if (PluginConfig.addGuideLinesMeridian.Value) { selectivePlanetPainter.Register(new MajorMeridianPainter(reformIndexInfoProvider)); } if (PluginConfig.minorMeridianInterval.Value > 0) { selectivePlanetPainter.Register(new MinorMeridianPainter()); } if (PluginConfig.addGuideLinesTropic.Value) { selectivePlanetPainter.Register(new TropicsPainter(reformIndexInfoProvider)); } if (PluginConfig.enableRegionColor.Value) { selectivePlanetPainter.Register(new SelectiveRegionalPlanetDecorator()); } return selectivePlanetPainter; } } public class SelectivePlanetPainter { private readonly ReformIndexInfoProvider _reformIndexInfoProvider; private readonly List _decorators = new List(); public SelectivePlanetPainter(ReformIndexInfoProvider reformIndexInfoProvider) { _reformIndexInfoProvider = reformIndexInfoProvider; } public void Decorate() { //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) if (!_reformIndexInfoProvider.Initted) { Log.Warn("Can't paint regions, index provider is not initted"); return; } PlatformSystem platformSystem = _reformIndexInfoProvider.platformSystem; PlanetRawData data = GameMain.localPlanet.data; Player mainPlayer = GameMain.mainPlayer; if (((mainPlayer != null) ? mainPlayer.controller.actionBuild : null) == null) { return; } platformSystem.EnsureReformData(); Log.Debug($"starting selective mode with {_decorators.Count} decorators registered"); int maxReformCount = platformSystem.maxReformCount; HashSet hashSet = new HashSet(); int num = 0; for (int i = 0; i < maxReformCount; i++) { LatLon forIndex = _reformIndexInfoProvider.GetForIndex(i); if (forIndex.IsEmpty()) { Log.Warn($"latLon for index: {i} was really empty"); } if (PluginConfig.LatitudeOutOfBounds(forIndex.Lat)) { continue; } DecorationConfig decorationConfig = DecoratorForLocation(forIndex); if (decorationConfig.IsNone()) { continue; } if (PluginConfig.guideLinesOnly.Value) { LatLon[] pointsAround = GetPointsAround(forIndex); for (int j = 0; j < pointsAround.Length; j++) { LatLon latLon = pointsAround[j]; Vector3 val = GeoUtil.LatLonToPosition(latLon.Lat, latLon.Long, platformSystem.planet.realRadius); int num2 = data.QueryIndex(val); if (!hashSet.Contains(num2)) { GameMain.localPlanet.AddHeightMapModLevel(num2, 3); data.modData[num2 / 2] = 51; hashSet.Add(num2); } } } int num3 = ((!platformSystem.IsTerrainReformed(platformSystem.GetReformType(i))) ? 1 : 0); if (num3 > 0 && PluginConfig.foundationConsumption.Value != OperationMode.FullCheat) { num += num3; if (!StorageSystemManager.RemoveItems(1131, num3).successful && PluginConfig.foundationConsumption.Value == OperationMode.Honest) { Log.LogAndPopupMessage("Out of foundation, halting."); break; } } platformSystem.SetReformType(i, decorationConfig.ReformType); platformSystem.SetReformColor(i, decorationConfig.ColorIndex); } for (int k = 0; k < platformSystem.planet.dirtyFlags.Length; k++) { platformSystem.planet.dirtyFlags[k] = true; } platformSystem.planet.landPercentDirtyFlag = true; if (platformSystem.planet.UpdateDirtyMeshes()) { platformSystem.planet.factory.RenderLocalPlanetHeightmap(); } } public void Register(ISelectivePlanetDecorator decorator) { if (!_decorators.Contains(decorator)) { _decorators.Add(decorator); } } public void UnregisterAll() { _decorators.Clear(); } public DecorationConfig DecoratorForLocation(LatLon location) { foreach (ISelectivePlanetDecorator decorator in _decorators) { DecorationConfig decorationForLocation = decorator.GetDecorationForLocation(location); if (!decorationForLocation.IsNone()) { return decorationForLocation; } } return DecorationConfig.None; } public string BuildActionSummary() { StringBuilder stringBuilder = new StringBuilder("Add the following guide markings: \n"); foreach (ISelectivePlanetDecorator decorator in _decorators) { string text = decorator.ActionSummary(); if (!string.IsNullOrWhiteSpace(text)) { stringBuilder.Append("\t" + text + "\n"); } } return stringBuilder.ToString(); } public SelectivePlanetPainter Flatten() { if (!PluginConfig.guideLinesOnly.Value) { return this; } for (int i = 0; i < GameMain.localPlanet.modData.Length << 1; i++) { LatLon forModIndex = _reformIndexInfoProvider.GetForModIndex(i); if (forModIndex.Equals(LatLon.Empty)) { Log.LogNTimes("No coord mapped to data index for {0}", 200, i); GameMain.localPlanet.AddHeightMapModLevel(i, 3); } else if (!PluginConfig.LatitudeOutOfBounds(forModIndex.Lat) && ShouldPave(forModIndex)) { GameMain.localPlanet.AddHeightMapModLevel(i, 3); } } bool[] dirtyFlags = GameMain.localPlanet.dirtyFlags; int num = dirtyFlags.Length; for (int j = 0; j < num; j++) { dirtyFlags[j] = true; } GameMain.localPlanet.landPercentDirtyFlag = true; if (GameMain.localPlanet.UpdateDirtyMeshes()) { GameMain.localPlanet.factory.RenderLocalPlanetHeightmap(); } return this; } private bool ShouldPave(LatLon latLon) { if (!DecoratorForLocation(latLon).IsNone()) { return true; } if (!DecoratorForLocation(latLon.Offset(-1, -1)).IsNone()) { return true; } if (!DecoratorForLocation(latLon.Offset(-1, 0)).IsNone()) { return true; } if (!DecoratorForLocation(latLon.Offset(-1, 1)).IsNone()) { return true; } if (!DecoratorForLocation(latLon.Offset(0, -1)).IsNone()) { return true; } if (!DecoratorForLocation(latLon.Offset(0, 1)).IsNone()) { return true; } if (!DecoratorForLocation(latLon.Offset(1, -1)).IsNone()) { return true; } if (!DecoratorForLocation(latLon.Offset(1, 0)).IsNone()) { return true; } if (!DecoratorForLocation(latLon.Offset(1, 1)).IsNone()) { return true; } return false; } private LatLon[] GetPointsAround(LatLon latLon) { return new LatLon[9] { latLon.Offset(-1, -1), latLon.Offset(-1, 0), latLon.Offset(-1, 1), latLon.Offset(0, -1), latLon, latLon.Offset(0, 1), latLon.Offset(1, -1), latLon.Offset(1, 0), latLon.Offset(1, 1) }; } } public class SelectiveRegionalPlanetDecorator : ISelectivePlanetDecorator { public DecorationConfig GetDecorationForLocation(LatLon location) { RegionColorConfig forPosition = RegionalColors.Instance.GetForPosition(location.Lat, location.Long); if (forPosition != null) { return new DecorationConfig(forPosition.colorIndex); } return DecorationConfig.None; } public string ActionSummary() { return $"Regions ({RegionalColors.Instance.Count})"; } } public class TropicsPainter : ISelectivePlanetDecorator { private readonly ReformIndexInfoProvider _infoProvider; private readonly DecorationConfig _tropicsDecorationConfig; public TropicsPainter(ReformIndexInfoProvider provider) { _infoProvider = provider; _tropicsDecorationConfig = new DecorationConfig(PluginConfig.guideLinesTropicColor.Value); } public DecorationConfig GetDecorationForLocation(LatLon location) { if (_infoProvider.GetTropicsLatitudes().Contains(LatLon.FromCoords(location.Lat, 0.0, location.Precision))) { return _tropicsDecorationConfig; } return DecorationConfig.None; } public string ActionSummary() { return $"Tropics (detected {_infoProvider.GetTropicsLatitudes().Count})"; } } } namespace Bulldozer.Properties { [GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [DebuggerNonUserCode] [CompilerGenerated] internal class Resources { private static ResourceManager resourceMan; private static CultureInfo resourceCulture; [EditorBrowsable(EditorBrowsableState.Advanced)] internal static ResourceManager ResourceManager { get { if (resourceMan == null) { resourceMan = new ResourceManager("Bulldozer.Properties.Resources", typeof(Resources).Assembly); } return resourceMan; } } [EditorBrowsable(EditorBrowsableState.Advanced)] internal static CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } internal static string BulldozerPlugin_Not_Initialized => ResourceManager.GetString("BulldozerPlugin_Not_Initialized", resourceCulture); internal Resources() { } } }