[
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n##\n## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore\n\n# User-specific files\n*.rsuser\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n\n# User-specific files (MonoDevelop/Xamarin Studio)\n*.userprefs\n\n# Mono auto generated files\nmono_crash.*\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\nx64/\nx86/\n[Aa][Rr][Mm]/\n[Aa][Rr][Mm]64/\nbld/\n[Bb]in/\n[Oo]bj/\n[Ll]og/\n[Ll]ogs/\n\n# Visual Studio 2015/2017 cache/options directory\n.vs/\n# Uncomment if you have tasks that create the project's static files in wwwroot\n#wwwroot/\n\n# Visual Studio 2017 auto generated files\nGenerated\\ Files/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n# NUnit\n*.VisualState.xml\nTestResult.xml\nnunit-*.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n# Benchmark Results\nBenchmarkDotNet.Artifacts/\n\n# .NET Core\nproject.lock.json\nproject.fragment.lock.json\nartifacts/\n\n# StyleCop\nStyleCopReport.xml\n\n# Files built by Visual Studio\n*_i.c\n*_p.c\n*_h.h\n*.ilk\n*.meta\n*.obj\n*.iobj\n*.pch\n*.pdb\n*.ipdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*_wpftmp.csproj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opendb\n*.opensdf\n*.sdf\n*.cachefile\n*.VC.db\n*.VC.VC.opendb\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n*.sap\n\n# Visual Studio Trace Files\n*.e2e\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# AxoCover is a Code Coverage Tool\n.axoCover/*\n!.axoCover/settings.json\n\n# Visual Studio code coverage results\n*.coverage\n*.coveragexml\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\nnCrunchTemp_*\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n# Note: Comment the next line if you want to checkin your web deploy settings,\n# but database connection strings (with potential passwords) will be unencrypted\n*.pubxml\n*.publishproj\n\n# Microsoft Azure Web App publish settings. Comment the next line if you want to\n# checkin your Azure Web App publish settings, but sensitive information contained\n# in these scripts will be unencrypted\nPublishScripts/\n\n# NuGet Packages\n*.nupkg\n# NuGet Symbol Packages\n*.snupkg\n# The packages folder can be ignored because of Package Restore\n**/[Pp]ackages/*\n# except build/, which is used as an MSBuild target.\n!**/[Pp]ackages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/[Pp]ackages/repositories.config\n# NuGet v3's project.json files produces more ignorable files\n*.nuget.props\n*.nuget.targets\n\n# Microsoft Azure Build Output\ncsx/\n*.build.csdef\n\n# Microsoft Azure Emulator\necf/\nrcf/\n\n# Windows Store app package directories and files\nAppPackages/\nBundleArtifacts/\nPackage.StoreAssociation.xml\n_pkginfo.txt\n*.appx\n*.appxbundle\n*.appxupload\n\n# Visual Studio cache files\n# files ending in .cache can be ignored\n*.[Cc]ache\n# but keep track of directories ending in .cache\n!?*.[Cc]ache/\n\n# Others\nClientBin/\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.jfm\n*.pfx\n*.publishsettings\norleans.codegen.cs\n\n# Including strong name files can present a security risk\n# (https://github.com/github/gitignore/pull/2483#issue-259490424)\n#*.snk\n\n# Since there are multiple workflows, uncomment next line to ignore bower_components\n# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)\n#bower_components/\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\nServiceFabricBackup/\n*.rptproj.bak\n\n# SQL Server files\n*.mdf\n*.ldf\n*.ndf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n*.rptproj.rsuser\n*- [Bb]ackup.rdl\n*- [Bb]ackup ([0-9]).rdl\n*- [Bb]ackup ([0-9][0-9]).rdl\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# GhostDoc plugin setting file\n*.GhostDoc.xml\n\n# Node.js Tools for Visual Studio\n.ntvs_analysis.dat\nnode_modules/\n\n# Visual Studio 6 build log\n*.plg\n\n# Visual Studio 6 workspace options file\n*.opt\n\n# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)\n*.vbw\n\n# Visual Studio LightSwitch build output\n**/*.HTMLClient/GeneratedArtifacts\n**/*.DesktopClient/GeneratedArtifacts\n**/*.DesktopClient/ModelManifest.xml\n**/*.Server/GeneratedArtifacts\n**/*.Server/ModelManifest.xml\n_Pvt_Extensions\n\n# Paket dependency manager\n.paket/paket.exe\npaket-files/\n\n# FAKE - F# Make\n.fake/\n\n# CodeRush personal settings\n.cr/personal\n\n# Python Tools for Visual Studio (PTVS)\n__pycache__/\n*.pyc\n\n# Cake - Uncomment if you are using it\n# tools/**\n# !tools/packages.config\n\n# Tabs Studio\n*.tss\n\n# Telerik's JustMock configuration file\n*.jmconfig\n\n# BizTalk build output\n*.btp.cs\n*.btm.cs\n*.odx.cs\n*.xsd.cs\n\n# OpenCover UI analysis results\nOpenCover/\n\n# Azure Stream Analytics local run output\nASALocalRun/\n\n# MSBuild Binary and Structured Log\n*.binlog\n\n# NVidia Nsight GPU debugger configuration file\n*.nvuser\n\n# MFractors (Xamarin productivity tool) working folder\n.mfractor/\n\n# Local History for Visual Studio\n.localhistory/\n\n# BeatPulse healthcheck temp database\nhealthchecksdb\n\n# Backup folder for Package Reference Convert tool in Visual Studio 2017\nMigrationBackup/\n\n# Ionide (cross platform F# VS Code tools) working folder\n.ionide/\n"
  },
  {
    "path": "Caesar/Caesar/App.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<configuration>\n    <startup> \n        <supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.6\" />\n    </startup>\n</configuration>"
  },
  {
    "path": "Caesar/Caesar/BitUtility.cs",
    "content": "﻿using System;\nusing System.Runtime.InteropServices;\nusing System.Text;\n\nnamespace Caesar\n{\n    /// <summary>\n    /// Utilities for bit and byte operations.\n    /// (Frequently copied-and-pasted across my projects)\n    /// </summary>\n    public class BitUtility\n    {\n        /// <summary>\n        /// Sets all values in an array of bytes to a specific value\n        /// </summary>\n        /// <param name=\"value\">Value to set byte array to</param>\n        /// <param name=\"buf\">Target byte array buffer</param>\n        public static void Memset(byte value, byte[] buf)\n        {\n            for (int i = 0; i < buf.Length; i++)\n            {\n                buf[i] = value;\n            }\n        }\n        // Internally used by BytesFromHex\n        private static byte[] StringToByteArrayFastest(string hex)\n        {\n            // see https://stackoverflow.com/questions/321370/how-can-i-convert-a-hex-string-to-a-byte-array\n            if (hex.Length % 2 == 1)\n            {\n                throw new Exception(\"The binary key cannot have an odd number of digits\");\n            }\n            byte[] arr = new byte[hex.Length >> 1];\n            for (int i = 0; i < hex.Length >> 1; ++i)\n            {\n                arr[i] = (byte)((GetHexValue(hex[i << 1]) << 4) + (GetHexValue(hex[(i << 1) + 1])));\n            }\n            return arr;\n        }\n        // Internally used by StringToByteArrayFastest\n        private static int GetHexValue(char hex)\n        {\n            int val = (int)hex;\n            return val - (val < 58 ? 48 : 55);\n        }\n        /// <summary>\n        /// Converts an array of bytes into its hex-string equivalent\n        /// </summary>\n        /// <param name=\"inBytes\">Input byte array</param>\n        /// <param name=\"spacedOut\">Option to add spaces between individual bytes</param>\n        /// <returns>Hex-string based on the input byte array</returns>\n        public static string BytesToHex(byte[] inBytes, bool spacedOut = false)\n        {\n            return BitConverter.ToString(inBytes).Replace(\"-\", spacedOut ? \" \" : \"\");\n        }\n\n        /// <summary>\n        /// Converts an array of bytes into a printable hex-string\n        /// </summary>\n        /// <param name=\"hexString\">Input hex-string to convert into a byte array</param>\n        /// <returns>Byte array based on the input hex-string</returns>\n        public static byte[] BytesFromHex(string hexString)\n        {\n            return StringToByteArrayFastest(hexString.Replace(\" \", \"\"));\n        }\n\n        /// <summary>\n        /// Resize a smaller array of bytes to a larger array. The padding bytes will be 0.\n        /// </summary>\n        /// <param name=\"inData\">Input byte array</param>\n        /// <param name=\"finalSize\">New size for the input array</param>\n        /// <returns>Resized byte array</returns>\n        public static byte[] PadBytes(byte[] inData, int finalSize)\n        {\n            if (inData.Length > finalSize)\n            {\n                return inData;\n            }\n            byte[] result = new byte[finalSize];\n            Buffer.BlockCopy(inData, 0, result, 0, inData.Length);\n            return result;\n        }\n\n        [StructLayout(LayoutKind.Explicit)]\n        struct UIntFloat\n        {\n            [FieldOffset(0)]\n            public float FloatValue;\n\n            [FieldOffset(0)]\n            public uint IntValue;\n        }\n\n        /// <summary>\n        /// Directly converts an in-memory representation of an uint to a float.\n        /// </summary>\n        /// <param name=\"value\"></param>\n        /// <returns></returns>\n        public static float ToFloat(uint value)\n        {\n            UIntFloat intermediate = new UIntFloat();\n            intermediate.IntValue = value;\n            return intermediate.FloatValue;\n        }\n\n\n        // Caesar specific\n\n        public static byte[] BitArrayToByteArray(byte[] inArray, bool littleEndian = true)\n        {\n            if (inArray.Length % 8 != 0)\n            {\n                throw new NotImplementedException(\"Bits must be byte-aligned\");\n            }\n\n            byte[] result = new byte[inArray.Length / 8];\n            byte workingByte = 0;\n            int arrayIndex = 0;\n            for (int i = 0; i < inArray.Length; i++)\n            {\n                if (littleEndian)\n                {\n                    workingByte >>= 1;\n                    workingByte |= (inArray[i] == 0) ? (byte)0 : (byte)0x80;\n                }\n                else\n                {\n                    workingByte <<= 1;\n                    workingByte |= inArray[i];\n                }\n                if (i % 8 == 7)\n                {\n                    result[arrayIndex] = workingByte;\n                    arrayIndex++;\n                }\n            }\n            return result;\n        }\n\n        public static byte[] ByteArrayToBitArray(byte[] inArray, bool littleEndian = true)\n        {\n            byte[] result = new byte[inArray.Length * 8];\n            int arrayIndex = 0;\n            foreach (byte inByte in inArray)\n            {\n                if (littleEndian)\n                {\n                    for (int i = 0; i < 8; i++)\n                    {\n                        bool bitSet = ((1 << i) & inByte) > 0;\n                        result[arrayIndex] = (bitSet ? (byte)1 : (byte)0);\n                        arrayIndex++;\n                    }\n                }\n                else\n                {\n                    for (int i = 7; i >= 0; i--)\n                    {\n                        bool bitSet = ((1 << i) & inByte) > 0;\n                        result[arrayIndex] = (bitSet ? (byte)1 : (byte)0);\n                        arrayIndex++;\n                    }\n                }\n            }\n            return result;\n        }\n\n        public static string BytesToBitString(byte[] inArray)\n        {\n            StringBuilder sb = new StringBuilder();\n            foreach (byte b in inArray)\n            {\n                sb.Append(Convert.ToString(b, toBase: 2).PadLeft(8, '0') + \" \");\n            }\n            return sb.ToString().TrimEnd();\n        }\n        public static string BytesToDecimalString(byte[] inArray)\n        {\n            StringBuilder sb = new StringBuilder();\n            foreach (byte b in inArray)\n            {\n                sb.Append(Convert.ToString(b, toBase: 10).PadLeft(3, '0') + \" \");\n            }\n            return sb.ToString().TrimEnd();\n        }\n        public static byte[] BytesFromDecimalString(string inData)\n        {\n            string[] chunks = inData.Split(new string[] { \" \" }, StringSplitOptions.RemoveEmptyEntries);\n            byte[] result = new byte[chunks.Length];\n            for (int i = 0; i < chunks.Length; i++) \n            {\n                result[i] = byte.Parse(chunks[i]);\n            }\n            return result;\n        }\n\n        public static string BitsToString(byte[] inArray) \n        {\n            StringBuilder sb = new StringBuilder();\n            for (int i = 0; i < inArray.Length; i++)\n            {\n                sb.Append(inArray[i]);\n                if (i % 8 == 7) \n                {\n                    sb.Append(\" \");\n                }\n            }\n            return sb.ToString();\n        }\n\n        public void BitRoundtripTest() \n        {\n            byte[] bitarray = new byte[] {\n                1,1,1,1, 1,1,1,1,\n                1,0,1,0, 1,0,1,0,\n                0,1,0,1, 0,1,0,1,\n                0,0,0,0, 0,0,0,0,\n                1,1,1,1, 0,0,0,0,\n                0,0,0,0, 1,1,1,1,\n            };\n            byte[] testByteArray = BitUtility.BitArrayToByteArray(bitarray, false);\n            Console.WriteLine($\"test in 1: {BitUtility.BytesToBitString(testByteArray)}\");\n            Console.WriteLine($\"test in 1: {BitUtility.BytesToHex(testByteArray)}\");\n            foreach (byte b in bitarray)\n            {\n                Console.Write(b);\n            }\n            Console.WriteLine();\n\n            byte[] testBitArray = BitUtility.ByteArrayToBitArray(testByteArray, false);\n            testByteArray = BitUtility.BitArrayToByteArray(testBitArray);\n            Console.WriteLine($\"test in 2: {BitUtility.BytesToBitString(testByteArray)}\");\n            Console.WriteLine($\"test in 2: {BitUtility.BytesToHex(testByteArray)}\");\n\n            foreach (byte b in testBitArray)\n            {\n                Console.Write(b);\n            }\n            Console.WriteLine();\n\n        }\n\n        public static bool CheckHexValid(string inHex) \n        {\n            string cleanedText = inHex.Replace(\" \", \"\").Replace(\"\\r\", \"\").Replace(\"\\n\", \"\").Replace(\"\\t\", \"\").Replace(\"-\", \"\").ToUpper();\n            if (cleanedText.Length % 2 != 0)\n            {\n                return false;\n            }\n            if (!System.Text.RegularExpressions.Regex.IsMatch(cleanedText, @\"\\A\\b[0-9a-fA-F]+\\b\\Z\"))\n            {\n                return false;\n            }\n            return true;\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/CFFHeader.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Caesar\n{\n    public class CFFHeader\n    {\n        public int CaesarVersion;\n        public int GpdVersion;\n        public int EcuCount;\n        public int EcuOffset;\n        public int CtfOffset; // nCtfHeaderRpos\n        public int StringPoolSize;\n        private int DscOffset;\n        private int DscCount;\n        private int DscEntrySize;\n        public string CbfVersionString;\n        public string GpdVersionString;\n        public string XmlString;\n\n        [Newtonsoft.Json.JsonIgnore]\n        public int CffHeaderSize;\n        [Newtonsoft.Json.JsonIgnore]\n        public long BaseAddress;\n\n        public long DscBlockOffset;\n        private int DscBlockSize;\n\n        [Newtonsoft.Json.JsonIgnore]\n        public byte[] DSCPool = new byte[] { };\n\n        // DIIAddCBFFile\n\n        public CFFHeader() \n        { }\n\n        public CFFHeader(BinaryReader reader) \n        {\n            reader.BaseStream.Seek(StubHeader.StubHeaderSize, SeekOrigin.Begin);\n            CffHeaderSize = reader.ReadInt32();\n\n            BaseAddress = reader.BaseStream.Position;\n\n            ulong bitFlags = reader.ReadUInt16();\n\n            CaesarVersion = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            GpdVersion = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            EcuCount = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            EcuOffset = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            CtfOffset = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            StringPoolSize = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            DscOffset = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            DscCount = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            DscEntrySize = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n\n            CbfVersionString = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress);\n            GpdVersionString = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress);\n            XmlString = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress);\n\n            \n            long dataBufferOffsetAfterStrings = StringPoolSize + CffHeaderSize + 0x414;\n            if (DscCount > 0) \n            {\n                DscBlockOffset = DscOffset + dataBufferOffsetAfterStrings;\n                DscBlockSize = DscEntrySize * DscCount;\n                reader.BaseStream.Seek(DscBlockOffset, SeekOrigin.Begin);\n                DSCPool = reader.ReadBytes(DscBlockSize);\n            }\n        }\n\n        public void PrintDebug() \n        {\n            Console.WriteLine($\"{nameof(CaesarVersion)} : {CaesarVersion}\");\n            Console.WriteLine($\"{nameof(GpdVersion)} : {GpdVersion}\");\n            Console.WriteLine($\"{nameof(EcuCount)} : {EcuCount}\");\n            Console.WriteLine($\"{nameof(EcuOffset)} : {EcuOffset} 0x{EcuOffset:X}\");\n            Console.WriteLine($\"{nameof(CtfOffset)} : 0x{CtfOffset:X}\");\n            Console.WriteLine($\"{nameof(StringPoolSize)} : {StringPoolSize} 0x{StringPoolSize:X}\");\n            \n            Console.WriteLine($\"{nameof(DscEntrySize)} : {DscEntrySize}\");\n            Console.WriteLine($\"{nameof(CbfVersionString)} : {CbfVersionString}\");\n            Console.WriteLine($\"{nameof(GpdVersionString)} : {GpdVersionString}\");\n\n            Console.WriteLine($\"{nameof(DscOffset)} : {DscOffset} 0x{DscOffset:X}\");\n            Console.WriteLine($\"{nameof(DscBlockOffset)} : {DscBlockOffset} 0x{DscBlockOffset:X}\");\n            Console.WriteLine($\"{nameof(DscCount)} : {DscCount}\");\n            Console.WriteLine($\"{nameof(DscBlockSize)} : {DscCount}\");\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/CTFHeader.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.IO;\n\nnamespace Caesar\n{\n    public class CTFHeader\n    {\n        public int CtfUnk1;\n        public string Qualifier;\n        public int CtfUnk3;\n        public int CtfUnk4;\n        private int CtfLanguageCount;\n        private int CtfLanguageTableOffset;\n        public string CtfUnkString;\n\n        public List<CTFLanguage> CtfLanguages;\n\n        public long BaseAddress;\n\n        public CTFHeader() { }\n        public CTFHeader(BinaryReader reader, long baseAddress, int headerSize) \n        {\n            BaseAddress = baseAddress;\n            reader.BaseStream.Seek(BaseAddress, SeekOrigin.Begin);\n            ulong ctfBitflags = reader.ReadUInt16();\n\n            CtfUnk1 = CaesarReader.ReadBitflagInt32(ref ctfBitflags, reader);\n            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref ctfBitflags, reader, BaseAddress);\n            CtfUnk3 = CaesarReader.ReadBitflagInt16(ref ctfBitflags, reader);\n            CtfUnk4 = CaesarReader.ReadBitflagInt32(ref ctfBitflags, reader);\n            CtfLanguageCount = CaesarReader.ReadBitflagInt32(ref ctfBitflags, reader);\n            CtfLanguageTableOffset = CaesarReader.ReadBitflagInt32(ref ctfBitflags, reader);\n            CtfUnkString = CaesarReader.ReadBitflagStringWithReader(ref ctfBitflags, reader, BaseAddress);\n\n            long ctfLanguageTableOffsetRelativeToDefintions = CtfLanguageTableOffset + BaseAddress;\n\n            // parse every language record\n            CtfLanguages = new List<CTFLanguage>();\n            for (int languageEntry = 0; languageEntry < CtfLanguageCount; languageEntry++)\n            {\n                long languageTableEntryOffset = ctfLanguageTableOffsetRelativeToDefintions + (languageEntry * 4);\n\n                reader.BaseStream.Seek(languageTableEntryOffset, SeekOrigin.Begin);\n                long realLanguageEntryAddress = reader.ReadInt32() + ctfLanguageTableOffsetRelativeToDefintions;\n                CTFLanguage language = new CTFLanguage(reader, realLanguageEntryAddress, headerSize);\n                CtfLanguages.Add(language);\n            }\n        }\n        public void PrintDebug() \n        {\n            Console.WriteLine(\"----------- CTF header ----------- \");\n            Console.WriteLine($\"{nameof(CtfUnk1)} : {CtfUnk1}\");\n            Console.WriteLine($\"{nameof(Qualifier)} : {Qualifier}\");\n            Console.WriteLine($\"{nameof(CtfUnk3)} : {CtfUnk3}\");\n            Console.WriteLine($\"{nameof(CtfUnk4)} : {CtfUnk4}\");\n            Console.WriteLine($\"{nameof(CtfLanguageCount)} : {CtfLanguageCount}\");\n            Console.WriteLine($\"{nameof(CtfLanguageTableOffset)} : 0x{CtfLanguageTableOffset:X}\");\n            Console.WriteLine($\"{nameof(CtfUnkString)} : {CtfUnkString}\");\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/CTFLanguage.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.IO;\n\nnamespace Caesar\n{\n    public class CTFLanguage\n    {\n        public string Qualifier;\n        public int LanguageIndex;\n        private int StringPoolSize;\n        private int MaybeOffsetFromStringPoolBase;\n        private int StringCount;\n        public List<string> StringEntries;\n\n        public long BaseAddress;\n        public CTFLanguage() { }\n        public CTFLanguage(BinaryReader reader, long baseAddress, int headerSize) \n        {\n            BaseAddress = baseAddress;\n            reader.BaseStream.Seek(BaseAddress, SeekOrigin.Begin);\n            ulong languageEntryBitflags = reader.ReadUInt16();\n\n            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref languageEntryBitflags, reader, BaseAddress);\n            LanguageIndex = CaesarReader.ReadBitflagInt16(ref languageEntryBitflags, reader);\n            StringPoolSize = CaesarReader.ReadBitflagInt32(ref languageEntryBitflags, reader);\n            MaybeOffsetFromStringPoolBase = CaesarReader.ReadBitflagInt32(ref languageEntryBitflags, reader);\n            StringCount = CaesarReader.ReadBitflagInt32(ref languageEntryBitflags, reader);\n\n            LoadStrings(reader, headerSize, CaesarReader.DefaultEncoding);\n        }\n\n        public void LoadStrings(BinaryReader reader, int headerSize, Encoding encoding) \n        {\n            StringEntries = new List<string>();\n            int caesarStringTableOffset = headerSize + 0x410 + 4; // header.CffHeaderSize; strange that this has to be manually computed\n            for (int i = 0; i < StringCount; i++) \n            {\n                reader.BaseStream.Seek(caesarStringTableOffset + (i * 4), SeekOrigin.Begin);\n                int stringOffset = reader.ReadInt32();\n                reader.BaseStream.Seek(caesarStringTableOffset + stringOffset, SeekOrigin.Begin);\n                string result = CaesarReader.ReadStringFromBinaryReader(reader, encoding);\n                StringEntries.Add(result);\n            }\n        }\n\n        public string GetString(int stringId) \n        {\n            return GetString(StringEntries, stringId);\n        }\n\n        public static string GetString(List<string> language, int stringId) \n        {\n            if (stringId < 0) \n            {\n                return \"\";\n            }\n            if (stringId > language.Count) \n            {\n                return \"\";\n            }\n            return language[stringId];\n        }\n\n        public void PrintDebug() \n        {\n            Console.WriteLine($\"Language: {Qualifier} stringCount: {StringCount} stringPoolSize 0x{StringPoolSize:X}, unknowns: {LanguageIndex} {MaybeOffsetFromStringPoolBase}, base: {BaseAddress:X} \");\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/Caesar.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{71C43C61-7DC7-4D47-9947-1DD73E559911}</ProjectGuid>\n    <OutputType>Library</OutputType>\n    <RootNamespace>Caesar</RootNamespace>\n    <AssemblyName>Caesar</AssemblyName>\n    <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>\n    <Deterministic>true</Deterministic>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>\n  </PropertyGroup>\n  <PropertyGroup>\n    <StartupObject />\n  </PropertyGroup>\n  <PropertyGroup>\n    <ApplicationIcon>caesar_256.ico</ApplicationIcon>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Newtonsoft.Json.12.0.3\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"BitUtility.cs\" />\n    <Compile Include=\"CaesarContainer.cs\" />\n    <Compile Include=\"DiagPresentation.cs\" />\n    <Compile Include=\"DTC.cs\" />\n    <Compile Include=\"Flash\\CaesarFlashContainer.cs\" />\n    <Compile Include=\"CaesarReader.cs\" />\n    <Compile Include=\"CaesarStructure.cs\" />\n    <Compile Include=\"CFFHeader.cs\" />\n    <Compile Include=\"ComParameter.cs\" />\n    <Compile Include=\"CTFHeader.cs\" />\n    <Compile Include=\"CTFLanguage.cs\" />\n    <Compile Include=\"DiagPreparation.cs\" />\n    <Compile Include=\"DiagService.cs\" />\n    <Compile Include=\"DSCContext.cs\" />\n    <Compile Include=\"ECU.cs\" />\n    <Compile Include=\"ECUInterface.cs\" />\n    <Compile Include=\"ECUInterfaceSubtype.cs\" />\n    <Compile Include=\"ECUVariant.cs\" />\n    <Compile Include=\"ECUVariantPattern.cs\" />\n    <Compile Include=\"Flash\\FlashDataBlock.cs\" />\n    <Compile Include=\"Flash\\FlashDescriptionHeader.cs\" />\n    <Compile Include=\"Flash\\FlashHeader.cs\" />\n    <Compile Include=\"Flash\\FlashSecurity.cs\" />\n    <Compile Include=\"Flash\\FlashSegment.cs\" />\n    <Compile Include=\"Program.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <Compile Include=\"Scale.cs\" />\n    <Compile Include=\"StubHeader.cs\" />\n    <Compile Include=\"VCDomain.cs\" />\n    <Compile Include=\"VCFragment.cs\" />\n    <Compile Include=\"VCSubfragment.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"App.config\" />\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Content Include=\"caesar_256.ico\" />\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n</Project>"
  },
  {
    "path": "Caesar/Caesar/CaesarContainer.cs",
    "content": "﻿using Newtonsoft.Json;\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.IO.Compression;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Diagnostics;\n\nnamespace Caesar\n{\n    public class CaesarContainer\n    {\n        public CFFHeader CaesarCFFHeader;\n        public CTFHeader CaesarCTFHeader;\n        public List<ECU> CaesarECUs = new List<ECU>();\n        [Newtonsoft.Json.JsonIgnore]\n        public byte[] FileBytes = new byte[] { };\n\n        public uint FileChecksum;\n\n        public CaesarContainer() { }\n\n        // fixup serialization/deserialization:\n        // language strings should be properties; resolve to actual string only when called\n        public CaesarContainer(byte[] fileBytes)\n        {\n            Stopwatch sw = new Stopwatch();\n            sw.Start();\n\n            FileBytes = fileBytes;\n            // work from int __cdecl DIIAddCBFFile(char *fileName)\n            using (BinaryReader reader = new BinaryReader(new MemoryStream(fileBytes, 0, fileBytes.Length, false, true)))\n            {\n                byte[] header = reader.ReadBytes(StubHeader.StubHeaderSize);\n                StubHeader.ReadHeader(header);\n\n                int cffHeaderSize = reader.ReadInt32();\n                byte[] cffHeaderData = reader.ReadBytes(cffHeaderSize);\n\n                // expensive, probably an impediment for modders\n                // VerifyChecksum(fileBytes, out uint checksum);\n                FileChecksum = ReadFileChecksum(fileBytes);\n\n                ReadCFFDefinition(reader);\n                // language is the highest priority since all our strings come from it\n                ReadCTF(reader);\n                ReadECU(reader);\n            }\n\n            sw.Stop();\n#if DEBUG\n            Console.WriteLine($\"Loaded {CaesarECUs[0].Qualifier} in {sw.ElapsedMilliseconds}ms\");\n#endif\n        }\n\n        public static string SerializeContainer(CaesarContainer container) \n        {\n            return JsonConvert.SerializeObject(container);\n        }\n\n        public static CaesarContainer DeserializeContainer(string json) \n        {\n            CaesarContainer container = JsonConvert.DeserializeObject<CaesarContainer>(json);\n            // at this point, the container needs to restore its internal object references before it is fully usable\n            CTFLanguage language = container.CaesarCTFHeader.CtfLanguages[0];\n            foreach (ECU ecu in container.CaesarECUs) \n            {\n                ecu.Restore(language, container);\n            }\n\n            return container;\n        }\n\n        public static CaesarContainer DeserializeCompressedContainer(byte[] containerBytes)\n        {\n            string json = Encoding.UTF8.GetString(Inflate(containerBytes));\n            return DeserializeContainer(json);\n        }\n        public static byte[] SerializeCompressedContainer(CaesarContainer container)\n        {\n            return Deflate(Encoding.UTF8.GetBytes(SerializeContainer(container)));\n        }\n\n\n        private static byte[] Inflate(byte[] input)\n        {\n            using (MemoryStream ms = new MemoryStream(input))\n            {\n                using (MemoryStream msInner = new MemoryStream())\n                {\n                    using (DeflateStream z = new DeflateStream(ms, CompressionMode.Decompress))\n                    {\n                        z.CopyTo(msInner);\n                    }\n                    return msInner.ToArray();\n                }\n            }\n        }\n        private static byte[] Deflate(byte[] input)\n        {\n            using (MemoryStream compressedStream = new MemoryStream())\n            {\n                DeflateStream deflateStream = new DeflateStream(compressedStream, CompressionLevel.Optimal, true);\n                deflateStream.Write(input, 0, input.Length);\n                deflateStream.Close();\n                return compressedStream.ToArray();\n            }\n        }\n\n\n        public static bool VerifyChecksum(byte[] fileBytes, out uint checksum) \n        {\n            uint computedChecksum = CaesarReader.ComputeFileChecksumLazy(fileBytes);\n            uint providedChecksum = ReadFileChecksum(fileBytes);\n            checksum = providedChecksum;\n            if (computedChecksum != providedChecksum)\n            {\n                Console.WriteLine($\"WARNING: Checksum mismatch : computed/provided: {computedChecksum:X8}/{providedChecksum:X8}\");\n                return false;\n            }\n            return true;\n        }\n\n        public static string GetCaesarVersionString()\n        {\n            System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();\n            System.Diagnostics.FileVersionInfo fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(assembly.Location);\n            return fvi.FileVersion;\n        }\n\n        public static uint ReadFileChecksum(byte[] fileBytes) \n        {\n            return BitConverter.ToUInt32(fileBytes, fileBytes.Length - 4);\n        }\n\n        public ECUVariant GetECUVariantByName(string name)\n        {\n            foreach (ECU ecu in CaesarECUs)\n            {\n                foreach (ECUVariant variant in ecu.ECUVariants)\n                {\n                    if (variant.Qualifier == name)\n                    {\n                        return variant;\n                    }\n                }\n            }\n            return null;\n        }\n        public ECU GetECUByName(string name)\n        {\n            foreach (ECU ecu in CaesarECUs)\n            {\n                if (ecu.Qualifier == name)\n                {\n                    return ecu;\n                }\n            }\n            return null;\n        }\n\n        public string[] GetECUVariantNames() \n        {\n            List<string> result = new List<string>();\n\n            foreach (ECU ecu in CaesarECUs)\n            {\n                foreach (ECUVariant variant in ecu.ECUVariants)\n                {\n                    result.Add(variant.Qualifier);\n                }\n            }\n            return result.ToArray();\n        }\n\n        public CTFLanguage GetLanguage() \n        {\n            if (CaesarCTFHeader.CtfLanguages is null)\n            {\n                throw new NotImplementedException(\"stringtable not initialized\");\n            }\n\n            if (CaesarCTFHeader.CtfLanguages.Count != 0)\n            {\n                return CaesarCTFHeader.CtfLanguages[0];\n            }\n            throw new NotImplementedException(\"no idea how to handle missing stringtable\");\n        }\n\n        void ReadECU(BinaryReader fileReader) \n        {\n            CaesarECUs = new List<ECU>();\n            // read all ecu definitions\n            long ecuTableOffset = CaesarCFFHeader.EcuOffset + CaesarCFFHeader.BaseAddress;\n            \n            for (int ecuIndex = 0; ecuIndex < CaesarCFFHeader.EcuCount; ecuIndex++)\n            {\n                // seek to an entry the ecu offsets table\n                fileReader.BaseStream.Seek(ecuTableOffset + (ecuIndex * 4), SeekOrigin.Begin);\n                // read the offset to the ecu entry, then seek to the actual address\n                int offsetToActualEcuEntry = fileReader.ReadInt32();\n                CaesarECUs.Add(new ECU(fileReader, GetLanguage(), CaesarCFFHeader, ecuTableOffset + offsetToActualEcuEntry, this));\n            }\n        }\n\n        void ReadCTF(BinaryReader fileReader) \n        {\n            // parse CTF language stuff\n            // approx 0x1304 / 4 number of strings?\n            if (CaesarCFFHeader.CtfOffset == 0)\n            {\n                throw new NotImplementedException(\"No idea how to handle nonexistent ctf header\");\n            }\n            long ctfOffset = CaesarCFFHeader.BaseAddress + CaesarCFFHeader.CtfOffset;\n            CaesarCTFHeader = new CTFHeader(fileReader, ctfOffset, CaesarCFFHeader.CffHeaderSize);\n        }\n\n\n        void ReadCFFDefinition(BinaryReader fileReader)\n        {\n            CaesarCFFHeader = new CFFHeader(fileReader);\n            // CaesarCFFHeader.PrintDebug();\n\n            if (CaesarCFFHeader.CaesarVersion < 400) \n            {\n                throw new NotImplementedException($\"Unhandled Caesar version: {CaesarCFFHeader.CaesarVersion}\");\n            }\n\n            int caesarStringTableOffset = CaesarCFFHeader.CffHeaderSize + 0x410 + 4;\n            int formEntryTable = caesarStringTableOffset + CaesarCFFHeader.StringPoolSize;\n                \n            //Console.WriteLine($\"{nameof(caesarStringTableOffset)} : 0x{caesarStringTableOffset:X}\");\n            //Console.WriteLine($\"{nameof(afterStringTableOffset)} : 0x{afterStringTableOffset:X}\");\n\n            /*\n            if (CaesarCFFHeader.FormEntries > 0)\n            {\n                int formOffsetTable = CaesarCFFHeader.unk2RelativeOffset + formEntryTable;\n                int formOffsetTableSize = CaesarCFFHeader.FormEntrySize * CaesarCFFHeader.FormEntries;\n                Console.WriteLine($\"after string table block (*.fm) is present: {nameof(formEntryTable)} : 0x{formEntryTable:X}\\n\\n\");\n                Console.WriteLine($\"{nameof(formOffsetTable)} : 0x{formOffsetTable:X}\\n\\n\");\n                Console.WriteLine($\"{nameof(formOffsetTableSize)} : 0x{formOffsetTableSize:X}\\n\\n\");\n            }\n            */\n        }\n\n        public string GetFileSize() \n        {\n            return BytesToString(FileBytes.Length);\n        }\n\n        private static string BytesToString(long byteCount)\n        {\n            string[] suf = { \" B\", \" KB\", \" MB\", \" GB\", \" TB\", \" PB\", \" EB\" }; //Longs run out around EB\n            if (byteCount == 0)\n            {\n                return \"0\" + suf[0];\n            }\n            long bytes = Math.Abs(byteCount);\n            int place = Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024)));\n            double num = Math.Round(bytes / Math.Pow(1024, place), 3);\n            return (Math.Sign(byteCount) * num).ToString() + suf[place];\n        }\n\n        public override bool Equals(object obj)\n        {\n            var container = obj as CaesarContainer;\n\n            if (container == null) \n            {\n                return false;\n            }\n            return this.FileChecksum == container.FileChecksum;\n        }\n\n        public override int GetHashCode()\n        {\n            return (int)FileChecksum;\n        }\n\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/CaesarReader.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Caesar\n{\n    public class CaesarReader\n    {\n        public static Encoding DefaultEncoding = Encoding.UTF8;\n\n        // slightly more complex because it jumps to the string position for reading\n        public static string ReadBitflagStringWithReader(ref ulong bitFlags, BinaryReader reader, long virtualBase = 0)\n        {\n            if (CheckAndAdvanceBitflag(ref bitFlags))\n            {\n                // read the string's offset relative to our current block\n                int stringOffset = reader.ReadInt32();\n                // save our reading cursor\n                long readerPosition = reader.BaseStream.Position;\n                // seek to the specified offset, then read out the string\n                reader.BaseStream.Seek(stringOffset + virtualBase, SeekOrigin.Begin);\n                string result = ReadStringFromBinaryReader(reader);\n                // restore our reading cursor\n                reader.BaseStream.Seek(readerPosition, SeekOrigin.Begin);\n                return result;\n            }\n            else\n            {\n                // Console.WriteLine(\"Bitflag was off for string\");\n                return \"(flag disabled)\";\n            }\n        }\n        public static byte[] ReadBitflagDumpWithReader(ref ulong bitFlags, BinaryReader reader, int dumpSize, long virtualBase = 0)\n        {\n            if (CheckAndAdvanceBitflag(ref bitFlags))\n            {\n                // read the dump's offset relative to our current block\n                int dumpOffset = reader.ReadInt32();\n                // save our reading cursor\n                long readerPosition = reader.BaseStream.Position;\n                // seek to the specified offset, then read out the dump\n                reader.BaseStream.Seek(dumpOffset + virtualBase, SeekOrigin.Begin);\n                byte[] result = reader.ReadBytes(dumpSize);\n                // restore our reading cursor\n                reader.BaseStream.Seek(readerPosition, SeekOrigin.Begin);\n                return result;\n            }\n            else\n            {\n                return new byte[] { };\n            }\n        }\n\n        public static string ReadBitflagDumpWithReaderAsString(ref ulong bitFlags, BinaryReader reader, int dumpSize, long virtualBase = 0)\n        {\n            byte[] stringBytes = ReadBitflagDumpWithReader(ref bitFlags, reader, dumpSize, virtualBase);\n            return DefaultEncoding.GetString(stringBytes); // lazy: no encoding is specified\n        }\n\n        public static string ReadStringFromBinaryReader(BinaryReader reader, Encoding encoding = null)\n        {\n            if (encoding is null) \n            {\n                encoding = DefaultEncoding;\n            }\n\n            // slightly better performance than the original below at the expense of compiling with unsafe\n            long stringStartPosition = reader.BaseStream.Position;\n            byte[] underlyingBuffer = ((MemoryStream)reader.BaseStream).GetBuffer();\n            long cursor = stringStartPosition;\n            while (underlyingBuffer[cursor++] != 0) \n            {\n            }\n            int difference = (int)(cursor - stringStartPosition) - 1;\n            byte[] stringBytes = new byte[difference];\n            Buffer.BlockCopy(underlyingBuffer, (int)stringStartPosition, stringBytes, 0, difference);\n            return encoding.GetString(stringBytes);\n\n            /*\n            // significant performance bottleneck: (original)\n            // read out a string, stopping at the first null terminator\n            using (BinaryWriter writer = new BinaryWriter(new MemoryStream()))\n            {\n                while (true)\n                {\n                    byte nextByte = reader.ReadByte();\n                    if (nextByte == 0)\n                    {\n                        byte[] stringRaw = ((MemoryStream)writer.BaseStream).ToArray();\n                        return encoding.GetString(stringRaw);\n                    }\n                    else\n                    {\n                        writer.Write(nextByte);\n                    }\n                }\n            }\n            */\n        }\n\n        public static bool CheckAndAdvanceBitflag(ref ulong bitFlag)\n        {\n            bool flagIsSet = (bitFlag & 1) > 0;\n            bitFlag >>= 1;\n            return flagIsSet;\n        }\n\n        public static byte[] ReadBitflagRawBytes(ref ulong bitFlags, BinaryReader reader, int bytes) {\n            if (CheckAndAdvanceBitflag(ref bitFlags)) {\n                return reader.ReadBytes(bytes);\n            }\n            return new byte[] { };\n        }\n        public static float ReadBitflagFloat(ref ulong bitFlags, BinaryReader reader, float defaultResult = 0)\n        {\n            if (CheckAndAdvanceBitflag(ref bitFlags))\n            {\n                byte[] floatBytes = reader.ReadBytes(4);\n                return BitConverter.ToSingle(floatBytes, 0);\n            }\n            return defaultResult;\n        }\n        public static int ReadBitflagInt32(ref ulong bitFlags, BinaryReader reader, int defaultResult = 0)\n        {\n            if (CheckAndAdvanceBitflag(ref bitFlags))\n            {\n                return reader.ReadInt32();\n            }\n            return defaultResult;\n        }\n        public static uint ReadBitflagUInt32(ref ulong bitFlags, BinaryReader reader, uint defaultResult = 0)\n        {\n            if (CheckAndAdvanceBitflag(ref bitFlags))\n            {\n                return reader.ReadUInt32();\n            }\n            return defaultResult;\n        }\n        public static short ReadBitflagInt16(ref ulong bitFlags, BinaryReader reader, short defaultResult = 0)\n        {\n            if (CheckAndAdvanceBitflag(ref bitFlags))\n            {\n                return reader.ReadInt16();\n            }\n            return defaultResult;\n        }\n        public static ushort ReadBitflagUInt16(ref ulong bitFlags, BinaryReader reader, ushort defaultResult = 0)\n        {\n            if (CheckAndAdvanceBitflag(ref bitFlags))\n            {\n                return reader.ReadUInt16();\n            }\n            return defaultResult;\n        }\n        public static int ReadBitflagInt8(ref ulong bitFlags, BinaryReader reader, int defaultResult = 0)\n        {\n            if (CheckAndAdvanceBitflag(ref bitFlags))\n            {\n                return reader.ReadChar();\n            }\n            return defaultResult;\n        }\n        public static byte ReadBitflagUInt8(ref ulong bitFlags, BinaryReader reader, byte defaultResult = 0)\n        {\n            if (CheckAndAdvanceBitflag(ref bitFlags))\n            {\n                return reader.ReadByte();\n            }\n            return defaultResult;\n        }\n\n        public static int ReadIntWithSize(BinaryReader reader, int size, long offset)\n        {\n            reader.BaseStream.Seek(offset, SeekOrigin.Begin);\n            if (size == 1)\n            {\n                return reader.ReadChar();\n            }\n            else if (size == 2)\n            {\n                return reader.ReadInt16();\n            }\n            else if (size == 4)\n            {\n                return reader.ReadInt32();\n            }\n            else\n            {\n                throw new NotImplementedException($\"Requested an unknown integer size to read: {size}\");\n            }\n        }\n        public static uint ReadUIntWithSize(BinaryReader reader, int size, long offset)\n        {\n            reader.BaseStream.Seek(offset, SeekOrigin.Begin);\n            if (size == 1)\n            {\n                return reader.ReadByte();\n            }\n            else if (size == 2)\n            {\n                return reader.ReadUInt16();\n            }\n            else if (size == 4)\n            {\n                return reader.ReadUInt32();\n            }\n            else\n            {\n                throw new NotImplementedException($\"Requested an unknown integer size to read: {size}\");\n            }\n        }\n\n        private static uint[] CrcTable = { \n            0x00000000, 0x77073096, 0x0EE0E612C, 0x990951BA, 0x76DC419, 0x706AF48F, 0x0E963A535, 0x9E6495A3, \n            0x0EDB8832, 0x79DCB8A4, 0x0E0D5E91E, 0x97D2D988, 0x9B64C2B, 0x7EB17CBD, 0x0E7B82D07, 0x90BF1D91, \n            0x1DB71064, 0x6AB020F2, 0x0F3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0x0F4D4B551, 0x83D385C7, \n            0x136C9856, 0x646BA8C0, 0x0FD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0x0FA0F3D63, 0x8D080DF5, \n            0x3B6E20C8, 0x4C69105E, 0x0D56041E4, 0x0A2677172, 0x3C03E4D1, 0x4B04D447, 0x0D20D85FD, 0x0A50AB56B, \n            0x35B5A8FA, 0x42B2986C, 0x0DBBBC9D6, 0x0ACBCF940, 0x32D86CE3, 0x45DF5C75, 0x0DCD60DCF, 0x0ABD13D59, \n            0x26D930AC, 0x51DE003A, 0x0C8D75180, 0x0BFD06116, 0x21B4F4B5, 0x56B3C423, 0x0CFBA9599, 0x0B8BDA50F, \n            0x2802B89E, 0x5F058808, 0x0C60CD9B2, 0x0B10BE924, 0x2F6F7C87, 0x58684C11, 0x0C1611DAB, 0x0B6662D3D, \n            0x76DC4190, 0x1DB7106, 0x98D220BC, 0x0EFD5102A, 0x71B18589, 0x6B6B51F, 0x9FBFE4A5, 0x0E8B8D433, \n            0x7807C9A2, 0x0F00F934, 0x9609A88E, 0x0E10E9818, 0x7F6A0DBB, 0x86D3D2D, 0x91646C97, 0x0E6635C01, \n            0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0x0F262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0x0F50FC457, \n            0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0x0FCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0x0FBD44C65, \n            0x4DB26158, 0x3AB551CE, 0x0A3BC0074, 0x0D4BB30E2, 0x4ADFA541, 0x3DD895D7, 0x0A4D1C46D, 0x0D3D6F4FB, \n            0x4369E96A, 0x346ED9FC, 0x0AD678846, 0x0DA60B8D0, 0x44042D73, 0x33031DE5, 0x0AA0A4C5F, 0x0DD0D7CC9, \n            0x5005713C, 0x270241AA, 0x0BE0B1010, 0x0C90C2086, 0x5768B525, 0x206F85B3, 0x0B966D409, 0x0CE61E49F, \n            0x5EDEF90E, 0x29D9C998, 0x0B0D09822, 0x0C7D7A8B4, 0x59B33D17, 0x2EB40D81, 0x0B7BD5C3B, 0x0C0BA6CAD, \n            0x0EDB88320, 0x9ABFB3B6, 0x3B6E20C, 0x74B1D29A, 0x0EAD54739, 0x9DD277AF, 0x4DB2615, 0x73DC1683, \n            0x0E3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0x0E40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, \n            0x0F00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0x0F762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, \n            0x0FED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0x0F9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, \n            0x0D6D6A3E8, 0x0A1D1937E, 0x38D8C2C4, 0x4FDFF252, 0x0D1BB67F1, 0x0A6BC5767, 0x3FB506DD, 0x48B2364B, \n            0x0D80D2BDA, 0x0AF0A1B4C, 0x36034AF6, 0x41047A60, 0x0DF60EFC3, 0x0A867DF55, 0x316E8EEF, 0x4669BE79, \n            0x0CB61B38C, 0x0BC66831A, 0x256FD2A0, 0x5268E236, 0x0CC0C7795, 0x0BB0B4703, 0x220216B9, 0x5505262F, \n            0x0C5BA3BBE, 0x0B2BD0B28, 0x2BB45A92, 0x5CB36A04, 0x0C2D7FFA7, 0x0B5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, \n            0x9B64C2B0, 0x0EC63F226, 0x756AA39C, 0x26D930A, 0x9C0906A9, 0x0EB0E363F, 0x72076785, 0x5005713, \n            0x95BF4A82, 0x0E2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0x0E5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, \n            0x86D3D2D4, 0x0F1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0x0F6B9265B, 0x6FB077E1, 0x18B74777, \n            0x88085AE6, 0x0FF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0x0F862AE69, 0x616BFFD3, 0x166CCF45, \n            0x0A00AE278, 0x0D70DD2EE, 0x4E048354, 0x3903B3C2, 0x0A7672661, 0x0D06016F7, 0x4969474D, 0x3E6E77DB, \n            0x0AED16A4A, 0x0D9D65ADC, 0x40DF0B66, 0x37D83BF0, 0x0A9BCAE53, 0x0DEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, \n            0x0BDBDF21C, 0x0CABAC28A, 0x53B39330, 0x24B4A3A6, 0x0BAD03605, 0x0CDD70693, 0x54DE5729, 0x23D967BF, \n            0x0B3667A2E, 0x0C4614AB8, 0x5D681B02, 0x2A6F2B94, 0x0B40BBE37, 0x0C30C8EA1, 0x5A05DF1B, 0x2D02EF8D \n        };\n\n        public static UInt32 CrcAccumulate(byte[] inputBuffer, uint currentChecksum = 0, int length = 0) \n        {\n            length = length == 0 ? inputBuffer.Length : length;\n            for (int i = 0; i < length; i++) \n            {\n                uint tableIndex = (currentChecksum ^ inputBuffer[i]) & 0xFF;\n                uint tableValue = CrcTable[tableIndex];\n                // mix in the loaded byte into the crc on the most significant byte\n                currentChecksum >>= 8;\n                currentChecksum &= 0xFFFFFF;\n                currentChecksum ^= tableValue;\n            }\n\n            return currentChecksum;\n        }\n\n        public static uint ComputeFileChecksum(byte[] fileBytes)\n        {\n            // caesar uses a 0x8000 block size\n            // const int blockSize = 0x8000;\n            const int blockSize = int.MaxValue;\n\n            // skip the appended checksum\n            fileBytes = fileBytes.Take(fileBytes.Length - 4).ToArray();\n\n            int fileCursor = 0;\n            uint currentChecksum = 0xFFFFFFFF;\n            while (fileCursor < fileBytes.Length)\n            {\n                byte[] blockToRead = fileBytes.Skip(fileCursor).Take(blockSize).ToArray();\n                fileCursor += blockSize;\n                currentChecksum = CaesarReader.CrcAccumulate(blockToRead, currentChecksum);\n            }\n            return currentChecksum;\n        }\n        public static uint ComputeFileChecksumLazy(byte[] fileBytes)\n        {\n            return CaesarReader.CrcAccumulate(fileBytes, 0xFFFFFFFF, fileBytes.Length - 4);\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/CaesarStructure.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Caesar\n{\n    class CaesarStructure\n    {\n        // offsets\n        public enum StructureName\n        {\n            CBFHEADER = 0,\n            UNK1 = 1,\n            UNK2 = 2,\n            UNK3 = 3,\n            UNK4 = 4,\n            PRESENTATION_STRUCTURE = 0x5,\n            UNK6 = 6,\n            UNK7 = 7,\n            UNK8 = 8,\n            UNK9 = 9,\n            UNK10 = 0xA,\n            SCALEINTERVAL_STRUCTURE = 0xB,\n            UNK12 = 0xC,\n            UNK13 = 0xD,\n            UNK14 = 0xE,\n            UNK15 = 0xF,\n            FLASH_DESCRIPTION_HEADER = 0x10,\n            FLASH_TABLE_STRUCTURE = 0x11,\n            UNK18 = 0x12,\n            UNK19 = 0x13,\n            SESSION_TABLE_STRUCTURE = 0x14,\n            UNK21 = 0x15,\n            DATA_BLOCK_TABLE_STRUCTURE = 0x16,\n            UNK23 = 0x17,\n            UNK24 = 0x18,\n            UNK25 = 0x19,\n            UNK26 = 0x1A,\n            SEGMENT_TABLE_STRUCTURE = 0x1B,\n            UNK28 = 0x1C,\n            CTFHEADER = 0x1D,\n            LANGUAGE_TABLE = 0x1E,\n            CCFHEADER = 0x1F,\n            UNK32 = 0x20,\n            CCFFRAGMENT = 0x21,\n            UNK34 = 0x22,\n            UNK35 = 0x23,\n            UNK36 = 0x24,\n        }\n\n        /*\n        raw values from ida:\n        [\n\t        [2,4,4,4,4,4,4,4,4,4,4,4,4],\n\t        [4,4,4,2,2,4,4,4,4,4,2,2,2,4,4,4,4,4,4,4,4,4,4,1,1,2,1],\n\t        [6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2],\n\t        [6,4,4,2,4,4,4,4,4,4,4,4,4,2,4,4,4,4,4,4,2,2,4,4,2,1,4,4,4,4,4,4],\n\t        [4,4,4,4,4,4,4,2,2,2,2,1,1,1,1,1,5,1,1,1,1,4,4,4,4,4],\n\t        [6,4,4,4,4,4,4,4,4,4,4,4,4,2,2,2,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,4,4,4,2,4,4,4],\n\t        [2,4,4,2,4,4,4,4,4,4,4,4,4],\n\t        [2,4,4,4,4,2,4,2,4],\n\t        [2,4,4,4,4,4,4,4,4,4,4,2],\n\t        [2,4,4,4,4,4,4,4,4],\n\t        [2,4,4,4],\n\t        [2,4,4,4,4,4,4,4,4,4,4,4],\n\t        [2,4,4,4,1,1],\n\t        [2,4,2,2,2,4,2,2,4,4,4],\n\t        [2,4,4,4,4,4,4,4,4,1,1],\n\t        [6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1],\n\t        [4,4,4,4,4,4,4,4,4,4,4,4,4],\n\t        [2,4,4,4,4,4,4,4,4,4,4,4,4,4],\n\t        [2,4,4,4,4,4,4,4,4,4,4,4,4,4],\n\t        [2,4,4,4,4],\n\t        [2,4,4,4,4,4,4,4,4,4,2],\n\t        [2,4,4,4,4,4],\n\t        [6,4,4,4,4,4,4,4,4,4,4,4,2,4,4,4,4,4,4,4,4,4,4,4,4,4],\n\t        [2,4,4,4,4],\n\t        [2,4,4,4,4,4,4],\n\t        [2,4,4],\n\t        [2,2,4,4,2,4,4,2,4,4,2,4,4],\n\t        [2,4,4,4,4,4,4,4],\n\t        [2,4,4],\n\t        [2,4,4,2,4,4,4,4,4],\n\t        [2,4,2,4,4,4],\n\t        [6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,2],\n\t        [6,4,4,4,4,4,4,4,4,4,4,4,4],\n\t        [2,4,4,4,4,4,2,4],\n\t        [2,4,4,4,4,4,2,4],\n\t        [2,4,4,4,4,4,4,2,4],\n\t        [2,2,2,2,2,2,2,2,4,4,0,0,0]\n        ]\n         */\n        public static List<byte[]> CaesarTypes = new List<byte[]>();\n\n        public static void GetOffset(StructureName name, int memberIndex) \n        {\n            FillCaesarTypes();\n        }\n\n        public static byte[] GetCaesarLayout(StructureName name) \n        {\n            FillCaesarTypes();\n            return CaesarTypes[(int)name];\n        }\n\n        public static void FillCaesarTypes() \n        {\n            if (CaesarTypes.Count != 0) \n            {\n                return;\n            }\n            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }); // CBFHEADER\n            CaesarTypes.Add(new byte[] { 4, 4, 4, 2, 2, 4, 4, 4, 4, 4, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 2, 1 }); // UNK1\n            CaesarTypes.Add(new byte[] { 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2 }); // UNK2\n            CaesarTypes.Add(new byte[] { 6, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 2, 2, 4, 4, 2, 1, 4, 4, 4, 4, 4, 4 }); // UNK3\n            CaesarTypes.Add(new byte[] { 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1, 5, 1, 1, 1, 1, 4, 4, 4, 4, 4 }); // UNK4\n            CaesarTypes.Add(new byte[] { 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 4, 4, 4, 2, 4, 4, 4 }); // PRESENTATION_STRUCTURE\n            CaesarTypes.Add(new byte[] { 2, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4 }); // UNK6\n            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 2, 4, 2, 4 }); // UNK7\n            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2 }); // UNK8\n            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 4, 4, 4 }); // UNK9\n            CaesarTypes.Add(new byte[] { 2, 4, 4, 4 }); // UNK10\n            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }); // SCALEINTERVAL_STRUCTURE\n            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 1, 1 }); // UNK12\n            CaesarTypes.Add(new byte[] { 2, 4, 2, 2, 2, 4, 2, 2, 4, 4, 4 }); // UNK13\n            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1 }); // UNK14\n            CaesarTypes.Add(new byte[] { 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1 }); // 0xF : FlashHeader : FLASH_DESCRIPTION_HEADER\n\n            CaesarTypes.Add(new byte[] { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }); // 0x10 : FLASH_DESCRIPTION_HEADER\n            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }); // \n            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }); // UNK18\n            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4 }); // UNK19\n            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2 }); // SESSION_TABLE_STRUCTURE\n            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4 }); // UNK21\n            CaesarTypes.Add(new byte[] { 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }); // DATA_BLOCK_TABLE_STRUCTURE\n            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4 }); // UNK23\n            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 4 }); // UNK24\n            CaesarTypes.Add(new byte[] { 2, 4, 4 }); // UNK25\n            CaesarTypes.Add(new byte[] { 2, 2, 4, 4, 2, 4, 4, 2, 4, 4, 2, 4, 4 }); // UNK26\n            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 4, 4 }); // SEGMENT_TABLE_STRUCTURE\n            CaesarTypes.Add(new byte[] { 2, 4, 4 }); // UNK28\n            CaesarTypes.Add(new byte[] { 2, 4, 4, 2, 4, 4, 4, 4, 4 }); // CTFHEADER\n            CaesarTypes.Add(new byte[] { 2, 4, 2, 4, 4, 4 }); // LANGUAGE_TABLE\n            CaesarTypes.Add(new byte[] { 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2 }); // CCFHEADER\n            CaesarTypes.Add(new byte[] { 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }); // UNK32\n            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 2, 4 }); // CCFFRAGMENT\n            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 2, 4 }); // UNK34\n            CaesarTypes.Add(new byte[] { 2, 4, 4, 4, 4, 4, 4, 2, 4 }); // UNK35\n            CaesarTypes.Add(new byte[] { 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 0, 0, 0 }); // UNK36\n        }\n\n        // this is an artifact from implementing the reverse-engineered code as-is; since Caesar loads all objects in a greedy strategy (for serialization), \n        // use of ReadCBFWithOffset should be discontinued\n        public static int ReadCBFWithOffset(int memberIndex, StructureName structureName, byte[] input)\n        {\n            int byteOffset = CaesarStructure.GetCBFOffset(memberIndex, structureName, input);\n            using (BinaryReader reader = new BinaryReader(new MemoryStream(input)))\n            {\n                byte[] layout = CaesarStructure.GetCaesarLayout(structureName);\n                return CaesarReader.ReadIntWithSize(reader, layout[memberIndex], byteOffset);\n            }\n        }\n        public static uint ReadCBFWithOffsetUnsigned(int memberIndex, StructureName structureName, byte[] input)\n        {\n            int byteOffset = CaesarStructure.GetCBFOffset(memberIndex, structureName, input);\n            using (BinaryReader reader = new BinaryReader(new MemoryStream(input)))\n            {\n                byte[] layout = CaesarStructure.GetCaesarLayout(structureName);\n                return CaesarReader.ReadUIntWithSize(reader, layout[memberIndex], byteOffset);\n            }\n        }\n\n        public static int GetCBFOffset(int memberIndex, StructureName structureName, byte[] cbfInput)\n        {\n            // test:\n            // byte[] cbfInput = new byte[] { 0x03, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x63, 0x54, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x50, 0x52, 0x45, 0x50, 0x5F, 0x55, 0x6E, 0x73, 0x69, 0x67, 0x6E, 0x65, 0x64, 0x5F, 0x31, 0x42, 0x79, 0x74, 0x65, 0x00 };\n            // int member_type = 0x1C; \n            // CaesarStructure.StructureName.PRESENTATION_STRUCTURE\n            // result =  0x13\n\n            // essentially checks if a bitflag is active, then returns the byte offset to the member\n\n            byte[] structureLayout = GetCaesarLayout(structureName);\n\n            byte bitmask = 1;\n            int arrayOffset = structureLayout[0]; // first structure element is always a static offset, to skip past the bitflags\n            int cbfOffset = 0;\n\n            for (int i = 1; i < memberIndex; ++i)\n            {\n                bool bitflagIsEnabled = (bitmask & cbfInput[cbfOffset]) > 0;\n                if (bitflagIsEnabled)\n                {\n                    if (memberIndex != i)\n                    {\n                        arrayOffset += structureLayout[i];\n                    }\n                }\n                else if ((memberIndex == i) && !bitflagIsEnabled)\n                {\n                    // found the requested member, but the member is marked as absent in the bitflag, so there is no value\n                    arrayOffset = 0;\n                }\n\n                // move on to the next bit, and if our bitflag is fully read, move to the next bitflag\n                if (bitmask == 0x80)\n                {\n                    ++cbfOffset;\n                    bitmask = 1;\n                }\n                else\n                {\n                    bitmask *= 2;\n                }\n            }\n            return arrayOffset;\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/ComParameter.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.IO;\n\nnamespace Caesar\n{\n    public class ComParameter\n    {\n        public int ComParamIndex;\n        // this takes precedence over SubinterfaceIndex for KW2C3PE\n        public int ParentInterfaceIndex;\n        public int SubinterfaceIndex;\n        public int Unk5;\n        public int Unk_CTF;\n        public int Phrase;\n        private int DumpSize;\n        public byte[] Dump;\n       \n        public int ComParamValue;\n        public string ParamName = \"\";\n\n        private long BaseAddress;\n        CTFLanguage Language;\n\n        public void Restore(CTFLanguage language) \n        {\n            Language = language;\n        }\n\n        public ComParameter() { }\n\n        // looks exactly like the definition in DIOpenDiagService (#T)\n        public ComParameter(BinaryReader reader, long baseAddress, List<ECUInterface> parentEcuInterfaceList, CTFLanguage language) \n        {\n            BaseAddress = baseAddress;\n            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);\n            ulong bitflags = reader.ReadUInt16();\n\n            ComParamIndex = CaesarReader.ReadBitflagInt16(ref bitflags, reader);\n            ParentInterfaceIndex = CaesarReader.ReadBitflagInt16(ref bitflags, reader);\n            SubinterfaceIndex = CaesarReader.ReadBitflagInt16(ref bitflags, reader, 0);\n            Unk5 = CaesarReader.ReadBitflagInt16(ref bitflags, reader);\n            Unk_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader); // no -1? ctf strings should have -1\n            Phrase = CaesarReader.ReadBitflagInt16(ref bitflags, reader);\n            DumpSize = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            Dump = CaesarReader.ReadBitflagDumpWithReader(ref bitflags, reader, DumpSize, baseAddress);\n            ComParamValue = 0;\n            if (DumpSize == 4) \n            {\n                ComParamValue = BitConverter.ToInt32(Dump, 0);\n            }\n\n\n            ECUInterface parentEcuInterface = parentEcuInterfaceList[ParentInterfaceIndex];\n\n            if (ComParamIndex >= parentEcuInterface.ComParameterNames.Count)\n            {\n                // throw new Exception(\"Invalid communication parameter : parent interface has no matching key\");\n                ParamName = \"CP_UNKNOWN_MISSING_KEY\";\n                Console.WriteLine($\"Warning: Tried to load a communication parameter without a parent (value: {ComParamValue}), parent: {parentEcuInterface.Qualifier}.\");\n            }\n            else\n            {\n                ParamName = parentEcuInterface.ComParameterNames[ComParamIndex];\n            }\n        }\n\n        public void PrintDebug() \n        {\n            Console.WriteLine($\"ComParam: id {ComParamIndex} ({ParamName}), v {ComParamValue} 0x{ComParamValue:X8} SI_Index:{SubinterfaceIndex} | parentIndex:{ParentInterfaceIndex} 5:{Unk5} DumpSize:{DumpSize} D: {BitUtility.BytesToHex(Dump)}\");\n            Console.WriteLine($\"Pos 0x{BaseAddress:X}\");\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/DSCContext.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\n\nnamespace Caesar\n{\n    public class DSCContext\n    {\n        public DSCContext(byte[] dscContainerBytes) \n        {\n            const int fnTableEntrySize = 50;\n            using (BinaryReader reader = new BinaryReader(new MemoryStream(dscContainerBytes, 0, dscContainerBytes.Length, true, true)))\n            {\n                reader.BaseStream.Seek(0x10, SeekOrigin.Begin);\n                int fnTableOffset = reader.ReadInt32(); // @ 0x10, originally i16\n                int numberOfFunctions = reader.ReadInt16(); // @ 0x14\n                int dscOffsetA = reader.ReadInt32(); // @ 0x16, originally i16\n                int caesarHash = reader.ReadInt16(); // @ 0x1A, size is u32?\n\n                int idk_field_1c = reader.ReadInt16(); // ?? @ 1C, padding\n\n                int globalVarAllocSize = reader.ReadInt16(); // @ 1E\n\n                int idk_field_20 = reader.ReadInt16(); // ?? @ 20, padding\n                int globalVariablesBufferPtr = reader.ReadInt32(); // ?? @ 22\n                int globalVariablesCount = reader.ReadInt16(); // ?? @ 26\n\n                int globalVariablesIdk1 = reader.ReadInt32(); // ?? @ 28\n                int globalVariablesIdk2 = reader.ReadInt16(); // ?? @ 2C\n\n                int globalVariablesPreinitBufferPtr = reader.ReadInt32(); // ?? @ 2E\n                int globalVariablesBytesToRead = reader.ReadInt16(); // ?? @ 32\n\n                byte[] globalVarByteBuffer = new byte[globalVarAllocSize];\n\n                Console.WriteLine($\"{nameof(dscOffsetA)} : {dscOffsetA} (0x{dscOffsetA:X})\\n\");\n                Console.WriteLine($\"{nameof(caesarHash)} : {caesarHash} (0x{caesarHash:X})\\n\");\n                Console.WriteLine($\"{nameof(globalVarAllocSize)} : {globalVarAllocSize} (0x{globalVarAllocSize:X})\\n\");\n\n                Console.WriteLine($\"{nameof(globalVariablesBufferPtr)} : {globalVariablesBufferPtr} (0x{globalVariablesBufferPtr:X})\");\n                Console.WriteLine($\"{nameof(globalVariablesCount)} : {globalVariablesCount} (0x{globalVariablesCount:X})\\n\");\n\n                Console.WriteLine($\"{nameof(globalVariablesIdk1)} : {globalVariablesIdk1} (0x{globalVariablesIdk1:X})\");\n                Console.WriteLine($\"{nameof(globalVariablesIdk2)} : {globalVariablesIdk2} (0x{globalVariablesIdk2:X})\\n\");\n\n                Console.WriteLine($\"{nameof(globalVariablesPreinitBufferPtr)} : {globalVariablesPreinitBufferPtr} (0x{globalVariablesPreinitBufferPtr:X})\");\n                Console.WriteLine($\"{nameof(globalVariablesBytesToRead)} : {globalVariablesBytesToRead} (0x{globalVariablesBytesToRead:X})\\n\");\n\n                // assemble global vars: MIGlobalVarBuild (parent: MIInterpreterRun)\n                int gvBytesRemaining = globalVariablesBytesToRead;\n                reader.BaseStream.Seek(globalVariablesPreinitBufferPtr, SeekOrigin.Begin);\n                while (gvBytesRemaining > 0)\n                {\n                    int gvAddress = reader.ReadInt16();\n                    int gvSize = reader.ReadByte();\n                    byte[] gvData = reader.ReadBytes(gvSize);\n                    Console.WriteLine($\"GV Fill: 0x{gvAddress:X} ({gvSize} bytes) : {BitUtility.BytesToHex(gvData)}\");\n                    Buffer.BlockCopy(gvData, 0, globalVarByteBuffer, gvAddress, gvSize);\n\n                    gvBytesRemaining -= gvSize;\n                    gvBytesRemaining -= 3;\n                }\n\n                if (gvBytesRemaining != 0) \n                {\n                    throw new Exception(\"Global variable preinit has leftover data in the read cursor\");\n                }\n\n                // CreateGlobalVar\n                for (int gvIndex = 0; gvIndex < globalVariablesCount; gvIndex++)\n                {\n                    /*\n                     guesses:\n                    base\n                    1 -> char\n                    2 -> word\n                    3 -> dword\n\n\n                    derived\n                    1 -> native\n                    2 -> array\n                    3 -> pointer\n\n                     */\n                    reader.BaseStream.Seek(globalVariablesBufferPtr + (gvIndex * 12), SeekOrigin.Begin);\n                    int varName = reader.ReadInt32();\n                    DSCBasicType baseType = (DSCBasicType)reader.ReadInt16();\n                    DSCDerivedType derivedType = (DSCDerivedType)reader.ReadInt16();\n                    int arraySize = reader.ReadInt16();\n                    int positionInGlobalBuffer = reader.ReadInt16();\n                    reader.BaseStream.Seek(varName, SeekOrigin.Begin);\n                    string varNameResolved = CaesarReader.ReadStringFromBinaryReader(reader, CaesarReader.DefaultEncoding);\n\n                    int dataSizeInBytes = GetDscTypeSize((int)baseType, (int)derivedType);\n                    if (derivedType == DSCDerivedType.Array) \n                    {\n                        dataSizeInBytes *= arraySize;\n                    }\n                    byte[] varBytes = new byte[dataSizeInBytes];\n                    Buffer.BlockCopy(globalVarByteBuffer, positionInGlobalBuffer, varBytes, 0, dataSizeInBytes);\n\n                    Console.WriteLine($\"\\nVar: {baseType}/{derivedType} [{arraySize}] @ {positionInGlobalBuffer} : {varNameResolved}\");\n                    Console.WriteLine($\"{BitUtility.BytesToHex(varBytes)}\");\n                    // actual insertion into global var list is in MIGlobalVarCallback, stored in interpreter's ->GlobalVarList\n                }\n\n                for (int fnIndex = 0; fnIndex < numberOfFunctions; fnIndex++)\n                {\n                    long fnBaseAddress = fnTableEntrySize * fnIndex + fnTableOffset;\n                    reader.BaseStream.Seek(fnBaseAddress, SeekOrigin.Begin);\n\n                    int fnIdentifier = reader.ReadInt16(); // @ 0\n                    int fnNameOffset = reader.ReadInt32(); // @ 2\n\n                    // not exactly sure if int32 is right -- the first fn's ep looks incorrect in both cases. \n                    // 16 bit would limit the filesize to ~32KB which seems unlikely\n\n                    int fnEntryPoint = reader.ReadInt32(); // @ 6\n                    //int fnEntryPoint = reader.ReadInt16(); // @ 6\n                    //int fnIdkIsThisStandalone = reader.ReadInt16(); // @ 6\n\n                    reader.BaseStream.Seek(fnBaseAddress + 38, SeekOrigin.Begin);\n                    int inputParamOffset = reader.ReadInt32(); // @ 38\n                    int inputParamCount = reader.ReadInt16(); // @ 42\n\n                    int outputParamOffset = reader.ReadInt32(); // @ 44\n                    int outputParamCount = reader.ReadInt16(); // @ 48\n\n                    reader.BaseStream.Seek(fnNameOffset, SeekOrigin.Begin);\n                    string fnName = CaesarReader.ReadStringFromBinaryReader(reader);\n\n                    Console.WriteLine($\"Fn: {fnName} Ordinal: {fnIdentifier} EP: 0x{fnEntryPoint:X}, InParam: {inputParamCount} @ 0x{inputParamOffset:X}, OutParam: {outputParamCount} @ 0x{outputParamOffset}\");\n\n                    // the EP points to an int16 to initialize the stack height\n                    // after the EP, the raw bytecode can be directly interpreted\n                }\n            }\n        }\n\n        public enum DSCBasicType \n        {\n            Undefined,\n            Char,\n            Word,\n            DWord,\n            Unk_1Byte,\n            Unk_2Byte,\n            Unk_4Byte,\n            Unk_4Byte_2,\n        }\n\n        public enum DSCDerivedType \n        {\n            Undefined,\n            Primitive,\n            Array,\n            Pointer, // DWORD PTR\n        }\n\n        public static int GetDscTypeSize(int basicType, int derivedType)\n        {\n            // MISizeofVarDataType\n            int[] typeSizes = new int[] { -1, 1, 2, 4, 1, 2, 4, 4 };\n            // char, word, dword, ??, ??, ??, ??\n\n            if (derivedType == 3)\n            {\n                return 4; // DWORD PTR\n            }\n            else if (derivedType < 3)\n            {\n                if ((basicType > 0) && (basicType < 8))\n                {\n                    return typeSizes[basicType];\n                }\n                else\n                {\n                    throw new Exception(\"Unrecognized DSC Type: basic type is out of bounds\");\n                }\n            }\n            else\n            {\n                throw new Exception(\"Unrecognized DSC Type: derived type is out of bounds\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/DTC.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Caesar\n{\n    public class DTC\n    {\n        public enum DTCStatusByte : uint\n        {\n            TestFailedAtRequestTime = 0x01,\n            TestFailedAtCurrentCycle = 0x02,\n            PendingDTC = 0x04,\n            ConfirmedDTC = 0x08,\n            TestIncompleteSinceLastClear = 0x10,\n            TestFailedSinceLastClear = 0x20,\n            TestIncompleteAtCurrentCycle = 0x40,\n            WarningIndicatorActive = 0x80,\n        }\n\n        // see : const char *__cdecl DIGetComfortErrorCode(DI_ECUINFO *ecuh, unsigned int dtcIndex)\n        public string Qualifier;\n\n        public int Description_CTF;\n        public int Reference_CTF;\n\n        public int XrefStart = -1;\n        public int XrefCount = -1;\n\n        private long BaseAddress;\n        public int PoolIndex;\n\n        [Newtonsoft.Json.JsonIgnore]\n        public ECU ParentECU;\n        [Newtonsoft.Json.JsonIgnore]\n        CTFLanguage Language;\n\n        [Newtonsoft.Json.JsonIgnore]\n        public string Description { get { return Language.GetString(Description_CTF); } }\n\n        public void Restore(CTFLanguage language, ECU parentEcu) \n        {\n            ParentECU = parentEcu;\n            Language = language;\n        }\n\n        public DTC() { }\n\n        public DTC(BinaryReader reader, CTFLanguage language, long baseAddress, int poolIndex, ECU parentEcu)\n        {\n            ParentECU = parentEcu;\n            PoolIndex = poolIndex;\n            BaseAddress = baseAddress;\n            Language = language;\n            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);\n\n            ulong bitflags = reader.ReadUInt16();\n\n            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);\n\n            Description_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);\n            Reference_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);\n#if DEBUG\n            if (bitflags > 0) \n            {\n                Console.WriteLine($\"DTC {Qualifier} has additional unparsed fields : 0x{bitflags:X}\");\n            }\n#endif\n        }\n        /*\n        public string GetDescription() \n        {\n            return Language.GetString(Description_CTF);\n        }\n        */\n        public static DTC FindDTCById(string id, ECUVariant variant)\n        {\n            foreach (DTC dtc in variant.DTCs)\n            {\n                if (dtc.Qualifier.EndsWith(id))\n                {\n                    return dtc;\n                }\n            }\n            return null;\n        }\n        public void PrintDebug() \n        {\n            Console.WriteLine($\"DTC: {Qualifier}: {Language.GetString(Description_CTF)} : {Language.GetString(Reference_CTF)}\");\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/DiagPreparation.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.IO;\n\nnamespace Caesar\n{\n    public class DiagPreparation\n    {\n        public string Qualifier;\n        public int Name_CTF;\n        public int Unk1;\n        public int Unk2;\n        public int AlternativeBitWidth;\n        public int IITOffset;\n        public int InfoPoolIndex;\n        public int PresPoolIndex;\n        public int Field1E;\n        public int SystemParam;\n        public int DumpMode;\n        private int DumpSize;\n        public byte[] Dump;\n\n        public int BitPosition;\n        public ushort ModeConfig;\n        public int SizeInBits = 0;\n\n        private CTFLanguage Language;\n\n        public static readonly byte[] IntegerSizeMapping = new byte[] { 0x00, 0x01, 0x04, 0x08, 0x10, 0x20, 0x40 };\n\n        long BaseAddress;\n        [Newtonsoft.Json.JsonIgnore]\n        public ECU ParentECU;\n        private DiagService ParentDiagService;\n\n        public InferredDataType FieldType;\n\n        public enum InferredDataType \n        {\n            UnassignedType,\n            IntegerType,\n            NativeInfoPoolType,\n            NativePresentationType,\n            UnhandledITType,\n            UnhandledSP17Type,\n            UnhandledType,\n            BitDumpType,\n            ExtendedBitDumpType,\n        }\n\n        public void Restore(CTFLanguage language, ECU parentEcu, DiagService parentDiagService) \n        {\n            Language = language;\n            ParentECU = parentEcu;\n            ParentDiagService = parentDiagService;\n        }\n\n        public DiagPreparation() { }\n\n        // void __cdecl DiagServiceReadPresentation(int *inBase, DECODED_PRESENTATION *outPresentation)\n        // Looks like its actually a presentation\n        // See DIDiagservice* functions\n        public DiagPreparation(BinaryReader reader, CTFLanguage language, long baseAddress, int bitPosition, ushort modeConfig, ECU parentEcu, DiagService parentDiagService)\n        {\n            BitPosition = bitPosition;\n            ModeConfig = modeConfig;\n            Language = language;\n            BaseAddress = baseAddress;\n            ParentECU = parentEcu;\n            ParentDiagService = parentDiagService;\n\n            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);\n            ulong bitflags = reader.ReadUInt32();\n\n\n            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);\n            Name_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);\n            Unk1 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader);\n            Unk2 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader);\n            AlternativeBitWidth = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            IITOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            InfoPoolIndex = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            PresPoolIndex = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            Field1E = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            SystemParam = CaesarReader.ReadBitflagInt16(ref bitflags, reader, -1);\n            DumpMode = CaesarReader.ReadBitflagInt16(ref bitflags, reader);\n            DumpSize = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            if (DumpMode == 5) \n            {\n                // dump is actually a string, use\n                // CaesarReader.ReadBitflagDumpWithReaderAsString\n            }\n            Dump = CaesarReader.ReadBitflagDumpWithReader(ref bitflags, reader, DumpSize, baseAddress);\n\n            SizeInBits = GetSizeInBits(reader);\n            // PrintDebug();\n        }\n\n        // look at.. DIInternalRetrieveConstParamPreparation\n        // \n        public int GetSizeInBits(BinaryReader reader, bool verbose = true) \n        {\n            // if (modeConfig & 0xF00) == 0x300, the value is a const param: DIIsConstParameter\n\n            // VCFragment does the same thing.. with the same ITT exception\n            // BitPosition /= 8\n\n            // look for the string \"nImplType <= 6\"\n            uint modeE = (uint)ModeConfig & 0xF000;\n            uint modeH = (uint)ModeConfig & 0xFF0;\n            uint modeL = (uint)ModeConfig & 0xF;\n            int resultBitSize = 0;\n\n\n            if ((ModeConfig & 0xF00) == 0x300) // this check is made in DIDiagServiceRetrievePreparation\n            {\n                if (modeL > 6)\n                {\n                    throw new Exception(\"nImplType <= 6; trying to map a data type that cannot exist\");\n                }\n\n                // const params : 0x320, 0x330, 0x340\n                if (modeH == 0x320)\n                {\n                    // this behavior is confirmed\n                    resultBitSize = IntegerSizeMapping[modeL];\n                    FieldType = InferredDataType.IntegerType;\n                }\n                else if (modeH == 0x330)\n                {\n                    // this behavior is also okay\n                    resultBitSize = AlternativeBitWidth; // inPres + 20\n                    FieldType = InferredDataType.BitDumpType;\n                }\n                else if (modeH == 0x340)\n                {\n                    // from dasm, but unimplemented\n                    // DIInternalRetrieveConstParamPreparation\n                    FieldType = InferredDataType.UnhandledITType;\n                    throw new NotImplementedException(\"WARNING: valid but unhandled data size (ITT not parsed)\");\n                    // resultBitSize = 0; // inPres + 20\n                }\n            }\n            else \n            {\n                // if systemparam is -1.. load a default system type\n                if (SystemParam == -1)\n                {\n                    // apparently both 0x2000 and 0x8000 source from different pools, but use the same PRESENTATION structure\n                    if (modeE == 0x8000)\n                    {\n                        FieldType = InferredDataType.NativeInfoPoolType;\n                        byte[] poolBytes = ParentECU.ReadECUInfoPool(reader);\n                        using (BinaryReader poolReader = new BinaryReader(new MemoryStream(poolBytes)))\n                        {\n                            DiagPresentation pres = ParentECU.GlobalInternalPresentations[InfoPoolIndex];\n                            /*\n                            // depreciate use of ReadCBFWithOffset\n                            poolReader.BaseStream.Seek(ParentECU.Info_EntrySize * InfoPoolIndex, SeekOrigin.Begin);\n\n                            int presentationStructOffset = poolReader.ReadInt32();\n                            int presentationStructSize = poolReader.ReadInt32();\n\n                            reader.BaseStream.Seek(presentationStructOffset + ParentECU.Info_BlockOffset, SeekOrigin.Begin);\n                            byte[] presentationStruct = reader.ReadBytes(presentationStructSize);\n\n                            int presentationMode = CaesarStructure.ReadCBFWithOffset(0x1C, CaesarStructure.StructureName.PRESENTATION_STRUCTURE, presentationStruct); // PRESS_Type\n                            int presentationLength = CaesarStructure.ReadCBFWithOffset(0x1A, CaesarStructure.StructureName.PRESENTATION_STRUCTURE, presentationStruct); // PRESS_TypeLength\n                            if (presentationLength > 0)\n                            {\n                                resultBitSize = presentationLength;\n                            }\n                            else\n                            {\n                                resultBitSize = CaesarStructure.ReadCBFWithOffset(0x21, CaesarStructure.StructureName.PRESENTATION_STRUCTURE, presentationStruct); // ???\n                            }\n                            */\n                            resultBitSize = pres.TypeLength_1A > 0 ? pres.TypeLength_1A : pres.TypeLengthBytesMaybe_21;\n\n                            // if value was specified in bytes, convert to bits\n                            if (pres.Type_1C == 0)\n                            {\n                                resultBitSize *= 8;\n                            }\n                        }\n                    }\n                    else if (modeE == 0x2000)\n                    {\n                        FieldType = InferredDataType.NativePresentationType;\n                        byte[] presPool = ParentECU.ReadECUPresentationsPool(reader);\n\n                        using (BinaryReader poolReader = new BinaryReader(new MemoryStream(presPool)))\n                        {\n                            DiagPresentation pres = ParentECU.GlobalPresentations[PresPoolIndex];\n                            /*\n                            // depreciate use of ReadCBFWithOffset\n                            poolReader.BaseStream.Seek(ParentECU.Presentations_EntrySize * PresPoolIndex, SeekOrigin.Begin);\n                            int presentationStructOffset = poolReader.ReadInt32();\n                            int presentationStructSize = poolReader.ReadInt32();\n\n                            reader.BaseStream.Seek(presentationStructOffset + ParentECU.Presentations_BlockOffset, SeekOrigin.Begin);\n                            byte[] presentationStruct = reader.ReadBytes(presentationStructSize);\n                            \n                            int presentationMode = CaesarStructure.ReadCBFWithOffset(0x1C, CaesarStructure.StructureName.PRESENTATION_STRUCTURE, presentationStruct); // PRESS_Type\n                            int presentationLength = CaesarStructure.ReadCBFWithOffset(0x1A, CaesarStructure.StructureName.PRESENTATION_STRUCTURE, presentationStruct); // PRESS_TypeLength\n                            \n                            if (presentationLength > 0)\n                            {\n                                resultBitSize = presentationLength;\n                            }\n                            else\n                            {\n                                resultBitSize = CaesarStructure.ReadCBFWithOffset(0x21, CaesarStructure.StructureName.PRESENTATION_STRUCTURE, presentationStruct); // ???\n                            }\n                            */\n\n                            resultBitSize = pres.TypeLength_1A > 0 ? pres.TypeLength_1A : pres.TypeLengthBytesMaybe_21;\n\n                            // if value was specified in bytes, convert to bits\n                            if (pres.Type_1C == 0)\n                            {\n                                resultBitSize *= 8;\n                            }\n                        }\n                    }\n                    else \n                    {\n                        // should throw an exception?\n                        //Console.WriteLine($\"WARNING: Unknown or unhandled type for for {qualifier}\");\n                        throw new Exception($\"Attempted to load an unknown system type for {Qualifier}\");\n                    }\n                }\n                else \n                {\n                    // not a const param, not a native param, this is a special param, parsed at DIInternalRetrieveSpecialPreparation\n                    // DIInternalRetrieveSpecialPreparation officially supports 0x410, 0x420 only\n                    if (modeH == 0x410)\n                    {\n                        int reducedSysParam = SystemParam - 0x10;\n                        if (reducedSysParam == 0)\n                        {\n                            // specifically requests for LOBYTE (& 0xFF)\n                            int resultByteSize = (ParentDiagService.RequestBytes.Length & 0xFF) - (BitPosition / 8);\n                            resultBitSize = resultByteSize * 8;\n                            FieldType = InferredDataType.ExtendedBitDumpType;\n                            // Console.WriteLine($\"0x{modeH:X} debug for {qualifier} (L: {modeL}) (BitWidth: {AlternativeBitWidth} SP: {SystemParam}), sz: {resultBitSize} b ({resultBitSize/8} B)\");\n                        }\n                        else if (reducedSysParam == 17)\n                        {\n                            // open a diagservice based on inputRef name\n                            // this is experimental, haven't seen a cbf that uses this yet\n                            Console.WriteLine($\"Parsing experimental 0x410 prep with sysparam 17 at {Qualifier}\");\n                            DiagService referencedDs = ParentECU.GlobalDiagServices.Find(x => x.Qualifier == ParentDiagService.InputRefNameMaybe);\n                            if (referencedDs != null)\n                            {\n                                bool referencedDsHasRequestData = referencedDs.RequestBytes.Length > 0; // supposed to check if requestMessage is valid too\n                                int internalType = referencedDs.DataClass_ServiceTypeShifted;\n                                if (((referencedDs.DataClass_ServiceTypeShifted & 0xC) > 0) && referencedDsHasRequestData)\n                                {\n                                    if ((referencedDs.DataClass_ServiceTypeShifted & 4) > 0)\n                                    {\n                                        internalType = 0x10000000;\n                                    }\n                                    else\n                                    {\n                                        internalType = 0x20000000;\n                                    }\n                                }\n                                if ((internalType & 0x10000) != 0)\n                                {\n                                    // referenced type is a global variable\n                                    resultBitSize = ParentDiagService.P_Count * 8;\n                                    FieldType = InferredDataType.UnhandledSP17Type;\n                                }\n                                else\n                                {\n                                    // use pres dump length\n                                    FieldType = InferredDataType.UnhandledSP17Type;\n                                    resultBitSize = ParentDiagService.RequestBytes.Length * 8;\n                                }\n                            }\n                            else\n                            {\n                                Console.WriteLine($\"0x410 : sys param: 17 for qualifier {Qualifier} could not find referenced DiagService with index {ParentDiagService.InputRefNameMaybe}\");\n                                // throw new NotImplementedException\n                            }\n                        }\n                        else\n                        {\n                            throw new Exception($\"Invalid system parameter for {Qualifier}\");\n                        }\n                    }\n                    else if (modeH == 0x420)\n                    {\n                        if (modeL > 6)\n                        {\n                            throw new Exception(\"nImplType <= 6; trying to map a data type that cannot exist\");\n                        }\n                        FieldType = InferredDataType.IntegerType;\n                        resultBitSize = IntegerSizeMapping[modeL];\n                    }\n                    else if (modeH == 0x430)\n                    {\n                        // mode 0x430 is nonstandard and doesn't seem to exist in the function that I was disassembling\n                        /*\n                            AlternativeBitWidth : 128\n                            SystemParam : 37\n                            \n                            See 0x320 vs 0x330, seems to be similar\n                        */\n\n                        resultBitSize = AlternativeBitWidth; // inPres + 20\n                        FieldType = InferredDataType.BitDumpType;\n                    }\n                    else\n                    {\n                        FieldType = InferredDataType.UnhandledType;\n                        Console.WriteLine($\"Unhandled type: {modeH} for {Qualifier}\");\n                        PrintDebug();\n                        throw new Exception($\"Attempted to load an unknown special param type for {Qualifier}\");\n                        //Console.WriteLine($\"{qualifier} ({poolThing}/{ParentECU.ecuInfoPool_tableEntryCount})\\n{BitUtility.BytesToHex(presentationStruct)}\\n\\n\");\n                    }\n                }\n            }\n\n\n            /*\n            if (modeH == 0x430)\n            {\n                // guessed\n                if (verbose)\n                {\n                    Console.WriteLine($\"Unsupported 0x{modeH:X} behavior for {qualifier} (L: {modeL}) (BitWidth: {AlternativeBitWidth} ByteWidth: {SystemParam})\");\n                }\n                //PrintDebug();\n                resultBitSize = AlternativeBitWidth; // alternate bit width is 128 which should be a nice 16 bytes\n            }\n            else if (modeH > 0x430)\n            {\n                // guessed from varcoding behavior\n                if ((PresPool == 0) && (AvailableBitWidth_PoolThing == 0))\n                {\n                    return 0;\n                }\n                else\n                {\n                    //Console.WriteLine($\"No idea how to handle Pres 0x750 from {qualifier} : {PresPool}\");\n                }\n                Console.WriteLine($\"No idea how to handle 0x{modeH:X} from {qualifier} ({PresPool}, {AvailableBitWidth_PoolThing})\");\n            }\n            */\n            return resultBitSize;\n        }\n\n        public void PrintDebug()\n        {\n            Console.WriteLine($\"{nameof(Qualifier)} : {Qualifier}\");\n            Console.WriteLine($\"{nameof(BitPosition)} : {BitPosition}\");\n            Console.WriteLine($\"{nameof(ModeConfig)} : 0x{ModeConfig:X}\");\n            Console.WriteLine($\"Mode H : 0x{ModeConfig & 0xFF0:X}, L : 0x{ModeConfig & 0xF:X}\");\n            Console.WriteLine($\"{nameof(SizeInBits)} : 0x{SizeInBits:X}\");\n            Console.WriteLine($\"{nameof(Name_CTF)} : {Name_CTF}\");\n            Console.WriteLine($\"{nameof(Name_CTF)} : {Language.GetString(Name_CTF)}\");\n            Console.WriteLine($\"{nameof(Unk1)} : {Unk1}\");\n            Console.WriteLine($\"{nameof(Unk2)} : {Unk2}\");\n            Console.WriteLine($\"{nameof(AlternativeBitWidth)} : {AlternativeBitWidth}\");\n            Console.WriteLine($\"{nameof(IITOffset)} : {IITOffset}\");\n            Console.WriteLine($\"{nameof(InfoPoolIndex)} : {InfoPoolIndex}\");\n            Console.WriteLine($\"{nameof(PresPoolIndex)} : {PresPoolIndex}\");\n            Console.WriteLine($\"{nameof(Field1E)} : {Field1E}\");\n            Console.WriteLine($\"{nameof(SystemParam)} : {SystemParam}\");\n            // Console.WriteLine($\"{nameof(noIdea_T)} : {language.GetString(noIdea_T)}\");\n            Console.WriteLine($\"{nameof(Dump)} : {BitUtility.BytesToHex(Dump)}\");\n            Console.WriteLine(\"---------------\");\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/DiagPresentation.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.IO;\n\nnamespace Caesar\n{\n    public class DiagPresentation\n    {\n        public string Qualifier;\n        public int Description_CTF;\n        public int ScaleTableOffset;\n        public int ScaleCountMaybe;\n        public int Unk5;\n        public int Unk6;\n        public int Unk7;\n        public int Unk8;\n        public int Unk9;\n        public int UnkA;\n        public int UnkB;\n        public int UnkC;\n        public int UnkD;\n        public int UnkE;\n        public int UnkF;\n        public int DisplayedUnit_CTF;\n        public int Unk11;\n        public int Unk12;\n        public int EnumMaxValue;\n        public int Unk14;\n        public int Unk15;\n        public int Description2_CTF;\n        public int Unk17;\n        public int Unk18;\n        public int Unk19;\n        public int TypeLength_1A;\n        public int InternalDataType; // discovered by @prj : #37\n        public int Type_1C;\n        public int Unk1d;\n        public int SignBit; // discovered by @prj : #37\n        public int ByteOrder; // discovered by @prj : #37 ; Unset = HiLo, 1 = LoHi\n        public int Unk20;\n\n        public int TypeLengthBytesMaybe_21;\n        public int Unk22;\n        public int Unk23;\n        public int Unk24;\n        public int Unk25;\n        public int Unk26;\n        // public string DescriptionString;\n        // public string DisplayedUnitString;\n        // public string DescriptionString2;\n\n        private long BaseAddress;\n        public int PresentationIndex;\n\n\n\n        [Newtonsoft.Json.JsonIgnore]\n        public string DescriptionString { get { return Language.GetString(Description_CTF); } }\n        [Newtonsoft.Json.JsonIgnore]\n        public string DisplayedUnitString { get { return Language.GetString(DisplayedUnit_CTF); } }\n        [Newtonsoft.Json.JsonIgnore]\n        public string DescriptionString2 { get { return Language.GetString(Description2_CTF); } }\n\n        [Newtonsoft.Json.JsonIgnore]\n        public CTFLanguage Language;\n\n        public List<Scale> Scales = new List<Scale>();\n\n        public void Restore(CTFLanguage language) \n        {\n            Language = language;\n            foreach (Scale s in Scales) \n            {\n                s.Restore(language);\n            }\n        }\n\n        public DiagPresentation() { }\n\n        // 0x05 [6,   4,4,4,4,  4,4,4,4,  4,4,4,4,  2,2,2,4,      4,4,4,4,   4,4,4,4,   4,4,1,1,  1,1,1,4,     4,4,2,4,   4,4],\n\n        public DiagPresentation(BinaryReader reader, long baseAddress, int presentationsIndex, CTFLanguage language) \n        {\n            BaseAddress = baseAddress;\n            PresentationIndex = presentationsIndex;\n            Language = language;\n\n            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);\n            ulong bitflags = reader.ReadUInt32();\n            \n            ulong extendedBitflags = reader.ReadUInt16(); // skip 2 bytes\n\n            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, BaseAddress);\n\n            Description_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);\n            ScaleTableOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);\n            ScaleCountMaybe = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            Unk5 = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);\n            Unk6 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            Unk7 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            Unk8 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            Unk9 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            UnkA = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            UnkB = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            UnkC = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            UnkD = CaesarReader.ReadBitflagInt16(ref bitflags, reader);\n            UnkE = CaesarReader.ReadBitflagInt16(ref bitflags, reader);\n            UnkF = CaesarReader.ReadBitflagInt16(ref bitflags, reader);\n            DisplayedUnit_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);\n\n            Unk11 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            Unk12 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            EnumMaxValue = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            Unk14 = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);\n\n            Unk15 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            Description2_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);\n            Unk17 = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);\n            Unk18 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            Unk19 = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);\n            TypeLength_1A = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);\n            InternalDataType = CaesarReader.ReadBitflagInt8(ref bitflags, reader, -1);\n            Type_1C = CaesarReader.ReadBitflagInt8(ref bitflags, reader, -1);\n\n            Unk1d = CaesarReader.ReadBitflagInt8(ref bitflags, reader);\n            SignBit = CaesarReader.ReadBitflagInt8(ref bitflags, reader);\n            ByteOrder = CaesarReader.ReadBitflagInt8(ref bitflags, reader);\n            Unk20 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            bitflags = extendedBitflags;\n\n            TypeLengthBytesMaybe_21 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            Unk22 = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);\n            Unk23 = CaesarReader.ReadBitflagInt16(ref bitflags, reader);\n            Unk24 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            Unk25 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            Unk26 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n\n            long scaleTableBase = BaseAddress + ScaleTableOffset;\n            Scales = new List<Scale>();\n            for (int i = 0; i < ScaleCountMaybe; i++) \n            {\n                reader.BaseStream.Seek(scaleTableBase + (i * 4), SeekOrigin.Begin);\n                int entryRelativeOffset = reader.ReadInt32();\n\n                Scale scale = new Scale(reader, scaleTableBase + entryRelativeOffset, language);\n                Scales.Add(scale);\n            }\n        }\n\n        public string InterpretData(byte[] inBytes, DiagPreparation inPreparation, bool describe = true)\n        {\n            // might be relevant: DMPrepareSingleDatum, DMPresentSingleDatum\n\n            bool isDebugBuild = false;\n#if DEBUG\n            isDebugBuild = true;\n#endif\n\n            string descriptionPrefix = describe ? $\"{DescriptionString}: \" : \"\";\n            byte[] workingBytes = inBytes.Skip(inPreparation.BitPosition / 8).Take(TypeLength_1A).ToArray();\n\n            bool isEnumType = (SignBit == 0) && ((Type_1C == 1) || (ScaleCountMaybe > 1));\n\n            // hack: sometimes hybrid types (regularly parsed as an scaled value if within bounds) are misinterpreted as pure enums\n            // this is a temporary fix for kilometerstand until there's a better way to ascertain its type\n            // this also won't work on other similar cases without a unit string e.g. error instance counter (Häufigkeitszähler)\n            if (DisplayedUnitString == \"km\") \n            {\n                isEnumType = false;\n            }\n\n            if (workingBytes.Length != TypeLength_1A)\n            {\n                return $\"InBytes [{BitUtility.BytesToHex(workingBytes)}] length mismatch (expecting {TypeLength_1A})\";\n            }\n\n            // handle booleans first since they're the edge case where they can cross byte boundaries\n            if (inPreparation.SizeInBits == 1)\n            {\n                int bytesToSkip = (int)(inPreparation.BitPosition / 8);\n                int bitsToSkip = inPreparation.BitPosition % 8;\n                byte selectedByte = inBytes[bytesToSkip];\n\n                int selectedBit = (selectedByte >> bitsToSkip) & 1;\n                if (isEnumType && (Scales.Count > selectedBit))\n                {\n                    return $\"{descriptionPrefix}{Language.GetString(Scales[selectedBit].EnumDescription)} {DisplayedUnitString}\";\n                }\n                else \n                {\n                    return $\"{descriptionPrefix}{selectedBit} {DisplayedUnitString}\";\n                }\n            }\n\n            // everything else should be aligned to byte boundaries\n            if (inPreparation.BitPosition % 8 != 0)\n            {\n                return \"BitOffset was outside byte boundary (skipped)\";\n            }\n            int dataType = GetDataType();\n            int rawIntInterpretation = 0;\n\n            string humanReadableType = $\"UnhandledType:{dataType}\";\n            string parsedValue = BitUtility.BytesToHex(workingBytes, true);\n            if (dataType == 20)\n            {\n                // parse as a regular int (BE)\n                for (int i = 0; i < workingBytes.Length; i++)\n                {\n                    rawIntInterpretation <<= 8;\n                    rawIntInterpretation |= workingBytes[i];\n                }\n\n                humanReadableType = \"IntegerType\";\n\n                parsedValue = rawIntInterpretation.ToString();\n                if (dataType == 20)\n                {\n                    humanReadableType = \"ScaledType\";\n\n                    double valueToScale = rawIntInterpretation;\n\n                    // if there's only one scale, use it as-is\n                    // if there's more than one, use the first scale as an interim solution;\n                    // the results of stacking scales does not make sense\n                    // there might be a better, non-hardcoded (0) solution to this, and perhaps with a sig-fig specifier\n\n                    valueToScale *= Scales[0].MultiplyFactor;\n                    valueToScale += Scales[0].AddConstOffset;\n\n                    parsedValue = valueToScale.ToString(\"0.000000\");\n                }\n            }\n            else if (dataType == 6) \n            {\n                // type 6 refers to either internal presentation types 8 (ieee754 float) or 5 (unsigned int?)\n                // these values are tagged with an exclamation [!] i (jglim) am not sure if they will work correctly yet\n                // specifically, i am not sure if the big endian float parsing is done correctly\n                uint rawUIntInterpretation = 0;\n                for (int i = 0; i < 4; i++)\n                {\n                    rawUIntInterpretation <<= 8;\n                    rawUIntInterpretation |= workingBytes[i];\n                }\n\n                if (InternalDataType == 8)\n                {\n                    // interpret as big-endian float, https://github.com/jglim/CaesarSuite/issues/37\n                    parsedValue = BitUtility.ToFloat(rawUIntInterpretation).ToString(\"\");\n                    humanReadableType = \"Float [!]\";\n                }\n                else if (InternalDataType == 5) \n                {\n                    // haven't seen this one around, will parse as a regular int (BE) for now\n                    humanReadableType = \"UnsignedIntegerType [!]\";\n                    parsedValue = rawUIntInterpretation.ToString();\n                }\n            }\n            else if (dataType == 18)\n            {\n                humanReadableType = \"HexdumpType\";\n            }\n            else if (dataType == 17)\n            {\n                humanReadableType = \"StringType\";\n                parsedValue = Encoding.UTF8.GetString(workingBytes);\n            }\n\n            if (isEnumType)\n            {\n                // discovered by @VladLupashevskyi in https://github.com/jglim/CaesarSuite/issues/27\n                // if an enum is specified, the inclusive upper bound and lower bound will be defined in the scale object\n\n                bool useNewInterpretation = false;\n                foreach (Scale scale in Scales)\n                {\n                    if ((scale.EnumUpBound > 0) || (scale.EnumLowBound > 0))\n                    {\n                        useNewInterpretation = true;\n                        break;\n                    }\n                }\n\n                if (useNewInterpretation)\n                {\n                    foreach (Scale scale in Scales)\n                    {\n                        if ((rawIntInterpretation >= scale.EnumLowBound) && (rawIntInterpretation <= scale.EnumUpBound))\n                        {\n                            return $\"{descriptionPrefix}{Language.GetString(scale.EnumDescription)} {DisplayedUnitString}\";\n                        }\n                    }\n                }\n                else \n                {\n                    // original implementation, probably incorrect\n                    if (rawIntInterpretation < Scales.Count)\n                    {\n                        return $\"{descriptionPrefix}{Language.GetString(Scales[rawIntInterpretation].EnumDescription)} {DisplayedUnitString}\";\n                    }\n                }\n                return $\"{descriptionPrefix}(Enum not found) {DisplayedUnitString}\";\n                // this bit below for troubleshooting problematic presentations\n                /*\n                if (rawIntInterpretation < Scales.Count)\n                {\n                    return $\"{descriptionPrefix}{Language.GetString(Scales[rawIntInterpretation].EnumDescription)} {DisplayedUnitString}\";\n                }\n                else \n                {\n                    // seems like an enum-like value broke\n                    return $\"{descriptionPrefix}{Language.GetString(Scales[0].EnumDescription)} {DisplayedUnitString} [!]\";\n                }\n                */\n            }\n            else\n            {\n                if (isDebugBuild)\n                {\n                    return $\"{descriptionPrefix}{parsedValue} {DisplayedUnitString} ({humanReadableType})\";\n                }\n                else\n                {\n                    return $\"{descriptionPrefix}{parsedValue} {DisplayedUnitString}\";\n                }\n            }\n        }\n\n        public int GetDataType() \n        {\n            // see DIDiagServiceRealPresType\n            int result = -1;\n            if (Unk14 != -1) \n            {\n                return 20;\n            }\n\n            // does the value have scale structures attached to it? \n            // supposed to parse scale struct and check if we can return 20\n            if (ScaleTableOffset != -1)\n            {\n                return 20; // scaled value\n            }\n            else\n            {\n                if (Unk5 != -1)\n                {\n                    return 18; // hexdump raw\n                }\n                if (Unk17 != -1)\n                {\n                    return 18; // hexdump raw\n                }\n                if (Unk19 != -1)\n                {\n                    return 18; // hexdump raw\n                }\n                if (Unk22 != -1)\n                {\n                    return 18; // hexdump raw\n                }\n                if (InternalDataType != -1)\n                {\n                    if (InternalDataType == 6)\n                    {\n                        return 17; // ascii dump\n                    }\n                    else if (InternalDataType == 7)\n                    {\n                        return 22; // ?? haven't seen this one around\n                    }\n                    else if (InternalDataType == 8)\n                    {\n                        result = 6; // IEEE754 float, discovered by @prj in https://github.com/jglim/CaesarSuite/issues/37\n                    }\n                    else if (InternalDataType == 5) \n                    {\n                        // UNSIGNED integer (i haven't seen a const for uint around, sticking it into a regular int for now)\n                        // this will be an issue for 32-bit+ uints\n                        // see DT_STO_Zaehler_Programmierversuche_Reprogramming and DT_STO_ID_Aktive_Diagnose_Information_Version\n                        result = 6; \n                    }\n                }\n                else \n                {\n                    if ((TypeLength_1A == -1) || (Type_1C == -1)) \n                    {\n                        Console.WriteLine(\"typelength and type must be valid\");\n                        // might be good to throw an exception here\n                    }\n                    if ((SignBit == 1) || (SignBit == 2))\n                    {\n                        result = 5; // ?? haven't seen this one around\n                    }\n                    else \n                    {\n                        result = 2; // ?? haven't seen this one around\n                    }\n                }\n                return result;\n            }\n        }\n\n        public void PrintDebug()\n        {\n            Console.WriteLine(\"Presentation: \");\n            Console.WriteLine($\"{nameof(Qualifier)}: {Qualifier}\");\n\n\n            //Console.WriteLine($\"{nameof(Description_CTF)}: {Description_CTF}\");\n            Console.WriteLine($\"{nameof(ScaleTableOffset)}: {ScaleTableOffset}\");\n            Console.WriteLine($\"{nameof(ScaleCountMaybe)}: {ScaleCountMaybe}\");\n\n            Console.WriteLine($\"{nameof(Unk5)}: {Unk5}\");\n            Console.WriteLine($\"{nameof(Unk6)}: {Unk6}\");\n            Console.WriteLine($\"{nameof(Unk7)}: {Unk7}\");\n            Console.WriteLine($\"{nameof(Unk8)}: {Unk8}\");\n\n            Console.WriteLine($\"{nameof(Unk9)}: {Unk9}\");\n            Console.WriteLine($\"{nameof(UnkA)}: {UnkA}\");\n            Console.WriteLine($\"{nameof(UnkB)}: {UnkB}\");\n            Console.WriteLine($\"{nameof(UnkC)}: {UnkC}\");\n\n            Console.WriteLine($\"{nameof(UnkD)}: {UnkD}\");\n            Console.WriteLine($\"{nameof(UnkE)}: {UnkE}\");\n            Console.WriteLine($\"{nameof(UnkF)}: {UnkF}\");\n            //Console.WriteLine($\"{nameof(DisplayedUnit_CTF)}: {DisplayedUnit_CTF}\");\n\n            Console.WriteLine($\"{nameof(Unk11)}: {Unk11}\");\n            Console.WriteLine($\"{nameof(Unk12)}: {Unk12}\");\n            Console.WriteLine($\"{nameof(EnumMaxValue)}: {EnumMaxValue}\");\n            Console.WriteLine($\"{nameof(Unk14)}: {Unk14}\");\n\n            Console.WriteLine($\"{nameof(Unk15)}: {Unk15}\");\n            // Console.WriteLine($\"{nameof(Description2_CTF)}: {Description2_CTF}\");\n            Console.WriteLine($\"{nameof(Unk17)}: {Unk17}\");\n            Console.WriteLine($\"{nameof(Unk18)}: {Unk18}\");\n\n            Console.WriteLine($\"{nameof(Unk19)}: {Unk19}\");\n            Console.WriteLine($\"{nameof(InternalDataType)}: {InternalDataType}\");\n\n            Console.WriteLine($\"{nameof(Unk1d)}: {Unk1d}\");\n            Console.WriteLine($\"{nameof(SignBit)}: {SignBit}\");\n            Console.WriteLine($\"{nameof(ByteOrder)}: {ByteOrder}\");\n            Console.WriteLine($\"{nameof(Unk20)}: {Unk20}\");\n\n            Console.WriteLine($\"{nameof(TypeLengthBytesMaybe_21)}: {TypeLengthBytesMaybe_21}\");\n            Console.WriteLine($\"{nameof(Unk22)}: {Unk22}\");\n            Console.WriteLine($\"{nameof(Unk23)}: {Unk23}\");\n            Console.WriteLine($\"{nameof(Unk24)}: {Unk24}\");\n\n            Console.WriteLine($\"{nameof(Unk25)}: {Unk25}\");\n            Console.WriteLine($\"{nameof(Unk26)}: {Unk26}\");\n            /**/\n\n\n            Console.WriteLine($\"{nameof(DescriptionString)}: {DescriptionString}\");\n            Console.WriteLine($\"{nameof(DisplayedUnitString)}: {DisplayedUnitString}\");\n            Console.WriteLine($\"{nameof(DescriptionString2)}: {DescriptionString2}\");\n            Console.WriteLine($\"Type: {GetDataType()}\");\n            Console.WriteLine($\"{nameof(Type_1C)}: {Type_1C}\");\n            Console.WriteLine($\"{nameof(TypeLength_1A)}: {TypeLength_1A}\");\n            Console.WriteLine($\"ScaleOffset: 0x{(ScaleTableOffset + BaseAddress):X}, base of pres @ 0x{BaseAddress:X}\");\n\n            foreach (Scale s in Scales)\n            {\n                Console.WriteLine(\"Scale: \");\n                s.PrintDebug();\n            }\n\n            Console.WriteLine(\"Presentation end\");\n        }\n\n        public string CopyMinDebug()\n        {\n            StringBuilder sb = new StringBuilder();\n            sb.Append(\"PRES: \");\n            sb.Append($\" {nameof(Unk5)}: {Unk5}\");\n            sb.Append($\" {nameof(Unk6)}: {Unk6}\");\n            sb.Append($\" {nameof(Unk7)}: {Unk7}\");\n            sb.Append($\" {nameof(Unk8)}: {Unk8}\");\n            sb.Append($\" {nameof(Unk9)}: {Unk9}\");\n            sb.Append($\" {nameof(UnkA)}: {UnkA}\");\n            sb.Append($\" {nameof(UnkB)}: {UnkB}\");\n            sb.Append($\" {nameof(UnkC)}: {UnkC}\");\n            sb.Append($\" {nameof(UnkD)}: {UnkD}\");\n            sb.Append($\" {nameof(UnkE)}: {UnkE}\");\n            sb.Append($\" {nameof(UnkF)}: {UnkF}\");\n            sb.Append($\" {nameof(Unk11)}: {Unk11}\");\n            sb.Append($\" {nameof(Unk12)}: {Unk12}\");\n            sb.Append($\" {nameof(EnumMaxValue)}: {EnumMaxValue}\");\n            sb.Append($\" {nameof(Unk14)}: {Unk14}\");\n            sb.Append($\" {nameof(Unk15)}: {Unk15}\");\n            sb.Append($\" {nameof(Unk17)}: {Unk17}\");\n            sb.Append($\" {nameof(Unk18)}: {Unk18}\");\n            sb.Append($\" {nameof(Unk19)}: {Unk19}\");\n            sb.Append($\" {nameof(InternalDataType)}: {InternalDataType}\");\n            sb.Append($\" {nameof(Unk1d)}: {Unk1d}\");\n            sb.Append($\" {nameof(SignBit)}: {SignBit}\");\n            sb.Append($\" {nameof(ByteOrder)}: {ByteOrder}\");\n            sb.Append($\" {nameof(Unk20)}: {Unk20}\");\n            sb.Append($\" {nameof(TypeLengthBytesMaybe_21)}: {TypeLengthBytesMaybe_21}\");\n            sb.Append($\" {nameof(Unk22)}: {Unk22}\");\n            sb.Append($\" {nameof(Unk23)}: {Unk23}\");\n            sb.Append($\" {nameof(Unk24)}: {Unk24}\");\n            sb.Append($\" {nameof(Unk25)}: {Unk25}\");\n            sb.Append($\" {nameof(Unk26)}: {Unk26}\");\n            sb.Append($\" {nameof(BaseAddress)}: 0x{BaseAddress:X8}\");\n            sb.Append($\" {nameof(Type_1C)}: {Type_1C}\");\n            sb.Append($\" {nameof(TypeLength_1A)}: {TypeLength_1A}\");\n            sb.Append($\" Type: {GetDataType()}\");\n            sb.Append($\" {nameof(ScaleTableOffset)}: {ScaleTableOffset}\");\n            sb.Append($\" {nameof(Qualifier)}: {Qualifier}\"); sb.Append($\" {nameof(ScaleCountMaybe)}: {ScaleCountMaybe}\");\n            if (ScaleCountMaybe > 0)\n            {\n                sb.Append($\" {Language.GetString(Scales[0].EnumDescription)}\");\n            }\n            return sb.ToString();\n        }\n\n\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/DiagService.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.IO;\n\nnamespace Caesar\n{\n\n    // DIAGJOB *__cdecl DIOpenDiagService(DI_ECUINFO *ecuHandle, char *serviceName, int ecuErrors)\n    public class DiagService\n    {\n        /*\n    5\tDT\tDATA\n    7\tDL\tDOWNLOAD\n    10\tFN|DNU\tDIAGNOSTIC_U, FN\n    19\tDJ\tDIAGNOSTIC_JOB\n    21\tSES\tSESSION\n    22\tDT_STO\tSTORED DATA\n    23\tRT\tROUTINE\n    24\tIOC\tIO CONTROL\n    26\tWVC\tVARIANTCODING WRITE\n    27\tWVC\tVARIANTCODING READ\n\n         */\n        public enum ServiceType\n        {\n            Data = 5,\n            Download = 7,\n            DiagnosticFunction = 10,\n            DiagnosticJob = 19,\n            Session = 21,\n            StoredData = 22,\n            Routine = 23,\n            IoControl = 24,\n            VariantCodingWrite = 26,\n            VariantCodingRead = 27,\n        }\n\n        public string Qualifier;\n\n        public int Name_CTF;\n        public int Description_CTF;\n\n        public ushort DataClass_ServiceType;\n        public int DataClass_ServiceTypeShifted;\n\n        public ushort IsExecutable;\n        public ushort ClientAccessLevel;\n        public ushort SecurityAccessLevel;\n\n        private int T_ComParam_Count;\n        private int T_ComParam_Offset;\n\n        private int Q_Count;\n        private int Q_Offset;\n\n        private int R_Count;\n        private int R_Offset;\n\n        public string InputRefNameMaybe;\n\n        private int U_prep_Count;\n        private int U_prep_Offset;\n\n        private int V_Count;\n        private int V_Offset;\n\n        private int RequestBytes_Count;\n        private int RequestBytes_Offset;\n\n        private int W_OutPres_Count;\n        private int W_OutPres_Offset;\n\n        public ushort Field50;\n\n        public string NegativeResponseName;\n        public string UnkStr3;\n        public string UnkStr4;\n\n        public int P_Count; // global vars?\n        public int P_Offset;\n\n        private int DiagServiceCodeCount;\n        private int DiagServiceCodeOffset;\n\n        private int S_Count;\n        private int S_Offset;\n\n        private int X_Count;\n        private int X_Offset;\n\n        private int Y_Count;\n        private int Y_Offset;\n\n        private int Z_Count;\n        private int Z_Offset;\n\n        public byte[] RequestBytes;\n\n        private long BaseAddress;\n        public int PoolIndex;\n\n        // these are inlined preparations\n        public List<DiagPreparation> InputPreparations = new List<DiagPreparation>();\n        public List<List<DiagPreparation>> OutputPreparations = new List<List<DiagPreparation>>();\n        public List<ComParameter> DiagComParameters = new List<ComParameter>();\n\n        [Newtonsoft.Json.JsonIgnore]\n        public ECU ParentECU;\n        private CTFLanguage Language;\n\n        public void Restore(CTFLanguage language, ECU parentEcu) \n        {\n            Language = language;\n            ParentECU = parentEcu;\n            foreach (DiagPreparation dp in InputPreparations)\n            {\n                dp.Restore(language, parentEcu, this);\n            }\n            foreach (List<DiagPreparation> dpl in OutputPreparations)\n            {\n                foreach (DiagPreparation dp in dpl)\n                {\n                    dp.Restore(language, parentEcu, this);\n                }\n            }\n            /*\n            // nothing in comparam to restore\n            foreach (ComParameter cp in DiagComParameters) \n            {\n            \n            }\n            */\n        }\n\n        public DiagService() { }\n\n        public DiagService(BinaryReader reader, CTFLanguage language, long baseAddress, int poolIndex, ECU parentEcu) \n        {\n            ParentECU = parentEcu;\n            Language = language;\n            PoolIndex = poolIndex;\n            BaseAddress = baseAddress;\n            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);\n\n            ulong bitflags = reader.ReadUInt32();\n            ulong bitflagExtended = reader.ReadUInt32();\n\n            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);\n\n            Name_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);\n            Description_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);\n\n            DataClass_ServiceType = CaesarReader.ReadBitflagUInt16(ref bitflags, reader);\n            DataClass_ServiceTypeShifted = 1 << (DataClass_ServiceType - 1);\n\n            IsExecutable = CaesarReader.ReadBitflagUInt16(ref bitflags, reader); ;\n            ClientAccessLevel = CaesarReader.ReadBitflagUInt16(ref bitflags, reader); ;\n            SecurityAccessLevel = CaesarReader.ReadBitflagUInt16(ref bitflags, reader); ;\n\n            T_ComParam_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            T_ComParam_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            Q_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            Q_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            R_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            R_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            InputRefNameMaybe = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);\n\n            U_prep_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            U_prep_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            // array of DWORDs, probably reference to elsewhere\n            V_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            V_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            RequestBytes_Count = CaesarReader.ReadBitflagInt16(ref bitflags, reader);\n            RequestBytes_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            W_OutPres_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            W_OutPres_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            Field50 = CaesarReader.ReadBitflagUInt16(ref bitflags, reader);\n\n            NegativeResponseName = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress); // negative response name\n            UnkStr3 = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);\n            UnkStr4 = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);\n\n            P_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            P_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            DiagServiceCodeCount = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            DiagServiceCodeOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            S_Count = CaesarReader.ReadBitflagInt16(ref bitflags, reader);\n            S_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            bitflags = bitflagExtended;\n            \n            X_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            X_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            Y_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            Y_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            Z_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            Z_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            if (RequestBytes_Count > 0)\n            {\n                reader.BaseStream.Seek(baseAddress + RequestBytes_Offset, SeekOrigin.Begin);\n                RequestBytes = reader.ReadBytes(RequestBytes_Count);\n            }\n            else \n            {\n                RequestBytes = new byte[] { };\n            }\n\n            // u_table to u_entries\n            InputPreparations = new List<DiagPreparation>();\n            for (int prepIndex = 0; prepIndex < U_prep_Count; prepIndex++)\n            {\n                long presentationTableOffset = baseAddress + U_prep_Offset;\n                reader.BaseStream.Seek(presentationTableOffset + (prepIndex * 10), SeekOrigin.Begin);\n\n                // DIOpenDiagService (reads 4, 4, 2 then calls DiagServiceReadPresentation) to build a presentation\n                int prepEntryOffset = reader.ReadInt32(); // file: 0 (DW)\n                int prepEntryBitPos = reader.ReadInt32(); // file: 4 (DW)\n                ushort prepEntryMode = reader.ReadUInt16(); // file: 8 (W)\n\n                DiagPreparation preparation = new DiagPreparation(reader, language, presentationTableOffset + prepEntryOffset, prepEntryBitPos, prepEntryMode, parentEcu, this);\n                //preparation.PrintDebug();\n                InputPreparations.Add(preparation);\n            }\n\n\n            OutputPreparations = new List<List<DiagPreparation>>();\n            long outPresBaseAddress = BaseAddress + W_OutPres_Offset;\n\n            // FIXME: run it through the entire dbr cbf directory, check if any file actually has more than 1 item in ResultPresentationSet\n            for (int presIndex = 0; presIndex < W_OutPres_Count; presIndex++)\n            {\n                reader.BaseStream.Seek(outPresBaseAddress + (presIndex * 8), SeekOrigin.Begin);\n                // FIXME\n                int resultPresentationCount = reader.ReadInt32(); // index? if true, will fix the \"wtf\" list<list<diagprep>>\n                int resultPresentationOffset = reader.ReadInt32();\n\n                List<DiagPreparation> ResultPresentationSet = new List<DiagPreparation>();\n                for (int presInnerIndex = 0; presInnerIndex < resultPresentationCount; presInnerIndex++)\n                {\n                    long presentationTableOffset = outPresBaseAddress + resultPresentationOffset;\n\n                    reader.BaseStream.Seek(presentationTableOffset + (presIndex * 10), SeekOrigin.Begin);\n\n                    int prepEntryOffset = reader.ReadInt32(); // file: 0 (DW)\n                    int prepEntryBitPos = reader.ReadInt32(); // file: 4 (DW)\n                    ushort prepEntryMode = reader.ReadUInt16(); // file: 8 (W)\n\n                    DiagPreparation preparation = new DiagPreparation(reader, language, presentationTableOffset + prepEntryOffset, prepEntryBitPos, prepEntryMode, parentEcu, this);\n                    ResultPresentationSet.Add(preparation);\n                }\n                OutputPreparations.Add(ResultPresentationSet);\n            }\n\n            DiagComParameters = new List<ComParameter>();\n            long comParamTableBaseAddress = BaseAddress + T_ComParam_Offset;\n            for (int cpIndex = 0; cpIndex < T_ComParam_Count; cpIndex++)\n            {\n                reader.BaseStream.Seek(comParamTableBaseAddress + (cpIndex * 4), SeekOrigin.Begin);\n                int resultCpOffset = reader.ReadInt32();\n                long cpEntryBaseAddress = comParamTableBaseAddress + resultCpOffset;\n                ComParameter cp = new ComParameter(reader, cpEntryBaseAddress, parentEcu.ECUInterfaces, language);\n                DiagComParameters.Add(cp);\n            }\n\n            // DJ_Zugriffsberechtigung_Abgleich\n            // DJ_Zugriffsberechtigung\n            // DT_Abgasklappe_kontinuierlich\n            // FN_HardReset\n            // WVC_Implizite_Variantenkodierung_Write\n\n            // NR_Disable_Resp_required noexec\n            // DT_Laufzeiten_Resetzaehler_nicht_implementiert exec\n            /*\n            if (false && qualifierName.Contains(\"RVC_SCN_Variantencodierung_VGS_73_Lesen\"))\n            {\n\n                Console.WriteLine($\"{nameof(field50)} : {field50}\");\n                Console.WriteLine($\"{nameof(IsExecutable)} : {IsExecutable} {IsExecutable != 0}\");\n                Console.WriteLine($\"{nameof(AccessLevel)} : {AccessLevel}\");\n                Console.WriteLine($\"{nameof(SecurityAccessLevel)} : {SecurityAccessLevel}\");\n                Console.WriteLine($\"{nameof(DataClass)} : {DataClass}\");\n\n\n\n                Console.WriteLine($\"{qualifierName} - ReqBytes: {RequestBytes_Count}, P: {P_Count}, Q: {Q_Count}, R: {R_Count}, S: {S_Count}, T: {T_Count}, Preparation: {U_prep_Count}, V: {V_Count}, W: {W_Count}, X: {X_Count}, Y: {Y_Count}, Z: {Z_Count}, DSC {DiagServiceCodeCount}\");\n                Console.WriteLine($\"at 0x{baseAddress:X}, W @ 0x{W_Offset:X}, DSC @ 0x{DiagServiceCodeOffset:X}\");\n                Console.WriteLine($\"ReqBytes: {BitUtility.BytesToHex(RequestBytes)}\");\n            }\n            */\n            //Console.WriteLine($\"{qualifierName} - O: {RequestBytes_Count}, P: {P_Count}, Q: {Q_Count}, R: {R_Count}, S: {S_Count}, T: {T_Count}, U: {U_Count}, V: {V_Count}, W: {W_Count}, X: {X_Count}, Y: {Y_Count}, Z: {Z_Count}, DSC {DiagServiceCodeCount}\");\n\n            \n            byte[] dscPool = parentEcu.ParentContainer.CaesarCFFHeader.DSCPool;\n            long dscTableBaseAddress = BaseAddress + DiagServiceCodeOffset;\n\n            using (BinaryReader dscPoolReader = new BinaryReader(new MemoryStream(dscPool)))\n            {\n                for (int dscIndex = 0; dscIndex < DiagServiceCodeCount; dscIndex++) \n                {\n                    reader.BaseStream.Seek(dscTableBaseAddress + (4 * dscIndex), SeekOrigin.Begin);\n                    long dscEntryBaseAddress = reader.ReadInt32() + dscTableBaseAddress;\n                    reader.BaseStream.Seek(dscEntryBaseAddress, SeekOrigin.Begin);\n\n                    ulong dscEntryBitflags = reader.ReadUInt16();\n                    uint idk1 = CaesarReader.ReadBitflagUInt8(ref dscEntryBitflags, reader);\n                    uint idk2 = CaesarReader.ReadBitflagUInt8(ref dscEntryBitflags, reader);\n                    int dscPoolOffset = CaesarReader.ReadBitflagInt32(ref dscEntryBitflags, reader);\n                    string dscQualifier = CaesarReader.ReadBitflagStringWithReader(ref dscEntryBitflags, reader, dscEntryBaseAddress);\n\n                    dscPoolReader.BaseStream.Seek(dscPoolOffset * 8, SeekOrigin.Begin);\n                    long dscRecordOffset = dscPoolReader.ReadInt32() + parentEcu.ParentContainer.CaesarCFFHeader.DscBlockOffset;\n                    int dscRecordSize = dscPoolReader.ReadInt32();\n\n                    reader.BaseStream.Seek(dscRecordOffset, SeekOrigin.Begin);\n\n                    // Console.WriteLine($\"DSC {qualifierName} @ 0x{dscTableBaseAddress:X8} {idk1}/{idk2} pool @ 0x{dscPoolOffset:X}, name: {dscQualifier}\");\n                    byte[] dscBytes = reader.ReadBytes(dscRecordSize);\n#if DEBUG\n                    //string dscName = $\"{parentEcu.Qualifier}_{Qualifier}_{dscIndex}.pal\";\n                    //Console.WriteLine($\"Exporting DSC: {dscName}\");\n                    //File.WriteAllBytes(dscName, dscBytes);\n#endif\n                    // at this point, the DSC binary is available in dscBytes, intended for use in DSCContext (but is currently unimplemented)\n                    // Console.WriteLine($\"DSC actual at 0x{dscRecordOffset:X}, size=0x{dscRecordSize:X}\\n\");\n                }\n\n            }\n\n        }\n\n        public string GetDescription()\n        {\n            return Language.GetString(Description_CTF);\n        }\n        public string GetName()\n        {\n            return Language.GetString(Name_CTF);\n        }\n\n        public long GetCALInt16Offset(BinaryReader reader) \n        {\n            reader.BaseStream.Seek(BaseAddress, SeekOrigin.Begin);\n\n            ulong bitflags = reader.ReadUInt32();\n            ulong bitflagExtended = reader.ReadUInt32();\n\n            CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, BaseAddress); // Qualifier\n            CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); // Name\n            CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); // Description\n            CaesarReader.ReadBitflagUInt16(ref bitflags, reader); // Type\n            CaesarReader.ReadBitflagUInt16(ref bitflags, reader); // IsExecutable \n            if (CaesarReader.CheckAndAdvanceBitflag(ref bitflags))\n            {\n                return reader.BaseStream.Position;\n            }\n            else \n            {\n                return -1;\n            }\n        }\n\n\n        public void PrintDebug() \n        {\n            Console.WriteLine($\"{Qualifier} - ReqBytes: {RequestBytes_Count}, P: {P_Count}, Q: {Q_Count}, R: {R_Count}, S: {S_Count}, ComParams: {T_ComParam_Count}, Preparation: {U_prep_Count}, V: {V_Count}, OutPres: {W_OutPres_Count}, X: {X_Count}, Y: {Y_Count}, Z: {Z_Count}, DSC {DiagServiceCodeCount}, field50: {Field50}\");\n            Console.WriteLine($\"BaseAddress @ 0x{BaseAddress:X}, NR: {NegativeResponseName}\");\n            Console.WriteLine($\"V @ 0x{BaseAddress + V_Offset:X}, count: {V_Count}\");\n        }\n    }\n}\n\n\n\n\n/*\n// originally EnvironmentContext, removed because of overlap\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Caesar\n{\n    public class EnvironmentContext\n    {\n        // see : const char *__cdecl DIGetComfortErrorCode(DI_ECUINFO *ecuh, unsigned int dtcIndex)\n        public string Qualifier;\n\n        public long BaseAddress;\n        public int PoolIndex;\n        public int Name_CTF;\n        public int Description_CTF;\n        public int ServiceTypeMaybe;\n        public int AccessLevelType_Maybe;\n        public int AccessLevelType_Maybe2;\n        public int PresentationTableCount;\n        public int PresentationTableOffset;\n        public int PresentationTableRowSize_Maybe; // see diagservice for similar layout, seems unused (uint16)\n\n        public ECU ParentECU;\n        CTFLanguage Language;\n\n        public EnvironmentContext(BinaryReader reader, CTFLanguage language, long baseAddress, int poolIndex, ECU parentEcu)\n        {\n            ParentECU = parentEcu;\n            PoolIndex = poolIndex;\n            BaseAddress = baseAddress;\n            Language = language;\n            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);\n\n            // layout seems very similar to DiagService\n            ulong bitflags = reader.ReadUInt32();\n            ulong bitflagsExtended = reader.ReadUInt32();\n\n            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);\n            Name_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);\n            Description_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);\n\n            ServiceTypeMaybe = CaesarReader.ReadBitflagInt16(ref bitflags, reader);\n            AccessLevelType_Maybe = CaesarReader.ReadBitflagInt16(ref bitflags, reader);\n            AccessLevelType_Maybe2 = CaesarReader.ReadBitflagInt16(ref bitflags, reader);\n\n            // doesn't seem to be set for any files in my library\n            for (int i = 0; i < 14; i++) \n            {\n                if (CaesarReader.CheckAndAdvanceBitflag(ref bitflags))\n                {\n                    throw new Exception(\"Sorry, The parser for EnvironmentContext has encountered an unknown bitflag; please open an issue and indicate your CBF file name.\");\n                }\n            }\n\n            // these describe the table to the presentation\n            PresentationTableCount = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            PresentationTableOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            PresentationTableRowSize_Maybe = CaesarReader.ReadBitflagInt16(ref bitflags, reader);\n\n            // ... looks like DiagService?!\n        }\n\n        public void PrintDebug()\n        {\n            Console.WriteLine(Qualifier);\n        }\n    }\n}\n*/"
  },
  {
    "path": "Caesar/Caesar/ECU.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Caesar\n{\n    public class ECU\n    {\n        public string Qualifier;\n        public int EcuName_CTF;\n        public int EcuDescription_CTF;\n        public string EcuXmlVersion;\n        public int InterfaceBlockCount;\n        public int InterfaceTableOffset;\n        public int SubinterfacesCount;\n        public int SubinterfacesOffset;\n        public string EcuClassName;\n        public string UnkStr7;\n        public string UnkStr8;\n\n        public int IgnitionRequired;\n        public int Unk2;\n        public int UnkBlockCount;\n        public int UnkBlockOffset;\n        public int EcuSgmlSource;\n        public int Unk6RelativeOffset;\n\n        private int EcuVariant_BlockOffset; // 1\n        private int EcuVariant_EntryCount;\n        private int EcuVariant_EntrySize;\n        private int EcuVariant_BlockSize;\n\n        private int DiagJob_BlockOffset; // 2\n        private int DiagJob_EntryCount;\n        private int DiagJob_EntrySize;\n        private int DiagJob_BlockSize;\n\n        private int Dtc_BlockOffset; // 3\n        private int Dtc_EntryCount;\n        private int Dtc_EntrySize;\n        private int Dtc_BlockSize;\n\n        private int Env_BlockOffset; // 4\n        private int Env_EntryCount;\n        private int Env_EntrySize;\n        private int Env_BlockSize;\n\n        private int VcDomain_BlockOffset; // 5 , 0x15716\n        private int VcDomain_EntryCount; // [1], 43 0x2B\n        private int VcDomain_EntrySize; // [2], 12 0xC (multiply with [1] for size), 43*12=516 = 0x204\n        private int VcDomain_BlockSize; // [3] unused\n\n        private int Presentations_BlockOffset;\n        private int Presentations_EntryCount;\n        private int Presentations_EntrySize;\n        private int Presentations_BlockSize;\n\n        private int InternalPresentations_BlockOffset; // 31 (formerly InfoPool)\n        private int InternalPresentations_EntryCount; // 32\n        private int InternalPresentations_EntrySize; // 33\n        private int InternalPresentations_BlockSize; // 34\n\n        private int Unk_BlockOffset;\n        private int Unk_EntryCount;\n        private int Unk_EntrySize;\n        private int Unk_BlockSize;\n\n        public int Unk39;\n\n        public List<ECUInterface> ECUInterfaces = new List<ECUInterface>();\n        public List<ECUInterfaceSubtype> ECUInterfaceSubtypes = new List<ECUInterfaceSubtype>();\n        public List<ECUVariant> ECUVariants = new List<ECUVariant>();\n\n        public List<VCDomain> GlobalVCDs = new List<VCDomain>();\n        public List<DTC> GlobalDTCs = new List<DTC>();\n        public List<DiagService> GlobalEnvironmentContexts = new List<DiagService>();\n        public List<DiagService> GlobalDiagServices = new List<DiagService>();\n        public List<DiagPresentation> GlobalPresentations = new List<DiagPresentation>();\n        public List<DiagPresentation> GlobalInternalPresentations = new List<DiagPresentation>();\n\n        private long BaseAddress;\n        [Newtonsoft.Json.JsonIgnore]\n        public CTFLanguage Language;\n\n        [Newtonsoft.Json.JsonIgnore]\n        public CaesarContainer ParentContainer;\n\n        byte[] cachedVarcodingPool = new byte[] { };\n        byte[] cachedVariantPool = new byte[] { };\n        byte[] cachedDiagjobPool = new byte[] { };\n        byte[] cachedEcuInfoPool = new byte[] { };\n        byte[] cachedPresentationsPool = new byte[] { };\n        byte[] cachedInternalPresentationsPool = new byte[] { };\n        byte[] cachedEnvPool = new byte[] { };\n        byte[] cachedDtcPool = new byte[] { };\n        byte[] cachedUnkPool = new byte[] { };\n\n        [Newtonsoft.Json.JsonIgnore]\n        public string ECUDescription { get { return Language.GetString(EcuDescription_CTF); } }\n\n\n        public void Restore(CTFLanguage language, CaesarContainer parentContainer) \n        {\n            Language = language;\n            ParentContainer = parentContainer;\n            foreach (VCDomain vc in GlobalVCDs)\n            {\n                vc.Restore(language, this);\n            }\n            foreach (DTC dtc in GlobalDTCs)\n            {\n                dtc.Restore(language, this);\n            }\n            foreach (DiagService ds in GlobalDiagServices)\n            {\n                ds.Restore(language, this);\n            }\n            foreach (DiagService ds in GlobalEnvironmentContexts)\n            {\n                ds.Restore(language, this);\n            }\n            foreach (DiagPresentation pres in GlobalPresentations)\n            {\n                pres.Restore(language);\n            }\n            foreach (DiagPresentation pres in GlobalInternalPresentations)\n            {\n                pres.Restore(language);\n            }\n            foreach (ECUInterface iface in ECUInterfaces)\n            {\n                iface.Restore(language);\n            }\n            foreach (ECUInterfaceSubtype iface in ECUInterfaceSubtypes)\n            {\n                iface.Restore(language);\n            }\n            foreach (ECUVariant variant in ECUVariants)\n            {\n                variant.Restore(language, this);\n            }\n        }\n\n        public byte[] ReadDiagjobPool(BinaryReader reader)\n        {\n            if (cachedDiagjobPool.Length == 0)\n            {\n                cachedDiagjobPool = ReadEcuPool(reader, DiagJob_BlockOffset, DiagJob_EntryCount, DiagJob_EntrySize);\n            }\n            return cachedDiagjobPool;\n        }\n\n        public byte[] ReadVariantPool(BinaryReader reader)\n        {\n            if (cachedVariantPool.Length == 0)\n            {\n                cachedVariantPool = ReadEcuPool(reader, EcuVariant_BlockOffset, EcuVariant_EntryCount, EcuVariant_EntrySize);\n            }\n            return cachedVariantPool;\n        }\n\n        public byte[] ReadVarcodingPool(BinaryReader reader)\n        {\n            if (cachedVarcodingPool.Length == 0)\n            {\n                cachedVarcodingPool = ReadEcuPool(reader, VcDomain_BlockOffset, VcDomain_EntryCount, VcDomain_EntrySize);\n            }\n            return cachedVarcodingPool;\n        }\n        // don't actually know what the proper name is, using \"ECUInfo\" for now\n        public byte[] ReadECUInfoPool(BinaryReader reader)\n        {\n            if (cachedEcuInfoPool.Length == 0)\n            {\n                cachedEcuInfoPool = ReadEcuPool(reader, InternalPresentations_BlockOffset, InternalPresentations_EntryCount, InternalPresentations_EntrySize);\n            }\n            return cachedEcuInfoPool;\n        }\n        public byte[] ReadECUPresentationsPool(BinaryReader reader)\n        {\n            if (cachedPresentationsPool.Length == 0)\n            {\n                cachedPresentationsPool = ReadEcuPool(reader, Presentations_BlockOffset, Presentations_EntryCount, Presentations_EntrySize);\n            }\n            return cachedPresentationsPool;\n        }\n        public byte[] ReadECUInternalPresentationsPool(BinaryReader reader)\n        {\n            if (cachedInternalPresentationsPool.Length == 0)\n            {\n                cachedInternalPresentationsPool = ReadEcuPool(reader, InternalPresentations_BlockOffset, InternalPresentations_EntryCount, InternalPresentations_EntrySize);\n            }\n            return cachedInternalPresentationsPool;\n        }\n        public byte[] ReadECUEnvPool(BinaryReader reader)\n        {\n            if (cachedEnvPool.Length == 0)\n            {\n                cachedEnvPool = ReadEcuPool(reader, Env_BlockOffset, Env_EntryCount, Env_EntrySize);\n            }\n            return cachedEnvPool;\n        }\n        public byte[] ReadECUUnkPool (BinaryReader reader)\n        {\n            if (cachedUnkPool.Length == 0)\n            {\n                cachedUnkPool = ReadEcuPool(reader, Unk_BlockOffset, Unk_EntryCount, Unk_EntrySize);\n            }\n            return cachedUnkPool;\n        }\n\n        public byte[] ReadECUDtcPool(BinaryReader reader)\n        {\n            if (cachedDtcPool.Length == 0)\n            {\n                cachedDtcPool = ReadEcuPool(reader, Dtc_BlockOffset, Dtc_EntryCount, Dtc_EntrySize);\n            }\n            return cachedDtcPool;\n        }\n\n        public byte[] ReadEcuPool(BinaryReader reader, long addressToReadFrom, int multiplier1, int multiplier2) \n        {\n            reader.BaseStream.Seek(addressToReadFrom, SeekOrigin.Begin);\n            return reader.ReadBytes(multiplier1 * multiplier2);\n        }\n\n        public ECU() { }\n\n        public ECU(BinaryReader reader, CTFLanguage language, CFFHeader header, long baseAddress, CaesarContainer parentContainer)  \n        {\n            ParentContainer = parentContainer;\n            BaseAddress = baseAddress;\n            Language = language;\n            // Read 32+16 bits\n            ulong ecuBitFlags = reader.ReadUInt32();\n            // after exhausting the 32 bits, load these additional 16 bits\n            ulong ecuBitFlagsExtended = reader.ReadUInt16();\n\n            // Console.WriteLine($\"ECU bitflags: {ecuBitFlags:X}\");\n\n            // advancing forward to ecuBase + 10\n            int ecuHdrIdk1 = reader.ReadInt32(); // no idea\n            // Console.WriteLine($\"Skipping: {ecuHdrIdk1:X8}\");\n\n            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref ecuBitFlags, reader, BaseAddress);\n            EcuName_CTF = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader, -1);\n            EcuDescription_CTF = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader, -1);\n            EcuXmlVersion = CaesarReader.ReadBitflagStringWithReader(ref ecuBitFlags, reader, BaseAddress);\n            InterfaceBlockCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);\n            InterfaceTableOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);\n            SubinterfacesCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);\n            SubinterfacesOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);\n            EcuClassName = CaesarReader.ReadBitflagStringWithReader(ref ecuBitFlags, reader, BaseAddress);\n            UnkStr7 = CaesarReader.ReadBitflagStringWithReader(ref ecuBitFlags, reader, BaseAddress);\n            UnkStr8 = CaesarReader.ReadBitflagStringWithReader(ref ecuBitFlags, reader, BaseAddress);\n\n            int dataBufferOffsetRelativeToFile = header.StringPoolSize + StubHeader.StubHeaderSize + header.CffHeaderSize + 4;\n            // Console.WriteLine($\"{nameof(dataBufferOffsetRelativeToFile)} : 0x{dataBufferOffsetRelativeToFile:X}\");\n\n            IgnitionRequired = CaesarReader.ReadBitflagInt16(ref ecuBitFlags, reader);\n            Unk2 = CaesarReader.ReadBitflagInt16(ref ecuBitFlags, reader);\n            UnkBlockCount = CaesarReader.ReadBitflagInt16(ref ecuBitFlags, reader);\n            UnkBlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);\n            EcuSgmlSource = CaesarReader.ReadBitflagInt16(ref ecuBitFlags, reader);\n            Unk6RelativeOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);\n\n            EcuVariant_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile;\n            EcuVariant_EntryCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);\n            EcuVariant_EntrySize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); // 10\n            EcuVariant_BlockSize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);\n\n            DiagJob_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile;\n            DiagJob_EntryCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);\n            DiagJob_EntrySize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); // 14\n            DiagJob_BlockSize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);\n\n            Dtc_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile;\n            Dtc_EntryCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);\n            Dtc_EntrySize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); // 12\n            Dtc_BlockSize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);\n\n            Env_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile;\n            Env_EntryCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);\n            Env_EntrySize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); // 8\n\n            // bitflags will be exhausted at this point, load the extended bitflags\n            ecuBitFlags = ecuBitFlagsExtended;\n\n            Env_BlockSize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);\n\n            VcDomain_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile;\n            VcDomain_EntryCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);\n            VcDomain_EntrySize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); // 12\n            VcDomain_BlockSize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);\n\n            Presentations_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile;\n            Presentations_EntryCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);\n            Presentations_EntrySize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); // 8\n            Presentations_BlockSize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);\n\n            InternalPresentations_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile;\n            InternalPresentations_EntryCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);\n            InternalPresentations_EntrySize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); // 8\n            InternalPresentations_BlockSize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);\n\n            Unk_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile;\n            Unk_EntryCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);\n            Unk_EntrySize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);\n            Unk_BlockSize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);\n\n            Unk39 = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);\n\n            // read ecu's supported interfaces and subtypes\n\n            // try to read interface block from the interface buffer table\n            // this address is relative to the definitions block\n            long interfaceTableAddress = BaseAddress + InterfaceTableOffset;\n            // Console.WriteLine($\"Interface table address: {interfaceTableAddress:X}, given offset: {interfaceTableOffset:X}\");\n\n            ECUInterfaces = new List<ECUInterface>();\n            for (int interfaceBufferIndex = 0; interfaceBufferIndex < InterfaceBlockCount; interfaceBufferIndex++)\n            {\n                // Console.WriteLine($\"Parsing interface {interfaceBufferIndex + 1}/{interfaceBlockCount}\");\n\n                // find our interface block offset\n                reader.BaseStream.Seek(interfaceTableAddress + (interfaceBufferIndex * 4), SeekOrigin.Begin);\n                // seek to the actual block (ambiguity: is this relative to the interface table or the current array?)\n                int interfaceBlockOffset = reader.ReadInt32();\n\n                long ecuInterfaceBaseAddress = interfaceTableAddress + interfaceBlockOffset;\n\n                ECUInterface ecuInterface = new ECUInterface(reader, ecuInterfaceBaseAddress);\n                ECUInterfaces.Add(ecuInterface);\n            }\n\n            // try to read interface subtype block from the interface buffer table\n            // this address is relative to the definitions block\n            ECUInterfaceSubtypes = new List<ECUInterfaceSubtype>();\n            long ctTableAddress = BaseAddress + SubinterfacesOffset;\n            // Console.WriteLine($\"Interface subtype table address: {ctTableAddress:X}, given offset: {ecuChildTypesOffset:X}\");\n            for (int ctBufferIndex = 0; ctBufferIndex < SubinterfacesCount; ctBufferIndex++)\n            {\n                // Console.WriteLine($\"Parsing interface subtype {ctBufferIndex + 1}/{ecuNumberOfEcuChildTypes}\");\n                // find our ct block offset\n                reader.BaseStream.Seek(ctTableAddress + (ctBufferIndex * 4), SeekOrigin.Begin);\n                // seek to the actual block (ambiguity: is this relative to the ct table or the current array?)\n                int actualBlockOffset = reader.ReadInt32();\n                long ctBaseAddress = ctTableAddress + actualBlockOffset;\n\n                ECUInterfaceSubtype ecuInterfaceSubtype = new ECUInterfaceSubtype(reader, ctBaseAddress, ctBufferIndex, language);\n                ECUInterfaceSubtypes.Add(ecuInterfaceSubtype);\n            }\n\n            // dependency of variants\n            CreatePresentations(reader, language);\n            CreateInternalPresentations(reader, language);\n            // requires presentations\n            CreateEnvironments(reader, language);\n            CreateDiagServices(reader, language);\n            // dtc has xrefs to envs\n            CreateDTCs(reader, language);\n            CreateVCDomains(reader, language);\n\n            CreateEcuVariants(reader, language);\n            //PrintDebug();\n        }\n\n        public void CreateDiagServices(BinaryReader reader, CTFLanguage language)\n        {\n            byte[] diagjobPool = ReadDiagjobPool(reader);\n            // arrays since list has become too expensive\n            DiagService[] globalDiagServices = new DiagService[DiagJob_EntryCount];\n\n\n            using (BinaryReader poolReader = new BinaryReader(new MemoryStream(diagjobPool)))\n            {\n                for (int diagjobIndex = 0; diagjobIndex < DiagJob_EntryCount; diagjobIndex++)\n                {\n                    int offset = poolReader.ReadInt32();\n                    int size = poolReader.ReadInt32();\n                    uint crc = poolReader.ReadUInt32();\n                    uint config = poolReader.ReadUInt16();\n                    long diagjobBaseAddress = offset + DiagJob_BlockOffset;\n                    // Console.WriteLine($\"DJ @ {offset:X} with size {size:X}\");\n\n                    DiagService dj = new DiagService(reader, language, diagjobBaseAddress, diagjobIndex, this);\n                    // GlobalDiagServices.Add(dj);\n                    globalDiagServices[diagjobIndex] = dj;\n                }\n            }\n\n            GlobalDiagServices = new List<DiagService>(globalDiagServices);\n        }\n        public void CreateDTCs(BinaryReader reader, CTFLanguage language)\n        {\n            byte[] dtcPool = ReadECUDtcPool(reader);\n            DTC[] globalDtcs = new DTC[Dtc_EntryCount];\n            using (BinaryReader poolReader = new BinaryReader(new MemoryStream(dtcPool)))\n            {\n                for (int dtcIndex = 0; dtcIndex < Dtc_EntryCount; dtcIndex++)\n                {\n                    int offset = poolReader.ReadInt32();\n                    int size = poolReader.ReadInt32();\n                    uint crc = poolReader.ReadUInt32();\n                    long dtcBaseAddress = offset + Dtc_BlockOffset;\n\n                    DTC dtc = new DTC(reader, language, dtcBaseAddress, dtcIndex, this);\n                    globalDtcs[dtcIndex] = dtc;\n                }\n            }\n            GlobalDTCs = new List<DTC>(globalDtcs);\n        }\n\n        public void CreateVCDomains(BinaryReader reader, CTFLanguage language) \n        {\n            byte[] vcPool = ReadVarcodingPool(reader);\n            VCDomain[] globalVCDs = new VCDomain[VcDomain_EntryCount];\n            using (BinaryReader poolReader = new BinaryReader(new MemoryStream(vcPool)))\n            {\n                for (int vcdIndex = 0; vcdIndex < VcDomain_EntryCount; vcdIndex++)\n                {\n                    int entryOffset = poolReader.ReadInt32();\n                    int entrySize = poolReader.ReadInt32();\n                    uint entryCrc = poolReader.ReadUInt32();\n                    long vcdBlockAddress = entryOffset + VcDomain_BlockOffset;\n                    VCDomain vcd = new VCDomain(reader, language, vcdBlockAddress, vcdIndex, this);\n                    globalVCDs[vcdIndex] = vcd;\n                }\n            }\n            GlobalVCDs = new List<VCDomain>(globalVCDs);\n        }\n\n        public void CreateEnvironments(BinaryReader reader, CTFLanguage language)\n        {\n            /*\n            byte[] envPool = ReadECUEnvPool(reader);\n            EnvironmentContext[] globalEnvs = new EnvironmentContext[Env_EntryCount];\n            using (BinaryReader poolReader = new BinaryReader(new MemoryStream(envPool)))\n            {\n                for (int envIndex = 0; envIndex < Env_EntryCount; envIndex++)\n                {\n                    int offset = poolReader.ReadInt32();\n                    int size = poolReader.ReadInt32();\n                    long envBaseAddress = offset + Env_BlockOffset;\n\n                    // Console.WriteLine($\"0x{envBaseAddress:X}\");\n                    EnvironmentContext env = new EnvironmentContext(reader, language, envBaseAddress, envIndex, this);\n                    globalEnvs[envIndex] = env;\n                }\n            }\n            GlobalEnvironmentContexts = new List<EnvironmentContext>(globalEnvs);\n            */\n            byte[] envPool = ReadECUEnvPool(reader);\n            DiagService[] globalEnvs = new DiagService[Env_EntryCount];\n            using (BinaryReader poolReader = new BinaryReader(new MemoryStream(envPool)))\n            {\n                for (int envIndex = 0; envIndex < Env_EntryCount; envIndex++)\n                {\n                    int offset = poolReader.ReadInt32();\n                    int size = poolReader.ReadInt32();\n                    long envBaseAddress = offset + Env_BlockOffset;\n\n                    // Console.WriteLine($\"0x{envBaseAddress:X}\");\n                    DiagService env = new DiagService(reader, language, envBaseAddress, envIndex, this);\n                    globalEnvs[envIndex] = env;\n                }\n            }\n            GlobalEnvironmentContexts = new List<DiagService>(globalEnvs);\n        }\n        public void CreateUnk(BinaryReader reader, CTFLanguage language)\n        {\n            byte[] unkPool = ReadECUUnkPool(reader);\n            using (BinaryReader poolReader = new BinaryReader(new MemoryStream(unkPool)))\n            {\n                for (int unkIndex = 0; unkIndex < Unk_EntryCount; unkIndex++)\n                {\n                }\n            }\n        }\n        public void CreatePresentations(BinaryReader reader, CTFLanguage language)\n        {\n            byte[] presentationsPool = ReadECUPresentationsPool(reader);\n            // arrays since list has become too expensive\n            // DiagService[] globalDiagServices = new DiagService[DiagJob_EntryCount];\n            DiagPresentation[] globalPresentations = new DiagPresentation[Presentations_EntryCount];\n\n            using (BinaryReader poolReader = new BinaryReader(new MemoryStream(presentationsPool)))\n            {\n                for (int presentationsIndex = 0; presentationsIndex < Presentations_EntryCount; presentationsIndex++)\n                {\n\n                    int offset = poolReader.ReadInt32();\n                    int size = poolReader.ReadInt32();\n\n                    long presentationsBaseAddress = offset + Presentations_BlockOffset;\n                    // string offsetLog = $\"Pres @ 0x{offset:X} with size 0x{size:X} base 0x{presentationsBaseAddress:X}\";\n\n                    DiagPresentation pres = new DiagPresentation(reader, presentationsBaseAddress, presentationsIndex, language);\n                    globalPresentations[presentationsIndex] = pres;\n                }\n                // Console.WriteLine($\"Entry count/size for presentations : {Presentations_EntryCount}, {Presentations_EntrySize}\");\n            }\n            GlobalPresentations = new List<DiagPresentation>(globalPresentations);\n        }\n        public void CreateInternalPresentations(BinaryReader reader, CTFLanguage language)\n        {\n            byte[] internalPresentationsPool = ReadECUInternalPresentationsPool(reader);\n            DiagPresentation[] globalInternalPresentations = new DiagPresentation[InternalPresentations_EntryCount];\n\n            using (BinaryReader poolReader = new BinaryReader(new MemoryStream(internalPresentationsPool)))\n            {\n                for (int internalPresentationsIndex = 0; internalPresentationsIndex < InternalPresentations_EntryCount; internalPresentationsIndex++)\n                {\n                    int offset = poolReader.ReadInt32();\n                    int size = poolReader.ReadInt32();\n\n                    long internalPresentationsBaseAddress = offset + InternalPresentations_BlockOffset;\n                    DiagPresentation pres = new DiagPresentation(reader, internalPresentationsBaseAddress, internalPresentationsIndex, language);\n                    globalInternalPresentations[internalPresentationsIndex] = pres;\n                }\n            }\n            GlobalInternalPresentations = new List<DiagPresentation>(globalInternalPresentations);\n        }\n        public void CreateEcuVariants(BinaryReader reader, CTFLanguage language) \n        {\n            ECUVariants.Clear();\n            byte[] ecuVariantPool = ReadVariantPool(reader);\n\n            using (BinaryReader poolReader = new BinaryReader(new MemoryStream(ecuVariantPool)))\n            {\n                for (int ecuVariantIndex = 0; ecuVariantIndex < EcuVariant_EntryCount; ecuVariantIndex++)\n                {\n                    poolReader.BaseStream.Seek(ecuVariantIndex * EcuVariant_EntrySize, SeekOrigin.Begin);\n                    \n                    int entryOffset = poolReader.ReadInt32();\n                    int entrySize = poolReader.ReadInt32();\n                    ushort poolEntryAttributes = poolReader.ReadUInt16();\n                    long variantBlockAddress = entryOffset + EcuVariant_BlockOffset;\n\n                    ECUVariant variant = new ECUVariant(reader, this, language, variantBlockAddress, entrySize);\n                    ECUVariants.Add(variant);\n                    // Console.WriteLine($\"Variant Entry @ 0x{entryOffset:X} with size 0x{entrySize:X} and CRC {poolEntryAttributes:X8}, abs addr {variantBlockAddress:X8}\");\n\n#if DEBUG\n                    int resultLimit = 1999;\n                    if (ecuVariantIndex >= resultLimit)\n                    {\n                        Console.WriteLine($\"Breaking prematurely to create only {resultLimit} variant(s) (debug)\");\n                        break;\n                    }\n#endif\n                }\n            }\n        }\n\n        public void PrintDebug()\n        {\n            Console.WriteLine($\"ECU Name: {Qualifier}\");\n            Console.WriteLine($\"{nameof(EcuName_CTF)} : {EcuName_CTF}\");\n            Console.WriteLine($\"{nameof(EcuDescription_CTF)} : {EcuDescription_CTF}\");\n            Console.WriteLine($\"ECU ecuXmlVersion: {EcuXmlVersion}\");\n            Console.WriteLine($\"{nameof(InterfaceBlockCount)} : {InterfaceBlockCount}\");\n            Console.WriteLine($\"{nameof(InterfaceTableOffset)} : 0x{InterfaceTableOffset:X}\");\n            Console.WriteLine($\"{nameof(SubinterfacesCount)} : {SubinterfacesCount}\");\n            Console.WriteLine($\"{nameof(SubinterfacesOffset)} : {SubinterfacesOffset}\");\n            Console.WriteLine($\"ECU ecuClassName: {EcuClassName}\");\n            Console.WriteLine($\"ECU ecuIdk7: {UnkStr7}\");\n            Console.WriteLine($\"ECU ecuIdk8: {UnkStr8}\");\n\n\n            Console.WriteLine($\"{nameof(IgnitionRequired)} : {IgnitionRequired}\");\n            \n            Console.WriteLine($\"{nameof(Unk2)} : {Unk2}\"); \n\n            Console.WriteLine($\"{nameof(UnkBlockCount)} : {UnkBlockCount}\");\n            Console.WriteLine($\"{nameof(UnkBlockOffset)} : {UnkBlockOffset}\");\n            \n            Console.WriteLine($\"{nameof(EcuSgmlSource)} : {EcuSgmlSource}\");\n            Console.WriteLine($\"{nameof(Unk6RelativeOffset)} : 0x{Unk6RelativeOffset:X}\");\n            \n            Console.WriteLine($\"{nameof(EcuVariant_BlockOffset)} : 0x{EcuVariant_BlockOffset:X}\");\n            Console.WriteLine($\"{nameof(EcuVariant_EntryCount)} : {EcuVariant_EntryCount}\");\n            Console.WriteLine($\"{nameof(EcuVariant_EntrySize)} : {EcuVariant_EntrySize}\");\n            Console.WriteLine($\"{nameof(EcuVariant_BlockSize)} : 0x{EcuVariant_BlockSize:X}\");\n            Console.WriteLine($\"{nameof(DiagJob_BlockOffset)} : 0x{DiagJob_BlockOffset:X}\");\n            Console.WriteLine($\"{nameof(DiagJob_EntryCount)} : {DiagJob_EntryCount}\");\n            Console.WriteLine($\"{nameof(DiagJob_EntrySize)} : {DiagJob_EntrySize}\");\n            Console.WriteLine($\"{nameof(DiagJob_BlockSize)} : 0x{DiagJob_BlockSize:X}\");\n            Console.WriteLine($\"{nameof(Dtc_BlockOffset)} : 0x{Dtc_BlockOffset:X}\");\n            Console.WriteLine($\"{nameof(Dtc_EntryCount)} : {Dtc_EntryCount}\");\n            Console.WriteLine($\"{nameof(Dtc_EntrySize)} : {Dtc_EntrySize}\");\n            Console.WriteLine($\"{nameof(Dtc_BlockSize)} : 0x{Dtc_BlockSize:X}\");\n            Console.WriteLine($\"{nameof(Env_BlockOffset)} : 0x{Env_BlockOffset:X}\");\n            Console.WriteLine($\"{nameof(Env_EntryCount)} : {Env_EntryCount}\");\n            Console.WriteLine($\"{nameof(Env_EntrySize)} : {Env_EntrySize}\");\n\n            // Console.WriteLine(\"--- bitflag load 2 ---\");\n\n            Console.WriteLine($\"{nameof(Env_BlockSize)} : 0x{Env_BlockSize:X}\");\n            Console.WriteLine($\"{nameof(VcDomain_BlockOffset)} : 0x{VcDomain_BlockOffset:X}\");\n            Console.WriteLine($\"{nameof(VcDomain_EntryCount)} : {VcDomain_EntryCount}\");\n            Console.WriteLine($\"{nameof(VcDomain_EntrySize)} : {VcDomain_EntrySize}\");\n            Console.WriteLine($\"{nameof(VcDomain_BlockSize)} : 0x{VcDomain_BlockSize:X}\");\n            Console.WriteLine($\"{nameof(Presentations_BlockOffset)} : 0x{Presentations_BlockOffset:X}\");\n            Console.WriteLine($\"{nameof(Presentations_EntryCount)} : {Presentations_EntryCount}\");\n            Console.WriteLine($\"{nameof(Presentations_EntrySize)} : {Presentations_EntrySize}\");\n            Console.WriteLine($\"{nameof(Presentations_BlockSize)} : 0x{Presentations_BlockSize:X}\");\n            Console.WriteLine($\"{nameof(InternalPresentations_BlockOffset)} : 0x{InternalPresentations_BlockOffset:X}\");\n            Console.WriteLine($\"{nameof(InternalPresentations_EntryCount)} : {InternalPresentations_EntryCount}\");\n            Console.WriteLine($\"{nameof(InternalPresentations_EntrySize)} : {InternalPresentations_EntrySize}\");\n            Console.WriteLine($\"{nameof(InternalPresentations_BlockSize)} : 0x{InternalPresentations_BlockSize:X}\");\n            Console.WriteLine($\"{nameof(Unk_BlockOffset)} : 0x{Unk_BlockOffset:X}\");\n            Console.WriteLine($\"{nameof(Unk_EntryCount)} : {Unk_EntryCount}\");\n            Console.WriteLine($\"{nameof(Unk_EntrySize)} : {Unk_EntrySize}\");\n            Console.WriteLine($\"{nameof(Unk_BlockSize)} : {Unk_BlockSize}\");\n            Console.WriteLine($\"{nameof(Unk39)} : {Unk39}\");\n        }\n    }\n}\n\n/*\n example env records\n\nENV_48_Data_Record_1_StdEnvData\nENV_56_StdEnv_OccurenceFlag\nENV_64_StdEnv_OriginalOdometerValue\nENV_80_StdEnv_MostRecentOdometerValue\nENV_96_StdEnv_FrequencyCounter\nENV_104_StdEnv_OperationCycleCounter\nENV_112_Data_Record_2_CommonEnvData\nENV_120_CommonEnv_StorageSequence\nENV_128_Data_Record_3_First_Occurrence\nENV_136_First_SIGNALS_xSet1\nENV_136_First_SIGNALS_xSet2\n*/\n"
  },
  {
    "path": "Caesar/Caesar/ECUInterface.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.IO;\n\nnamespace Caesar\n{\n    public class ECUInterface\n    {\n        public string Qualifier;\n        public int Name_CTF;\n        public int Description_CTF;\n        public string VersionString;\n        public int Version;\n        private int ComParamCount;\n        private int ComParamListOffset;\n        public int Unk6;\n        \n\n        public List<string> ComParameterNames = new List<string>();\n\n        private CTFLanguage Language;\n        private long BaseAddress;\n\n        public void Restore(CTFLanguage language) \n        {\n            Language = language;\n        }\n\n        public ECUInterface() { }\n\n        public ECUInterface(BinaryReader reader, long baseAddress)\n        {\n            BaseAddress = baseAddress;\n            reader.BaseStream.Seek(BaseAddress, SeekOrigin.Begin);\n\n            // we can now properly operate on the interface block\n            ulong interfaceBitflags = reader.ReadUInt32();\n\n            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref interfaceBitflags, reader, BaseAddress);\n            Name_CTF = CaesarReader.ReadBitflagInt32(ref interfaceBitflags, reader, -1);\n            Description_CTF = CaesarReader.ReadBitflagInt32(ref interfaceBitflags, reader, -1);\n            VersionString = CaesarReader.ReadBitflagStringWithReader(ref interfaceBitflags, reader, BaseAddress);\n            Version = CaesarReader.ReadBitflagInt32(ref interfaceBitflags, reader);\n            ComParamCount = CaesarReader.ReadBitflagInt32(ref interfaceBitflags, reader);\n            ComParamListOffset = CaesarReader.ReadBitflagInt32(ref interfaceBitflags, reader);\n            Unk6 = CaesarReader.ReadBitflagInt16(ref interfaceBitflags, reader);\n\n\n            long comparamFileOffset = ComParamListOffset + BaseAddress;\n            // Console.WriteLine($\"interface string table offset from definition block : {interfaceStringTableOffset_fromDefinitionBlock:X}\");\n\n            for (int interfaceStringIndex = 0; interfaceStringIndex < ComParamCount; interfaceStringIndex++)\n            {\n                // seek to string pointer\n                reader.BaseStream.Seek(comparamFileOffset + (interfaceStringIndex * 4), SeekOrigin.Begin);\n                // from pointer, seek to string\n                long interfaceStringReadoutPtr = reader.ReadInt32() + comparamFileOffset;\n                reader.BaseStream.Seek(interfaceStringReadoutPtr, SeekOrigin.Begin);\n                string comParameter = CaesarReader.ReadStringFromBinaryReader(reader);\n                ComParameterNames.Add(comParameter);\n            }\n        }\n\n        public void PrintDebug() \n        {\n            Console.WriteLine($\"{nameof(Qualifier)} : {Qualifier}\");\n            Console.WriteLine($\"{nameof(Name_CTF)} : {Name_CTF}\");\n            Console.WriteLine($\"{nameof(Description_CTF)} : {Description_CTF}\");\n            Console.WriteLine($\"{nameof(VersionString)} : {VersionString}\");\n            Console.WriteLine($\"{nameof(Version)} : {Version}\");\n            Console.WriteLine($\"{nameof(ComParamCount)} : {ComParamCount}\");\n            Console.WriteLine($\"{nameof(ComParamListOffset)} : 0x{ComParamListOffset:X}\");\n            Console.WriteLine($\"{nameof(Unk6)} : {Unk6}\");\n\n            foreach (string comParameter in ComParameterNames)\n            {\n                Console.WriteLine($\"InterfaceComParameter: {comParameter}\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/ECUInterfaceSubtype.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.IO;\n\n\nnamespace Caesar\n{\n    public class ECUInterfaceSubtype\n    {\n        public enum ParamName \n        {\n            CP_BAUDRATE,\n            CP_GLOBAL_REQUEST_CANIDENTIFIER,\n            CP_FUNCTIONAL_REQUEST_CANIDENTIFIER,\n            CP_REQUEST_CANIDENTIFIER,\n            CP_RESPONSE_CANIDENTIFIER,\n            CP_PARTNUMBERID,\n            CP_PARTBLOCK,\n            CP_HWVERSIONID,\n            CP_SWVERSIONID,\n            CP_SWVERSIONBLOCK,\n            CP_SUPPLIERID,\n            CP_SWSUPPLIERBLOCK,\n            CP_ADDRESSMODE,\n            CP_ADDRESSEXTENSION,\n            CP_ROE_RESPONSE_CANIDENTIFIER,\n            CP_USE_TIMING_RECEIVED_FROM_ECU,\n            CP_STMIN_SUG,\n            CP_BLOCKSIZE_SUG,\n            CP_P2_TIMEOUT,\n            CP_S3_TP_PHYS_TIMER,\n            CP_S3_TP_FUNC_TIMER,\n            CP_BR_SUG,\n            CP_CAN_TRANSMIT,\n            CP_BS_MAX,\n            CP_CS_MAX,\n            CPI_ROUTINECOUNTER,\n            CP_REQREPCOUNT,\n            // looks like outliers?\n            CP_P2_EXT_TIMEOUT_7F_78,\n            CP_P2_EXT_TIMEOUT_7F_21,\n        }\n\n        public string Qualifier;\n        public int Name_CTF;\n        public int Description_CTF;\n\n        public int Unk3;\n        public int Unk4;\n\n        public int Unk5;\n        public int Unk6;\n        public int Unk7;\n\n        public int Unk8;\n        public int Unk9;\n        public int Unk10; // might be signed\n\n        private long BaseAddress;\n        private int Index;\n\n        public List<ComParameter> CommunicationParameters = new List<ComParameter>();\n        private CTFLanguage Language;\n\n        public void Restore(CTFLanguage language) \n        {\n            Language = language;\n            foreach (ComParameter cp in CommunicationParameters) \n            {\n                cp.Restore(language);\n            }\n        }\n\n        public ECUInterfaceSubtype() { }\n\n        public ECUInterfaceSubtype(BinaryReader reader, long baseAddress, int index, CTFLanguage language)\n        {\n            Index = index;\n            BaseAddress = baseAddress;\n            Language = language;\n            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);\n            // we can now properly operate on the interface block\n            ulong ctBitflags = reader.ReadUInt32();\n\n            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref ctBitflags, reader, BaseAddress);\n            Name_CTF = CaesarReader.ReadBitflagInt32(ref ctBitflags, reader, -1);\n            Description_CTF = CaesarReader.ReadBitflagInt32(ref ctBitflags, reader, -1);\n\n            Unk3 = CaesarReader.ReadBitflagInt16(ref ctBitflags, reader);\n            Unk4 = CaesarReader.ReadBitflagInt16(ref ctBitflags, reader);\n\n            Unk5 = CaesarReader.ReadBitflagInt32(ref ctBitflags, reader);\n            Unk6 = CaesarReader.ReadBitflagInt32(ref ctBitflags, reader);\n            Unk7 = CaesarReader.ReadBitflagInt32(ref ctBitflags, reader);\n\n            Unk8 = CaesarReader.ReadBitflagUInt8(ref ctBitflags, reader);\n            Unk9 = CaesarReader.ReadBitflagUInt8(ref ctBitflags, reader);\n            Unk10 = CaesarReader.ReadBitflagInt8(ref ctBitflags, reader); // might be signed\n        }\n\n        public ComParameter GetComParameterByName(string paramName) \n        {\n            return CommunicationParameters.Find(x => x.ParamName == paramName);\n        }\n        public int GetComParameterValue(ParamName name)\n        {\n            return GetComParameterByName(name.ToString()).ComParamValue;\n        }\n        public bool GetComParameterValue(ParamName name, out int result)\n        {\n            ComParameter param = GetComParameterByName(name.ToString());\n            if (param is null)\n            {\n                result = 0;\n                return false;\n            }\n            else \n            {\n                result = param.ComParamValue;\n                return true;\n            }\n        }\n\n        public void PrintDebug()\n        {\n            Console.WriteLine($\"iface subtype: @ 0x{BaseAddress:X}\");\n            Console.WriteLine($\"{nameof(Name_CTF)} : {Name_CTF}\");\n            Console.WriteLine($\"{nameof(Description_CTF)} : {Description_CTF}\");\n            Console.WriteLine($\"{nameof(Unk3)} : {Unk3}\");\n            Console.WriteLine($\"{nameof(Unk4)} : {Unk4}\");\n            Console.WriteLine($\"{nameof(Unk5)} : {Unk5}\");\n            Console.WriteLine($\"{nameof(Unk6)} : {Unk6}\");\n            Console.WriteLine($\"{nameof(Unk7)} : {Unk7}\");\n            Console.WriteLine($\"{nameof(Unk8)} : {Unk8}\");\n            Console.WriteLine($\"{nameof(Unk9)} : {Unk9}\");\n            Console.WriteLine($\"{nameof(Unk10)} : {Unk10}\");\n            Console.WriteLine($\"CT: {Qualifier}\");\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/ECUVariant.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Caesar\n{\n    public class ECUVariant\n    {\n        public string Qualifier;\n        public int Name_CTF;\n        public int Description_CTF;\n        public string UnkStr1;\n        public string UnkStr2;\n        public int Unk1;\n        \n        private int MatchingPatternCount; // A\n        private int MatchingPatternOffset;\n        private int SubsectionB_Count; // B\n        private int SubsectionB_Offset;\n        private int ComParamsCount; // C\n        private int ComParamsOffset;\n        private int DiagServiceCode_Count; // D : DSC\n        private int DiagServiceCode_Offset;\n        private int DiagServicesCount; // E\n        private int DiagServicesOffset;\n        private int DTC_Count; // F\n        private int DTC_Offset;\n        private int EnvironmentCtx_Count; // G\n        private int EnvironmentCtx_Offset;\n        private int Xref_Count; // H\n        private int Xref_Offset;\n        private int VCDomainsCount; // I\n        private int VCDomainsOffset;\n\n        public string NegativeResponseName;\n        public int UnkByte;\n\n        public List<int> VCDomainPoolOffsets = new List<int>();\n        public List<int> DiagServicesPoolOffsets = new List<int>();\n        public List<Tuple<int, int, int>> DTCsPoolOffsetsWithBounds = new List<Tuple<int, int, int>>();\n        public List<int> EnvironmentContextsPoolOffsets = new List<int>();\n\n        public List<ECUVariantPattern> VariantPatterns = new List<ECUVariantPattern>();\n        public int[] Xrefs = new int[] { };\n\n        // these should be manually deserialized by creating references back to the parent ECU\n\n        [Newtonsoft.Json.JsonIgnore]\n        public List<VCDomain> VCDomains = new List<VCDomain>();\n        [Newtonsoft.Json.JsonIgnore]\n        public DiagService[] DiagServices = new DiagService[] { };\n        [Newtonsoft.Json.JsonIgnore]\n        public DTC[] DTCs = new DTC[] { };\n        [Newtonsoft.Json.JsonIgnore]\n        public DiagService[] EnvironmentContexts = new DiagService[] { };\n\n        public long BaseAddress;\n        [Newtonsoft.Json.JsonIgnore]\n        public ECU ParentECU;\n\n        [Newtonsoft.Json.JsonIgnore]\n        private CTFLanguage Language;\n\n        public void Restore(CTFLanguage language, ECU parentEcu) \n        {\n            Language = language;\n            ParentECU = parentEcu;\n\n            CreateVCDomains(parentEcu, language);\n            CreateDiagServices(parentEcu, language);\n            CreateDTCs(parentEcu, language);\n            CreateEnvironmentContexts(parentEcu, language);\n\n            /*\n            // no restoring required\n            foreach (ECUVariantPattern vp in VariantPatterns) \n            {\n                vp.Restore();\n            }\n            */\n            // CreateComParameters(reader, parentEcu); // already serialized in json\n        }\n\n        public ECUVariant() { }\n\n        public ECUVariant(BinaryReader reader, ECU parentEcu, CTFLanguage language, long baseAddress, int blockSize)\n        {\n            // int __usercall DIIFindVariantByECUID@<eax>(ECU_VARIANT *a1@<ebx>, _DWORD *a2, int a3, __int16 a4, int a5)\n\n            BaseAddress = baseAddress;\n            ParentECU = parentEcu;\n            Language = language;\n            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);\n            byte[] variantBytes = reader.ReadBytes(blockSize);\n\n            using (BinaryReader variantReader = new BinaryReader(new MemoryStream(variantBytes, 0, variantBytes.Length, false, true)))\n            {\n                ulong bitFlags = variantReader.ReadUInt32();\n                int skip = variantReader.ReadInt32();\n\n                Qualifier = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, variantReader);\n                Name_CTF = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader, -1);\n                Description_CTF = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader, -1);\n                UnkStr1 = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, variantReader);\n                UnkStr2 = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, variantReader);\n\n                Unk1 = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 1 \n                MatchingPatternCount = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 2 \n                MatchingPatternOffset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 3 \n                SubsectionB_Count = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 4 \n                SubsectionB_Offset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 5 \n                ComParamsCount = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 6 \n                ComParamsOffset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 7 \n                DiagServiceCode_Count = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 8 \n                DiagServiceCode_Offset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 9 \n                DiagServicesCount = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 10 \n                DiagServicesOffset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 11 \n                DTC_Count = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 12 \n                DTC_Offset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 13 \n                EnvironmentCtx_Count = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 14\n                EnvironmentCtx_Offset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 15 \n                Xref_Count = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 16\n                Xref_Offset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 17 \n\n                VCDomainsCount = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 18 \n                VCDomainsOffset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader);  // 19 \n\n                NegativeResponseName = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, variantReader);\n                UnkByte = CaesarReader.ReadBitflagInt8(ref bitFlags, variantReader);  // 20 byte\n\n                // vcdomain\n                VCDomainPoolOffsets = new List<int>();\n                variantReader.BaseStream.Seek(VCDomainsOffset, SeekOrigin.Begin);\n                for (int variantCodingIndex = 0; variantCodingIndex < VCDomainsCount; variantCodingIndex++)\n                {\n                    VCDomainPoolOffsets.Add(variantReader.ReadInt32());\n                }\n                // diagnostic services\n                DiagServicesPoolOffsets = new List<int>();\n                variantReader.BaseStream.Seek(DiagServicesOffset, SeekOrigin.Begin);\n                for (int diagIndex = 0; diagIndex < DiagServicesCount; diagIndex++)\n                {\n                    DiagServicesPoolOffsets.Add(variantReader.ReadInt32());\n                }\n                // DTCs\n                //DTCsPoolOffsets = new List<int>();\n                DTCsPoolOffsetsWithBounds = new List<Tuple<int, int, int>>();\n                variantReader.BaseStream.Seek(DTC_Offset, SeekOrigin.Begin);\n                for (int dtcIndex = 0; dtcIndex < DTC_Count; dtcIndex++)\n                {\n                    int actualIndex = variantReader.ReadInt32();\n                    int xrefStart = variantReader.ReadInt32(); \n                    int xrefCount = variantReader.ReadInt32(); // stitch with table H : int __cdecl DIECUGetNumberOfEnvForAllErrors(DI_ECUINFO *ecuh, int a2, int a3)\n                    //DTCsPoolOffsets.Add(actualIndex); // todo: depreciate this\n                    DTCsPoolOffsetsWithBounds.Add(new Tuple<int, int, int>(actualIndex, xrefStart, xrefCount));\n                }\n                // EnvCtxs\n                EnvironmentContextsPoolOffsets = new List<int>();\n                variantReader.BaseStream.Seek(EnvironmentCtx_Offset, SeekOrigin.Begin);\n                for (int envIndex = 0; envIndex < EnvironmentCtx_Count; envIndex++)\n                {\n                    EnvironmentContextsPoolOffsets.Add(variantReader.ReadInt32());\n                }\n            }\n\n            CreateVCDomains(parentEcu, language);\n            CreateDiagServices(parentEcu, language);\n            CreateVariantPatterns(reader);\n            CreateComParameters(reader, parentEcu);\n            CreateDTCs(parentEcu, language);\n            CreateEnvironmentContexts(parentEcu, language);\n            CreateXrefs(reader, parentEcu, language);\n            //PrintDebug();\n        }\n\n        // this function is parked here since the values are drawn from EnvironmentContexts // Xref_Count and Xref_Offset;\n        public List<DiagService> GetEnvironmentContextsForDTC(DTC inDtc)\n        {\n            List<DiagService> ctxList = new List<DiagService>();\n\n            for (int i = inDtc.XrefStart; i < (inDtc.XrefStart + inDtc.XrefCount); i++) \n            {\n                foreach (DiagService envToTest in EnvironmentContexts) \n                {\n                    int xref = Xrefs[i];\n                    if (envToTest.PoolIndex == xref)\n                    {\n                        ctxList.Add(envToTest);\n                        break;\n                    }\n                }\n            }\n            return ctxList;\n        }\n\n        public void CreateComParameters(BinaryReader reader, ECU parentEcu)\n        {\n            // this is unusual as it doesn't use the usual caesar-style bitflag reads\n            // for reasons unknown the comparam is attached to the basevariant\n            long comparamBaseAddress = BaseAddress + ComParamsOffset;\n            // Console.WriteLine($\"Comparam base: 0x{comparamBaseAddress:X} : number of comparams: {ComParamsCount} \");\n            reader.BaseStream.Seek(comparamBaseAddress, SeekOrigin.Begin);\n            List<long> comparameterOffsets = new List<long>();\n            for (int comIndex = 0; comIndex < ComParamsCount; comIndex++)\n            {\n                comparameterOffsets.Add(reader.ReadInt32() + comparamBaseAddress);\n            }\n\n            if (parentEcu.ECUInterfaces.Count == 0)\n            {\n                throw new Exception(\"Invalid communication parameter : no parent interface\");\n            }\n\n            foreach (long comparamOffset in comparameterOffsets)\n            {\n                ComParameter param = new ComParameter(reader, comparamOffset, parentEcu.ECUInterfaces, Language);\n\n                // KW2C3PE uses a different parent addressing style\n                int parentIndex = param.ParentInterfaceIndex > 0 ? param.ParentInterfaceIndex : param.SubinterfaceIndex;\n\n                if (param.ParentInterfaceIndex >= parentEcu.ECUInterfaceSubtypes.Count)\n                {\n                    throw new Exception(\"ComParam: tried to assign to nonexistent interface\");\n                }\n                else\n                {\n                    parentEcu.ECUInterfaceSubtypes[parentIndex].CommunicationParameters.Add(param);\n                }\n            }\n        }\n\n        public void CreateVariantPatterns(BinaryReader reader) \n        {\n            long tableOffset = BaseAddress + MatchingPatternOffset;\n            reader.BaseStream.Seek(tableOffset, SeekOrigin.Begin);\n\n            VariantPatterns.Clear();\n            for (int patternIndex = 0; patternIndex < MatchingPatternCount; patternIndex++) \n            {\n                reader.BaseStream.Seek(tableOffset + (patternIndex * 4), SeekOrigin.Begin);\n                int patternOffset = reader.ReadInt32();\n                long patternAddress = patternOffset + tableOffset;\n\n                ECUVariantPattern pattern = new ECUVariantPattern(reader, patternAddress);\n                VariantPatterns.Add(pattern);\n            }\n        }\n\n        public VCDomain GetVCDomainByName(string name)\n        {\n            foreach (VCDomain domain in VCDomains)\n            {\n                if (domain.Qualifier == name)\n                {\n                    return domain;\n                }\n            }\n            return null;\n        }\n        public DiagService GetDiagServiceByName(string name)\n        {\n            foreach (DiagService diag in DiagServices)\n            {\n                if (diag.Qualifier == name)\n                {\n                    return diag;\n                }\n            }\n            return null;\n        }\n        public string[] GetVCDomainNames()\n        {\n            List<string> result = new List<string>();\n            foreach (VCDomain domain in VCDomains)\n            {\n                result.Add(domain.Qualifier);\n            }\n            return result.ToArray();\n        }\n\n        private void CreateVCDomains(ECU parentEcu, CTFLanguage language)\n        {\n            VCDomains = new List<VCDomain>();\n            foreach (int variantCodingDomainEntry in VCDomainPoolOffsets)\n            {\n                /*\n                VCDomain vcDomain = new VCDomain(reader, parentEcu, language, variantCodingDomainEntry);\n                VCDomains.Add(vcDomain);\n                */\n                VCDomains.Add(ParentECU.GlobalVCDs[variantCodingDomainEntry]);\n            }\n        }\n        private void CreateDiagServices(ECU parentEcu, CTFLanguage language)\n        {\n            // unlike variant domains, storing references to the parent objects in the ecu is preferable since this is relatively larger\n            //DiagServices = new List<DiagService>();\n\n            DiagServices = new DiagService[DiagServicesPoolOffsets.Count];\n\n            /*\n            // computationally expensive, 40ish % runtime is spent here\n            // easier to read, below optimization essentially accomplishes this in a shorter period\n\n            foreach (DiagService diagSvc in parentEcu.GlobalDiagServices)\n            {\n                for (int i = 0; i < DiagServicesPoolOffsets.Count; i++)\n                {\n                    if (diagSvc.PoolIndex == DiagServicesPoolOffsets[i])\n                    {\n                        DiagServices[i] = diagSvc;\n                    }\n                }\n            }\n            */\n            // optimization hack\n            int poolSize = DiagServicesPoolOffsets.Count;\n            for (int i = 0; i < poolSize; i++) \n            {\n                if (i == DiagServicesPoolOffsets[i])\n                {\n                    DiagServices[i] = parentEcu.GlobalDiagServices[i];\n                }\n            }\n            DiagServicesPoolOffsets.Sort();\n            int lowestIndex = 0;\n            int loopMax = parentEcu.GlobalDiagServices.Count;\n            for (int i = 0; i < poolSize; i++)\n            {\n                if (DiagServices[i] != null) \n                {\n                    continue;\n                }\n                for (int globalIndex = lowestIndex; globalIndex < loopMax; globalIndex++)\n                {\n                    if (parentEcu.GlobalDiagServices[globalIndex].PoolIndex == DiagServicesPoolOffsets[i])\n                    {\n                        DiagServices[i] = parentEcu.GlobalDiagServices[globalIndex];\n                        lowestIndex = globalIndex;\n                        break;\n                    }\n                }\n            }\n        }\n        private void CreateDTCs(ECU parentEcu, CTFLanguage language)\n        {\n            int dtcPoolSize = DTCsPoolOffsetsWithBounds.Count;\n            DTCs = new DTC[dtcPoolSize];\n\n            for (int i = 0; i < dtcPoolSize; i++) \n            {\n                if (i == DTCsPoolOffsetsWithBounds[i].Item1) \n                {\n                    DTCs[i] = parentEcu.GlobalDTCs[i];\n                    DTCs[i].XrefStart = DTCsPoolOffsetsWithBounds[i].Item2;\n                    DTCs[i].XrefCount = DTCsPoolOffsetsWithBounds[i].Item3;\n                }\n            }\n            DTCsPoolOffsetsWithBounds.Sort((x, y) => x.Item1.CompareTo(y.Item1));\n            int lowestIndex = 0;\n            int loopMax = ParentECU.GlobalDTCs.Count;\n            for (int i = 0; i < dtcPoolSize; i++) \n            {\n                if (DTCs[i] != null)\n                {\n                    continue;\n                }\n                for (int globalIndex = lowestIndex; globalIndex < loopMax; globalIndex++)\n                {\n                    if (ParentECU.GlobalDTCs[globalIndex].PoolIndex == DTCsPoolOffsetsWithBounds[i].Item1) \n                    {\n                        DTCs[i] = parentEcu.GlobalDTCs[globalIndex];\n                        DTCs[i].XrefStart = DTCsPoolOffsetsWithBounds[i].Item2;\n                        DTCs[i].XrefCount = DTCsPoolOffsetsWithBounds[i].Item3;\n                        lowestIndex = globalIndex;\n                        break;\n                    }\n                }\n            }\n\n            /*\n            // same thing as above, just more readable and slower\n            foreach (DTC dtc in parentEcu.GlobalDTCs)\n            {\n                for (int i = 0; i < DTCsPoolOffsetsWithBounds.Count; i++)\n                {\n                    if (dtc.PoolIndex == DTCsPoolOffsetsWithBounds[i].Item1)\n                    {\n                        // this is only valid on the assumption that DTC instances are unique (e.g. not shared from a base variant)\n                        dtc.XrefStart = DTCsPoolOffsetsWithBounds[i].Item2;\n                        dtc.XrefCount = DTCsPoolOffsetsWithBounds[i].Item3;\n                        DTCs[i] = dtc;\n                    }\n                }\n            }\n            */\n        }\n        private void CreateXrefs(BinaryReader reader, ECU parentEcu, CTFLanguage language)\n        {\n            Xrefs = new int[Xref_Count];\n            reader.BaseStream.Seek(BaseAddress + Xref_Offset, SeekOrigin.Begin);\n            for (int i = 0; i < Xref_Count; i++)\n            {\n                Xrefs[i] = reader.ReadInt32();\n            }\n        }\n        private void CreateEnvironmentContexts(ECU parentEcu, CTFLanguage language)\n        {\n            int envPoolSize = EnvironmentContextsPoolOffsets.Count;\n            EnvironmentContexts = new DiagService[envPoolSize];\n\n            for (int i = 0; i < envPoolSize; i++)\n            {\n                if (i == EnvironmentContextsPoolOffsets[i])\n                {\n                    EnvironmentContexts[i] = parentEcu.GlobalEnvironmentContexts[i];\n                }\n            }\n            EnvironmentContextsPoolOffsets.Sort();\n            int lowestIndex = 0;\n            int loopMax = parentEcu.GlobalEnvironmentContexts.Count;\n            for (int i = 0; i < envPoolSize; i++)\n            {\n                if (EnvironmentContexts[i] != null)\n                {\n                    continue;\n                }\n                for (int globalIndex = lowestIndex; globalIndex < loopMax; globalIndex++)\n                {\n                    if (parentEcu.GlobalEnvironmentContexts[globalIndex].PoolIndex == EnvironmentContextsPoolOffsets[i])\n                    {\n                        EnvironmentContexts[i] = parentEcu.GlobalEnvironmentContexts[globalIndex];\n                        lowestIndex = globalIndex;\n                        break;\n                    }\n                }\n            }\n            /*\n            // same thing, more readable, much slower\n            foreach (DiagService env in parentEcu.GlobalEnvironmentContexts)\n            {\n                for (int i = 0; i < EnvironmentContextsPoolOffsets.Count; i++)\n                {\n                    if (env.PoolIndex == EnvironmentContextsPoolOffsets[i])\n                    {\n                        EnvironmentContexts[i] = env;\n                    }\n                }\n            }\n            */\n        }\n\n        public void PrintDebug() \n        {\n            Console.WriteLine($\"---------------- {BaseAddress:X} ----------------\");\n            Console.WriteLine($\"{nameof(Qualifier)} : {Qualifier}\");\n            Console.WriteLine($\"{nameof(Name_CTF)} : {Name_CTF}\");\n            Console.WriteLine($\"{nameof(Description_CTF)} : {Description_CTF}\");\n            Console.WriteLine($\"{nameof(UnkStr1)} : {UnkStr1}\");\n            Console.WriteLine($\"{nameof(UnkStr2)} : {UnkStr2}\");\n            Console.WriteLine($\"{nameof(VCDomainsCount)} : {VCDomainsCount}\");\n            Console.WriteLine($\"{nameof(VCDomainsOffset)} : {VCDomainsOffset}\");\n            Console.WriteLine($\"{nameof(NegativeResponseName)} : {NegativeResponseName}\");\n\n            Console.WriteLine($\"{nameof(Unk1)} : {Unk1}\");\n            Console.WriteLine($\"{nameof(MatchingPatternCount)} : {MatchingPatternCount}\");\n            Console.WriteLine($\"{nameof(MatchingPatternOffset)} : {MatchingPatternOffset}\");\n            Console.WriteLine($\"{nameof(SubsectionB_Count)} : {SubsectionB_Count}\");\n            Console.WriteLine($\"{nameof(SubsectionB_Offset)} : {SubsectionB_Offset}\");\n            Console.WriteLine($\"{nameof(ComParamsCount)} : {ComParamsCount}\");\n            Console.WriteLine($\"{nameof(ComParamsOffset)} : {ComParamsOffset}\");\n            Console.WriteLine($\"{nameof(DiagServiceCode_Count)} : {DiagServiceCode_Count}\");\n            Console.WriteLine($\"{nameof(DiagServiceCode_Offset)} : {DiagServiceCode_Offset}\");\n            Console.WriteLine($\"{nameof(DiagServicesCount)} : {DiagServicesCount}\");\n            Console.WriteLine($\"{nameof(DiagServicesOffset)} : {DiagServicesOffset}\");\n            Console.WriteLine($\"{nameof(DTC_Count)} : {DTC_Count}\");\n            Console.WriteLine($\"{nameof(DTC_Offset)} : {DTC_Offset}\");\n            Console.WriteLine($\"{nameof(EnvironmentCtx_Count)} : {EnvironmentCtx_Count}\");\n            Console.WriteLine($\"{nameof(EnvironmentCtx_Offset)} : {EnvironmentCtx_Offset}\");\n            Console.WriteLine($\"{nameof(Xref_Count)} : {Xref_Count}\");\n            Console.WriteLine($\"{nameof(Xref_Offset)} : {Xref_Offset}\");\n            Console.WriteLine($\"{nameof(VCDomainsCount)} : {VCDomainsCount}\");\n            Console.WriteLine($\"{nameof(VCDomainsOffset)} : {VCDomainsOffset}\");\n\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/ECUVariantPattern.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.IO;\nusing System.Diagnostics;\n\nnamespace Caesar\n{\n    public class ECUVariantPattern\n    {\n\n        public int UnkBufferSize;\n\n        public byte[] UnkBuffer;\n        public int Unk3;\n        public int Unk4;\n        public int Unk5;\n        public string VendorName;\n\n        public int KwpVendorID;\n        public int Unk8;\n        public int Unk9;\n        public int Unk10;\n\n        public int Unk11;\n        public int Unk12;\n        public int Unk13;\n        public int Unk14;\n        public int Unk15;\n\n        public byte[] EcuId;\n\n        public int Unk17;\n        public int Unk18;\n        public int Unk19;\n        public int Unk20;\n\n        public string Unk21;\n\n        public int Unk22;\n        public int Unk23;\n        public int UdsVendorID;\n        public int PatternType;\n\n        public int VariantID;\n\n        private readonly long BaseAddress;\n\n        public void Restore() \n        {\n        \n        }\n\n        public ECUVariantPattern() { }\n\n        public ECUVariantPattern(BinaryReader reader, long baseAddress) \n        {\n            BaseAddress = baseAddress;\n            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);\n            ulong bitflags = reader.ReadUInt32();\n\n            UnkBufferSize = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            UnkBuffer = CaesarReader.ReadBitflagDumpWithReader(ref bitflags, reader, UnkBufferSize, baseAddress);\n            Unk3 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            Unk4 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            Unk5 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            VendorName = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);\n\n            KwpVendorID = CaesarReader.ReadBitflagUInt16(ref bitflags, reader);\n            Unk8 = CaesarReader.ReadBitflagInt16(ref bitflags, reader);\n            Unk9 = CaesarReader.ReadBitflagInt16(ref bitflags, reader);\n            Unk10 = CaesarReader.ReadBitflagInt16(ref bitflags, reader);\n\n            Unk11 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader);\n            Unk12 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader);\n            Unk13 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader);\n            Unk14 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader);\n            Unk15 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader);\n\n            EcuId = CaesarReader.ReadBitflagRawBytes(ref bitflags, reader, 4);\n\n            Unk17 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader);\n            Unk18 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader);\n            Unk19 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader);\n            Unk20 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader);\n\n            Unk21 = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);\n\n            Unk22 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            Unk23 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            UdsVendorID = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            PatternType = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            VariantID = UdsVendorID == 0 ? KwpVendorID : UdsVendorID;\n            // type 3 contains a vendor name\n\n        }\n\n        public void PrintDebug() \n        {\n            Console.WriteLine($\"UnkBufferSize : {UnkBufferSize}\");\n            Console.WriteLine($\"UnkBuffer : {UnkBuffer}\");\n            Console.WriteLine($\"Unk3 : {Unk3}\");\n            Console.WriteLine($\"Unk4 : {Unk4}\");\n            Console.WriteLine($\"Unk5 : {Unk5}\");\n            Console.WriteLine($\"VendorName : {VendorName}\");\n            Console.WriteLine($\"Unk7 : {KwpVendorID}\");\n            Console.WriteLine($\"Unk8 : {Unk8}\");\n            Console.WriteLine($\"Unk9 : {Unk9}\");\n            Console.WriteLine($\"Unk10 : {Unk10}\");\n            Console.WriteLine($\"Unk11 : {Unk11}\");\n            Console.WriteLine($\"Unk12 : {Unk12}\");\n            Console.WriteLine($\"Unk13 : {Unk13}\");\n            Console.WriteLine($\"Unk14 : {Unk14}\");\n            Console.WriteLine($\"Unk15 : {Unk15}\");\n            Console.WriteLine($\"EcuId : {EcuId}\");\n            Console.WriteLine($\"Unk17 : {Unk17}\");\n            Console.WriteLine($\"Unk18 : {Unk18}\");\n            Console.WriteLine($\"Unk19 : {Unk19}\");\n            Console.WriteLine($\"Unk20 : {Unk20}\");\n            Console.WriteLine($\"Unk21 : {Unk21}\");\n            Console.WriteLine($\"Unk22 : {Unk22}\");\n            Console.WriteLine($\"Unk23 : {Unk23}\");\n            Console.WriteLine($\"VariantID : {VariantID}\");\n            Console.WriteLine($\"PatternType : {PatternType}\");\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/Flash/CaesarFlashContainer.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Caesar\n{\n    public class CaesarFlashContainer\n    {\n        public FlashHeader CaesarFlashHeader;\n        public CTFHeader CaesarCTFHeader;\n\n        public byte[] FileBytes = new byte[] { };\n        public CaesarFlashContainer(byte[] fileBytes)\n        {\n            FileBytes = fileBytes;\n            // from DIOpenCFF\n            using (BinaryReader reader = new BinaryReader(new MemoryStream(fileBytes, 0, FileBytes.Length, false, true)))\n            {\n                byte[] header = reader.ReadBytes(StubHeader.StubHeaderSize);\n\n                int cffHeaderSize = reader.ReadInt32();\n                byte[] cffHeaderData = reader.ReadBytes(cffHeaderSize);\n\n                uint computedChecksum = CaesarReader.ComputeFileChecksumLazy(fileBytes);\n                uint providedChecksum = ReadFileChecksum(fileBytes);\n\n                if (computedChecksum != providedChecksum)\n                {\n                    Console.WriteLine($\"WARNING: Checksum mismatch : computed/provided: {computedChecksum:X8}/{providedChecksum:X8}\");\n                }\n                ReadFlashCFF(reader); // fix this\n                ReadCTF(reader);\n            }\n        }\n        void ReadCTF(BinaryReader fileReader)\n        {\n            if (CaesarFlashHeader.CTFHeaderTable == 0)\n            {\n                throw new NotImplementedException(\"No idea how to handle nonexistent ctf header\");\n            }\n            long ctfOffset = CaesarFlashHeader.BaseAddress + CaesarFlashHeader.CTFHeaderTable;\n            CaesarCTFHeader = new CTFHeader(fileReader, ctfOffset, CaesarFlashHeader.CffHeaderSize);\n        }\n\n\n        public uint ReadFileChecksum(byte[] fileBytes)\n        {\n            return BitConverter.ToUInt32(fileBytes, fileBytes.Length - 4);\n        }\n\n        void ReadFlashCFF(BinaryReader fileReader)\n        {\n            CaesarFlashHeader = new FlashHeader(fileReader);\n        }\n\n        public static void ExportCFFMemorySegments(string filePath) \n        {\n            string directory = Path.GetDirectoryName(filePath);\n\n            Console.WriteLine($\"Starting CFF segment export. Assumes that segments are embedded and unprotected.\");\n            byte[] flashContainer = File.ReadAllBytes(filePath);\n            CaesarFlashContainer container = new CaesarFlashContainer(flashContainer);\n\n            // mini-feature: if a binary with enough space exists, the image's data will be written to it (for some CFFs with many segments, this saves time)\n            string mergePath = @\"merge.bin\";\n            bool useMergeFeature = File.Exists(mergePath);\n            byte[] mergeBytes = new byte[] { };\n            if (useMergeFeature) \n            {\n                mergeBytes = File.ReadAllBytes(mergePath);\n            }\n\n            using (BinaryReader reader = new BinaryReader(new MemoryStream(flashContainer)))\n            {\n                foreach (FlashDataBlock db in container.CaesarFlashHeader.DataBlocks)\n                {\n                    Console.WriteLine($\"FlashDataBlock: {db.Qualifier}\");\n                    long fileCursor = 0;\n                    foreach (FlashSegment seg in db.FlashSegments)\n                    {\n                        long offset = \n                            db.FlashData + \n                            container.CaesarFlashHeader.CffHeaderSize +\n                            container.CaesarFlashHeader.LanguageBlockLength + \n                            fileCursor + \n                            0x414;\n\n                        fileCursor += seg.SegmentLength;\n                        Console.WriteLine($\"Segment: {seg.SegmentName} mapped to 0x{seg.FromAddress:X} with size 0x{seg.SegmentLength:X}\");\n                        reader.BaseStream.Seek(offset, SeekOrigin.Begin);\n                        byte[] fileBytes = reader.ReadBytes(seg.SegmentLength);\n\n                        File.WriteAllBytes($\"{directory}\\\\{db.Qualifier}_{seg.FromAddress:X}.bin\", fileBytes);\n\n                        if (useMergeFeature)\n                        {\n                            if ((mergeBytes.Length >= (seg.FromAddress + fileBytes.Length)))\n                            {\n                                for (int i = 0; i < fileBytes.Length; i++)\n                                {\n                                    mergeBytes[i + seg.FromAddress] |= fileBytes[i];\n                                }\n                            }\n                            else \n                            {\n                                Console.WriteLine($\"Out-of-bound merge, skipping {seg.SegmentName} mapped to 0x{seg.FromAddress:X} with size 0x{seg.SegmentLength:X}\");\n                            }\n                        }\n                    }\n                }\n            }\n            Console.WriteLine($\"Exported segments can be found at {directory}\");\n            if (useMergeFeature) \n            {\n                File.WriteAllBytes(mergePath, mergeBytes);\n            }\n        }\n\n        public void SpliceCFFFile(string filePath)\n        {\n            string directory = Path.GetDirectoryName(filePath);\n\n            Console.WriteLine($\"Starting CFF splicer..\");\n            byte[] flashContainer = File.ReadAllBytes(filePath);\n            CaesarFlashContainer container = new CaesarFlashContainer(flashContainer);\n\n            using (BinaryReader reader = new BinaryReader(new MemoryStream(flashContainer)))\n            {\n                foreach (FlashDataBlock db in container.CaesarFlashHeader.DataBlocks)\n                {\n                    Console.WriteLine($\"FlashDataBlock: {db.Qualifier}\");\n                    long fileCursor = 0;\n                    foreach (FlashSegment seg in db.FlashSegments)\n                    {\n                        // check: which fields are mutable when splicing\n\n                        long offset =\n                            db.FlashData + // somewhat mutable : probably if there's more than 1 datablock, this value will be nonzero\n                            container.CaesarFlashHeader.CffHeaderSize + // constant\n                            container.CaesarFlashHeader.LanguageBlockLength + // constant\n                            fileCursor + // mutable, see below\n                            0x414; // constant\n\n                        fileCursor += seg.SegmentLength; // mutable because of segment length\n\n                        Console.WriteLine($\"Segment: {seg.SegmentName} mapped to 0x{seg.FromAddress:X} with size 0x{seg.SegmentLength:X}\");\n                        reader.BaseStream.Seek(offset, SeekOrigin.Begin);\n                        byte[] fileBytes = reader.ReadBytes(seg.SegmentLength);\n\n                        File.WriteAllBytes($\"{directory}\\\\{db.Qualifier}_{seg.FromAddress:X}.bin\", fileBytes);\n                    }\n                }\n            }\n            Console.WriteLine($\"Exported segments can be found at {directory}\");\n        }\n\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/Flash/FlashDataBlock.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Caesar\n{\n    public class FlashDataBlock\n    {\n\n        // 0x16 [6,  4,4,4,4,  4,4,4,4,  4,4,4,2,  4,4,4,4,  4,4,4,4,  4,4,4,4,4],\n        public string Qualifier;\n        public int LongName;\n        public int Description;\n        public int FlashData;\n        public int BlockLength;\n        public int DataFormat;\n        public int FileName;\n        public int NumberOfFilters;\n        public int FiltersOffset;\n        public int NumberOfSegments;\n        public int SegmentOffset;\n        public int EncryptionMode;\n        public int KeyLength;\n        public int KeyBuffer;\n        public int NumberOfOwnIdents;\n        public int IdentsOffset;\n        public int NumberOfSecurities;\n        public int SecuritiesOffset;\n        public string DataBlockType;\n        public int UniqueObjectId;\n        public string FlashDataInfoQualifier;\n        public int FlashDataInfoLongName;\n        public int FlashDataInfoDescription;\n        public int FlashDataInfoUniqueObjectId;\n\n        public long BaseAddress;\n        public List<FlashSegment> FlashSegments = new List<FlashSegment>();\n        public List<FlashSecurity> FlashSecurities = new List<FlashSecurity>();\n\n        public FlashDataBlock(BinaryReader reader, long baseAddress)\n        {\n            BaseAddress = baseAddress;\n            reader.BaseStream.Seek(BaseAddress, SeekOrigin.Begin);\n            \n            ulong bitflags = reader.ReadUInt32();\n            reader.ReadUInt16();\n\n            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, BaseAddress);\n            LongName = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            Description = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            FlashData = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            BlockLength = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            DataFormat = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            FileName = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            NumberOfFilters = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            FiltersOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            NumberOfSegments = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            SegmentOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            EncryptionMode = CaesarReader.ReadBitflagInt16(ref bitflags, reader);\n\n            KeyLength = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            KeyBuffer = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            NumberOfOwnIdents = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            IdentsOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            NumberOfSecurities = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            SecuritiesOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            DataBlockType = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, BaseAddress);\n            UniqueObjectId = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            FlashDataInfoQualifier = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, BaseAddress);\n            FlashDataInfoLongName = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            FlashDataInfoDescription = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            FlashDataInfoUniqueObjectId = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n\n            // CtfUnk1 = CaesarReader.ReadBitflagInt32(ref ctfBitflags, reader);\n            FlashSegments = new List<FlashSegment>();\n            for (int segmentIndex = 0; segmentIndex < NumberOfSegments; segmentIndex++) \n            {\n                long segmentEntryAddress = SegmentOffset + BaseAddress + (segmentIndex * 4);\n                reader.BaseStream.Seek(segmentEntryAddress, SeekOrigin.Begin);\n\n                long segmentBaseAddress = SegmentOffset + BaseAddress + reader.ReadInt32();\n\n                FlashSegment segment = new FlashSegment(reader, segmentBaseAddress);\n                FlashSegments.Add(segment);\n            }\n\n            FlashSecurities = new List<FlashSecurity>();\n            for (int securitiesIndex = 0; securitiesIndex < NumberOfSecurities; securitiesIndex++)\n            {\n                long securitiesEntryAddress = SecuritiesOffset + BaseAddress + (securitiesIndex * 4);\n                reader.BaseStream.Seek(securitiesEntryAddress, SeekOrigin.Begin);\n\n                long securitiesBaseAddress = SecuritiesOffset + BaseAddress + reader.ReadInt32();\n                FlashSecurity security = new FlashSecurity(reader, securitiesBaseAddress);\n                FlashSecurities.Add(security);\n            }\n\n        }\n\n\n        public long GetBlockLengthOffset(BinaryReader reader)\n        {\n            reader.BaseStream.Seek(BaseAddress, SeekOrigin.Begin);\n\n            ulong bitflags = reader.ReadUInt32();\n            reader.ReadUInt16();\n\n            CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, BaseAddress); // Qualifier \n            CaesarReader.ReadBitflagInt32(ref bitflags, reader); // LongName \n            CaesarReader.ReadBitflagInt32(ref bitflags, reader); // Description \n            CaesarReader.ReadBitflagInt32(ref bitflags, reader); // FlashData \n\n            if (CaesarReader.CheckAndAdvanceBitflag(ref bitflags))\n            {\n                return reader.BaseStream.Position;\n            }\n            else\n            {\n                return -1;\n            }\n        }\n        public long GetFlashDataOffset(BinaryReader reader)\n        {\n            reader.BaseStream.Seek(BaseAddress, SeekOrigin.Begin);\n\n            ulong bitflags = reader.ReadUInt32();\n            reader.ReadUInt16();\n\n            CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, BaseAddress); // Qualifier \n            CaesarReader.ReadBitflagInt32(ref bitflags, reader); // LongName \n            CaesarReader.ReadBitflagInt32(ref bitflags, reader); // Description \n\n            if (CaesarReader.CheckAndAdvanceBitflag(ref bitflags))\n            {\n                return reader.BaseStream.Position;\n            }\n            else\n            {\n                return -1;\n            }\n        }\n\n        public void PrintDebug()\n        {\n            Console.WriteLine($\"{nameof(Qualifier)} : {Qualifier}\");\n            Console.WriteLine($\"{nameof(LongName)} : {LongName}\");\n            Console.WriteLine($\"{nameof(Description)} : {Description}\");\n            Console.WriteLine($\"{nameof(FlashData)} : {FlashData}\");\n            Console.WriteLine($\"{nameof(BlockLength)} : 0x{BlockLength:X}\");\n            Console.WriteLine($\"{nameof(DataFormat)} : {DataFormat}\");\n            Console.WriteLine($\"{nameof(FileName)} : {FileName}\");\n            Console.WriteLine($\"{nameof(NumberOfFilters)} : {NumberOfFilters}\");\n            Console.WriteLine($\"{nameof(FiltersOffset)} : {FiltersOffset}\");\n            Console.WriteLine($\"{nameof(NumberOfSegments)} : {NumberOfSegments}\");\n            Console.WriteLine($\"{nameof(SegmentOffset)} : {SegmentOffset}\");\n            Console.WriteLine($\"{nameof(EncryptionMode)} : {EncryptionMode}\");\n            Console.WriteLine($\"{nameof(KeyLength)} : {KeyLength}\");\n            Console.WriteLine($\"{nameof(KeyBuffer)} : {KeyBuffer}\");\n            Console.WriteLine($\"{nameof(NumberOfOwnIdents)} : {NumberOfOwnIdents}\");\n            Console.WriteLine($\"{nameof(IdentsOffset)} : {IdentsOffset}\");\n            Console.WriteLine($\"{nameof(NumberOfSecurities)} : {NumberOfSecurities}\");\n            Console.WriteLine($\"{nameof(SecuritiesOffset)} : {SecuritiesOffset}\");\n            Console.WriteLine($\"{nameof(DataBlockType)} : {DataBlockType}\");\n            Console.WriteLine($\"{nameof(UniqueObjectId)} : {UniqueObjectId}\");\n            Console.WriteLine($\"{nameof(FlashDataInfoQualifier)} : {FlashDataInfoQualifier}\");\n            Console.WriteLine($\"{nameof(FlashDataInfoLongName)} : {FlashDataInfoLongName}\");\n            Console.WriteLine($\"{nameof(FlashDataInfoDescription)} : {FlashDataInfoDescription}\");\n            Console.WriteLine($\"{nameof(FlashDataInfoUniqueObjectId)} : {FlashDataInfoUniqueObjectId}\");\n\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/Flash/FlashDescriptionHeader.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.IO;\n\nnamespace Caesar\n{\n    // FLASH_DESCRIPTION_HEADER\n    // 0x10: 4 :  4, 4, 4, 4,  4, 4, 4, 4,  4, 4, 4, 4\n    public class FlashDescriptionHeader\n    {\n        public string Qualifier;\n        public int Description;\n        public int FlashAreaName;\n        public int FlashTableStructureCount;\n        public int FlashTableStructureOffset;\n        public int NumberOfUploads;\n        public int UploadTableRefTable;\n        public int NumberOfIdentServices;\n        public int IdentServicesOffset;\n        public int UniqueObjectID;\n        public int unkb;\n        public int unkc;\n        public long BaseAddress;\n\n        public FlashDescriptionHeader(BinaryReader reader, long baseAddress) \n        {\n            BaseAddress = baseAddress;\n\n            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);\n            ulong flashBitFlags = reader.ReadUInt32();\n\n            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref flashBitFlags, reader, baseAddress);\n            Description = CaesarReader.ReadBitflagInt32(ref flashBitFlags, reader);\n            FlashAreaName = CaesarReader.ReadBitflagInt32(ref flashBitFlags, reader);\n            FlashTableStructureCount = CaesarReader.ReadBitflagInt32(ref flashBitFlags, reader);\n            FlashTableStructureOffset = CaesarReader.ReadBitflagInt32(ref flashBitFlags, reader);\n            NumberOfUploads = CaesarReader.ReadBitflagInt32(ref flashBitFlags, reader);\n            UploadTableRefTable = CaesarReader.ReadBitflagInt32(ref flashBitFlags, reader);\n            NumberOfIdentServices = CaesarReader.ReadBitflagInt32(ref flashBitFlags, reader);\n            IdentServicesOffset = CaesarReader.ReadBitflagInt32(ref flashBitFlags, reader);\n            UniqueObjectID = CaesarReader.ReadBitflagInt32(ref flashBitFlags, reader);\n            unkb = CaesarReader.ReadBitflagInt32(ref flashBitFlags, reader);\n            unkc = CaesarReader.ReadBitflagInt32(ref flashBitFlags, reader);\n        }\n\n        public void PrintDebug()\n        {\n            Console.WriteLine($\"{nameof(Qualifier)} : {Qualifier}\");\n            Console.WriteLine($\"{nameof(Description)} : {Description}\");\n            Console.WriteLine($\"{nameof(FlashAreaName)} : {FlashAreaName}\");\n            Console.WriteLine($\"{nameof(FlashTableStructureCount)} : {FlashTableStructureCount}\");\n\n            Console.WriteLine($\"{nameof(FlashTableStructureOffset)} : 0x{FlashTableStructureOffset:X}\");\n            Console.WriteLine($\"{nameof(NumberOfUploads)} : {NumberOfUploads}\");\n            Console.WriteLine($\"{nameof(UploadTableRefTable)} : {UploadTableRefTable}\");\n            Console.WriteLine($\"{nameof(NumberOfIdentServices)} : {NumberOfIdentServices}\");\n\n            Console.WriteLine($\"{nameof(IdentServicesOffset)} : {IdentServicesOffset}\");\n            Console.WriteLine($\"{nameof(UniqueObjectID)} : {UniqueObjectID}\");\n            Console.WriteLine($\"{nameof(unkb)} : {unkb}\");\n            Console.WriteLine($\"{nameof(unkc)} : {unkc}\");\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/Flash/FlashHeader.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Caesar\n{\n    public class FlashHeader\n    {\n        public int CffHeaderSize;\n        public long BaseAddress;\n\n        public string FlashName;\n        public string FlashGenerationParams;\n        public int Unk3;\n        public int Unk4;\n        public string FileAuthor;\n        public string FileCreationTime;\n        public string AuthoringToolVersion;\n        public string FTRAFOVersionString;\n        public int FTRAFOVersionNumber;\n        public string CFFVersionString;\n        public int NumberOfFlashAreas;\n        public int FlashDescriptionTable;\n        public int DataBlockTableCountProbably;\n        public int DataBlockRefTable;\n        public int CTFHeaderTable;\n        public int LanguageBlockLength;\n        public int NumberOfECURefs;\n        public int ECURefTable;\n        public int UnkTableCount;\n        public int UnkTableProbably;\n        public int Unk15;\n\n        public List<FlashDataBlock> DataBlocks = new List<FlashDataBlock>();\n        public List<FlashDescriptionHeader> DescriptionHeaders = new List<FlashDescriptionHeader>();\n        // DIIAddCBFFile\n        /*\n            21 bits active\n            f [6, 4,4,4,4, 4,4,4,4, 4,4,4,4, 4,4,4,4, 4,4,4,4, 1],\n         */\n        public FlashHeader(BinaryReader reader)\n        {\n            reader.BaseStream.Seek(StubHeader.StubHeaderSize, SeekOrigin.Begin);\n            CffHeaderSize = reader.ReadInt32();\n\n            BaseAddress = reader.BaseStream.Position;\n\n            ulong bitFlags = reader.ReadUInt32();\n\n            reader.ReadUInt16(); // unused\n\n            FlashName = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress);\n            FlashGenerationParams = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress);\n            Unk3 = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            Unk4 = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            FileAuthor = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress);\n            FileCreationTime = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress);\n            AuthoringToolVersion = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress);\n            FTRAFOVersionString = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress);\n            FTRAFOVersionNumber = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            CFFVersionString = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress);\n            NumberOfFlashAreas = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            FlashDescriptionTable = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            DataBlockTableCountProbably = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            DataBlockRefTable = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            CTFHeaderTable = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            LanguageBlockLength = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            NumberOfECURefs = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            ECURefTable = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            UnkTableCount = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            UnkTableProbably = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            Unk15 = CaesarReader.ReadBitflagUInt8(ref bitFlags, reader);\n\n            DescriptionHeaders = new List<FlashDescriptionHeader>();\n            for (int flashDescIndex = 0; flashDescIndex < NumberOfFlashAreas; flashDescIndex++)\n            {\n                long flashTableEntryAddress = FlashDescriptionTable + BaseAddress + (flashDescIndex * 4);\n                reader.BaseStream.Seek(flashTableEntryAddress, SeekOrigin.Begin);\n\n                long flashEntryBaseAddress = FlashDescriptionTable + BaseAddress + reader.ReadInt32();\n                FlashDescriptionHeader fdh = new FlashDescriptionHeader(reader, flashEntryBaseAddress);\n                DescriptionHeaders.Add(fdh);\n            }\n\n            DataBlocks = new List<FlashDataBlock>();\n            for (int dataBlockIndex = 0; dataBlockIndex < DataBlockTableCountProbably; dataBlockIndex++)\n            {\n                long datablockEntryAddress = DataBlockRefTable + BaseAddress + (dataBlockIndex * 4);\n                reader.BaseStream.Seek(datablockEntryAddress, SeekOrigin.Begin);\n\n                long datablockBaseAddress = DataBlockRefTable + BaseAddress + reader.ReadInt32();\n                FlashDataBlock fdb = new FlashDataBlock(reader, datablockBaseAddress);\n                DataBlocks.Add(fdb);\n            }\n        }\n\n        public void PrintDebug()\n        {\n\n            Console.WriteLine($\"{nameof(FlashName)} : {FlashName}\");\n            Console.WriteLine($\"{nameof(FlashGenerationParams)} : {FlashGenerationParams}\");\n            Console.WriteLine($\"{nameof(Unk3)} : {Unk3}\");\n            Console.WriteLine($\"{nameof(Unk4)} : {Unk4}\");\n\n            Console.WriteLine($\"{nameof(FileAuthor)} : {FileAuthor}\");\n            Console.WriteLine($\"{nameof(FileCreationTime)} : {FileCreationTime}\");\n            Console.WriteLine($\"{nameof(AuthoringToolVersion)} : {AuthoringToolVersion}\");\n            Console.WriteLine($\"{nameof(FTRAFOVersionString)} : {FTRAFOVersionString}\");\n\n            Console.WriteLine($\"{nameof(FTRAFOVersionNumber)} : {FTRAFOVersionNumber}\");\n            Console.WriteLine($\"{nameof(CFFVersionString)} : {CFFVersionString}\");\n            Console.WriteLine($\"{nameof(NumberOfFlashAreas)} : {NumberOfFlashAreas}\");\n            Console.WriteLine($\"{nameof(FlashDescriptionTable)} : 0x{FlashDescriptionTable:X}\");\n\n            Console.WriteLine($\"{nameof(DataBlockTableCountProbably)} : {DataBlockTableCountProbably}\");\n            Console.WriteLine($\"{nameof(DataBlockRefTable)} : {DataBlockRefTable}\");\n            Console.WriteLine($\"{nameof(CTFHeaderTable)} : {CTFHeaderTable}\");\n            Console.WriteLine($\"{nameof(LanguageBlockLength)} : {LanguageBlockLength}\");\n\n            Console.WriteLine($\"{nameof(NumberOfECURefs)} : {NumberOfECURefs}\");\n            Console.WriteLine($\"{nameof(ECURefTable)} : {ECURefTable}\");\n            Console.WriteLine($\"{nameof(UnkTableCount)} : {UnkTableCount}\");\n            Console.WriteLine($\"{nameof(UnkTableProbably)} : 0x{UnkTableProbably:X}\");\n\n\n            Console.WriteLine($\"{nameof(Unk15)} : {Unk15}\");\n\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/Flash/FlashSecurity.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Caesar\n{\n    public class FlashSecurity\n    {\n        public int MethodValueType;\n        public int MethodSize;\n        public byte[] MethodValue;\n\n        public int SignatureValueType;\n        public int SignatureSize;\n        public byte[] SignatureValue;\n\n        public int ChecksumValueType;\n        public int ChecksumSize;\n        public byte[] ChecksumValue;\n\n        public int EcuKeyValueType;\n        public int EcuKeySize;\n        public byte[] EcuKeyValue;\n\n        public long BaseAddress;\n\n        public FlashSecurity(BinaryReader reader, long baseAddress)\n        {\n            BaseAddress = baseAddress;\n            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);\n\n            ulong bitFlags = reader.ReadUInt16();\n\n            MethodValueType = CaesarReader.ReadBitflagInt16(ref bitFlags, reader);\n            MethodSize = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            MethodValue = CaesarReader.ReadBitflagDumpWithReader(ref bitFlags, reader, MethodSize, baseAddress);\n\n            SignatureValueType = CaesarReader.ReadBitflagInt16(ref bitFlags, reader);\n            SignatureSize = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            SignatureValue = CaesarReader.ReadBitflagDumpWithReader(ref bitFlags, reader, SignatureSize, baseAddress);\n\n            ChecksumValueType = CaesarReader.ReadBitflagInt16(ref bitFlags, reader);\n            ChecksumSize = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            ChecksumValue = CaesarReader.ReadBitflagDumpWithReader(ref bitFlags, reader, ChecksumSize, baseAddress);\n\n            EcuKeyValueType = CaesarReader.ReadBitflagInt16(ref bitFlags, reader);\n            EcuKeySize = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            EcuKeyValue = CaesarReader.ReadBitflagDumpWithReader(ref bitFlags, reader, EcuKeySize, baseAddress);\n        }\n\n        public void PrintDebug()\n        {\n            Console.WriteLine($\"{nameof(MethodValueType)} : 0x{MethodValueType:X}\");\n            Console.WriteLine($\"{nameof(MethodSize)} : 0x{MethodSize:X}\");\n            Console.WriteLine($\"{nameof(MethodValue)} : {BitUtility.BytesToHex(MethodValue)}\");\n\n            Console.WriteLine($\"{nameof(SignatureValueType)} : 0x{SignatureValueType:X}\");\n            Console.WriteLine($\"{nameof(SignatureSize)} : 0x{SignatureSize:X}\");\n            Console.WriteLine($\"{nameof(SignatureValue)} : {BitUtility.BytesToHex(SignatureValue)}\");\n\n            Console.WriteLine($\"{nameof(ChecksumValueType)} : 0x{ChecksumValueType:X}\");\n            Console.WriteLine($\"{nameof(ChecksumSize)} : 0x{ChecksumSize:X}\");\n            Console.WriteLine($\"{nameof(ChecksumValue)} : {BitUtility.BytesToHex(ChecksumValue)}\");\n\n            Console.WriteLine($\"{nameof(EcuKeyValueType)} : 0x{EcuKeyValueType:X}\");\n            Console.WriteLine($\"{nameof(EcuKeySize)} : 0x{EcuKeySize:X}\");\n            Console.WriteLine($\"{nameof(EcuKeyValue)} : {BitUtility.BytesToHex(EcuKeyValue)}\");\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/Flash/FlashSegment.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Caesar\n{\n    public class FlashSegment\n    {\n        public int FromAddress;\n        public int SegmentLength;\n        public int Unk3;\n        public string SegmentName;\n\n        public int Unk5;\n        public int Unk6;\n        public int Unk7;\n\n        /*\n            0x1b [2,  4,4,4,4,  4,4,4],\n         \n         */\n        public long BaseAddress;\n\n        public FlashSegment(BinaryReader reader, long baseAddress)\n        {\n            BaseAddress = baseAddress;\n            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);\n\n            ulong bitFlags = reader.ReadUInt16();\n\n            // start reading\n\n            FromAddress = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            SegmentLength = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            Unk3 = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            SegmentName = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress);\n\n            Unk5 = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            Unk6 = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n            Unk7 = CaesarReader.ReadBitflagInt32(ref bitFlags, reader);\n        }\n\n        public long GetMappedAddressFileOffset(BinaryReader reader)\n        {\n            reader.BaseStream.Seek(BaseAddress, SeekOrigin.Begin);\n\n            ulong bitFlags = reader.ReadUInt16();\n\n            if (CaesarReader.CheckAndAdvanceBitflag(ref bitFlags))\n            {\n                return reader.BaseStream.Position;\n            }\n            else\n            {\n                return -1;\n            }\n        }\n        public long GetSegmentLengthFileOffset(BinaryReader reader)\n        {\n            reader.BaseStream.Seek(BaseAddress, SeekOrigin.Begin);\n\n            ulong bitFlags = reader.ReadUInt16();\n\n            CaesarReader.ReadBitflagInt32(ref bitFlags, reader); // skip FromAddress\n            if (CaesarReader.CheckAndAdvanceBitflag(ref bitFlags))\n            {\n                return reader.BaseStream.Position;\n            }\n            else\n            {\n                return -1;\n            }\n        }\n\n        public void PrintDebug()\n        {\n            Console.WriteLine($\"{nameof(FromAddress)} : 0x{FromAddress:X}\");\n            Console.WriteLine($\"{nameof(SegmentLength)} : 0x{SegmentLength:X}\");\n            Console.WriteLine($\"{nameof(Unk3)} : {Unk3}\");\n            Console.WriteLine($\"{nameof(SegmentName)} : {SegmentName}\");\n\n\n            Console.WriteLine($\"{nameof(Unk5)} : {Unk5}\");\n            Console.WriteLine($\"{nameof(Unk6)} : {Unk6}\");\n            Console.WriteLine($\"{nameof(Unk7)} : {Unk7}\");\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/Program.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.IO;\n\n\nnamespace Caesar\n{\n    class Program\n    {\n        // During normal operation, this class is completely ignored\n        // The project can be temporarily switched from class library to console application to run as a standalone binary\n        static void Main(string[] args)\n        {\n            Console.WriteLine(\"Caesar (running as console application)\");\n            // RunLibraryTest();\n            Console.WriteLine(\"Done, press any key to exit\");\n            Console.ReadKey();\n        }\n\n        static void RunLibraryTest() \n        {\n            // debug: step through files to observe potential faults, missing bitflags etc.\n            List<string> paths = new List<string>();\n            string basePath = @\"\";\n            LoadFilePaths(basePath + @\"Data05.00.00\\\", paths);\n            LoadFilePaths(basePath + @\"CBF VAN\\\", paths);\n            foreach (string file in paths)\n            {\n                Console.WriteLine(file);\n                CaesarContainer container = new CaesarContainer(File.ReadAllBytes(file));\n                //Console.ReadKey();\n            }\n        }\n\n        static void LoadFilePaths(string path, List<string> result)\n        {\n            foreach (string file in Directory.GetFiles(path))\n            {\n                if (Path.GetExtension(file).ToLower() == \".cbf\")\n                {\n                    result.Add(file);\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following\n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"Caesar\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"Caesar\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2020\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible\n// to COM components.  If you need to access a type in this assembly from\n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"71c43c61-7dc7-4d47-9947-1dd73e559911\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version\n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers\n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.5.2.0\")]\n[assembly: AssemblyFileVersion(\"1.5.2.0\")]\n"
  },
  {
    "path": "Caesar/Caesar/Scale.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.IO;\n\nnamespace Caesar\n{\n    public class Scale\n    {\n        public long BaseAddress;\n\n        // 0x0b [2,   4,4,4,4,    4,4,4,4,   4,4,4],\n\n        public int EnumLowBound;\n        public int EnumUpBound;\n        public int PrepLowBound;\n        public int PrepUpBound;\n\n        public float MultiplyFactor;\n        public float AddConstOffset;\n\n        public int SICount;\n        public int OffsetSI;\n\n        public int USCount;\n        public int OffsetUS;\n\n        public int EnumDescription;\n        public int UnkC;\n\n        [Newtonsoft.Json.JsonIgnore]\n        private CTFLanguage Language;\n\n        public void Restore(CTFLanguage language) \n        {\n            Language = language;\n        }\n\n        public Scale() { }\n\n        public Scale(BinaryReader reader, long baseAddress, CTFLanguage language) \n        {\n            BaseAddress = baseAddress;\n            Language = language;\n            \n            reader.BaseStream.Seek(BaseAddress, SeekOrigin.Begin);\n\n            ulong bitflags = reader.ReadUInt16();\n\n            EnumLowBound = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            EnumUpBound = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            PrepLowBound = CaesarReader.ReadBitflagInt32(ref bitflags, reader); // could be float\n            PrepUpBound = CaesarReader.ReadBitflagInt32(ref bitflags, reader); // could be float\n\n            MultiplyFactor = CaesarReader.ReadBitflagFloat(ref bitflags, reader);\n            AddConstOffset = CaesarReader.ReadBitflagFloat(ref bitflags, reader);\n\n            SICount = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            OffsetSI = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            USCount = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            OffsetUS = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n            EnumDescription = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);\n            UnkC = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n\n        }\n\n        public void PrintDebug()\n        {\n            Console.WriteLine($\"{nameof(EnumLowBound)} : {EnumLowBound}\");\n            Console.WriteLine($\"{nameof(EnumUpBound)} : {EnumUpBound}\");\n            Console.WriteLine($\"{nameof(PrepLowBound)} : {PrepLowBound}\");\n            Console.WriteLine($\"{nameof(PrepUpBound)} : {PrepUpBound}\");\n\n            Console.WriteLine($\"{nameof(MultiplyFactor)} : {MultiplyFactor}\");\n            Console.WriteLine($\"{nameof(AddConstOffset)} : {AddConstOffset}\");\n            Console.WriteLine($\"{nameof(SICount)} : {SICount}\");\n            Console.WriteLine($\"{nameof(OffsetSI)} : {OffsetSI}\");\n\n            Console.WriteLine($\"{nameof(USCount)} : {USCount}\");\n            Console.WriteLine($\"{nameof(OffsetUS)} : {OffsetUS}\");\n            Console.WriteLine($\"{nameof(EnumDescription)} : {EnumDescription}\");\n            Console.WriteLine($\"{nameof(UnkC)} : {UnkC}\");\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/StubHeader.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Caesar\n{\n    class StubHeader\n    {\n        public const int StubHeaderSize = 0x410;\n        private static readonly byte[] FileHeader = Encoding.ASCII.GetBytes(\"CBF-TRANSLATOR-VERSION:04.00\");\n\n        public static void ReadHeader(byte[] header)\n        {\n            // file checksum first, but we are skipping that\n            // last 4 bytes of cbf is for checksum\n\n            if (!header.Take(FileHeader.Length).SequenceEqual(FileHeader))\n            {\n                Console.WriteLine(\"Unknown CBF version\");\n            }\n            int cbfHeaderIdentifier = header[0x401];\n            if (cbfHeaderIdentifier != 3)\n            {\n                Console.WriteLine($\"Unrecognized magic 2 : {cbfHeaderIdentifier}\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/VCDomain.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.IO;\n\nnamespace Caesar\n{\n    public class VCDomain\n    {\n\n        public string Qualifier;\n        public int Name_CTF;\n        public int Description_CTF;\n        public string ReadServiceName;\n        public string WriteServiceName;\n        private int FragmentCount;\n        private int FragmentTableOffset;\n        public int DumpSize;\n        private int DefaultStringCount; // exposed as DefaultData.Count\n        private int StringTableOffset; // exposed as DefaultData\n        public int Unk1;\n\n        public List<VCFragment> VCFragments = new List<VCFragment>();\n        [Newtonsoft.Json.JsonIgnore]\n        public ECU ParentECU;\n\n        public List<Tuple<string, byte[]>> DefaultData = new List<Tuple<string, byte[]>>();\n\n        public long BaseAddress;\n        public int Index;\n\n        public void Restore(CTFLanguage language, ECU parentEcu) \n        {\n            ParentECU = parentEcu;\n            foreach (VCFragment fragment in VCFragments) \n            {\n                fragment.Restore(parentEcu, this, language);\n            }\n        }\n\n        public VCDomain() { }\n\n        // VCDomain(reader, language, vcdBlockAddress, vcdIndex, this);\n        public VCDomain(BinaryReader reader, CTFLanguage language, long baseAddress, int variantCodingDomainEntry, ECU parentEcu) \n        {\n            ParentECU = parentEcu;\n            BaseAddress = baseAddress;\n            Index = variantCodingDomainEntry;\n\n            /*\n            byte[] variantCodingPool = parentEcu.ReadVarcodingPool(reader);\n            using (BinaryReader poolReader = new BinaryReader(new MemoryStream(variantCodingPool)))\n            {\n                poolReader.BaseStream.Seek(variantCodingDomainEntry * parentEcu.VcDomain_EntrySize, SeekOrigin.Begin);\n                int entryOffset = poolReader.ReadInt32();\n                int entrySize = poolReader.ReadInt32();\n                uint entryCrc = poolReader.ReadUInt32();\n                long vcdBlockAddress = entryOffset + parentEcu.VcDomain_BlockOffset;\n            }\n            // Console.WriteLine($\"VCD Entry @ 0x{entryOffset:X} with size 0x{entrySize:X} and CRC {entryCrc:X8}, abs addr {vcdBlockAddress:X8}\");\n\n            long baseAddress = vcdBlockAddress;\n            */\n            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);\n            ulong bitflags = reader.ReadUInt16();\n\n            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);\n            Name_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);\n            Description_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);\n            ReadServiceName = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);\n            WriteServiceName = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);\n            FragmentCount = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            FragmentTableOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader) + (int)baseAddress; // demoting long (warning)\n            DumpSize = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            DefaultStringCount = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            StringTableOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);\n            Unk1 = CaesarReader.ReadBitflagInt16(ref bitflags, reader);\n\n            // PrintDebug();\n\n            VCFragments = new List<VCFragment>();\n            for (int fragmentIndex = 0; fragmentIndex < FragmentCount; fragmentIndex++)\n            {\n                VCFragment fragment = new VCFragment(reader, this, FragmentTableOffset, fragmentIndex, language, parentEcu);\n                VCFragments.Add(fragment);\n            }\n            // ValidateFragmentCoverage();\n\n            if (DefaultStringCount > 0) \n            {\n                DefaultData = new List<Tuple<string, byte[]>>();\n                long stringTableBaseAddress = StringTableOffset + baseAddress;\n                // this could almost be a class of its own but there isn't a distinct name to it\n                for (int stringTableIndex = 0; stringTableIndex < DefaultStringCount; stringTableIndex++) \n                {\n                    reader.BaseStream.Seek(stringTableBaseAddress + (4 * stringTableIndex), SeekOrigin.Begin);\n                    int offset = reader.ReadInt32();\n                    long stringBaseAddress = stringTableBaseAddress + offset;\n                    reader.BaseStream.Seek(stringBaseAddress, SeekOrigin.Begin);\n                    ulong strBitflags = reader.ReadUInt16();\n                    int nameUsuallyAbsent_T = CaesarReader.ReadBitflagInt32(ref strBitflags, reader, -1);\n                    int offsetToBlob = CaesarReader.ReadBitflagInt32(ref strBitflags, reader);\n                    int blobSize = CaesarReader.ReadBitflagInt32(ref strBitflags, reader);\n                    int valueType_T = CaesarReader.ReadBitflagInt32(ref strBitflags, reader, -1);\n                    string noIdeaStr1 = CaesarReader.ReadBitflagStringWithReader(ref strBitflags, reader, stringBaseAddress);\n                    int noIdea2_T = CaesarReader.ReadBitflagInt32(ref strBitflags, reader, -1);\n                    int noIdea3 = CaesarReader.ReadBitflagInt16(ref strBitflags, reader);\n                    string noIdeaStr2 = CaesarReader.ReadBitflagStringWithReader(ref strBitflags, reader, stringBaseAddress);\n                    byte[] blob = new byte[] { };\n                    if (blobSize > 0)\n                    {\n                        long blobFileAddress = stringBaseAddress + offsetToBlob;\n                        reader.BaseStream.Seek(blobFileAddress, SeekOrigin.Begin);\n                        blob = reader.ReadBytes(blobSize);\n                        // memcpy\n                    }\n\n                    string valueType = language.GetString(valueType_T); // this value is almost always \"default\"; can probably let the hardcoded string pass\n                    DefaultData.Add(new Tuple<string, byte[]>(valueType, blob));\n                    //Console.WriteLine($\"Blob: {BitUtility.BytesToHex(blob)} @ {valueType}\");\n                    //Console.WriteLine($\"String base address: 0x{stringBaseAddress:X}\");\n                }\n            }\n            \n        }\n\n        private void ValidateFragmentCoverage() \n        {\n            // apparently gaps are okay, there isn't a 100% way to find out if parsing errors have snuck through\n            int bitCursor = 0;\n            int expectedLengthInBits = DumpSize * 8;\n            List<VCFragment> fragments = new List<VCFragment>(VCFragments);\n            List<int> bitGapPositions = new List<int>();\n\n            while (fragments.Count > 0)\n            {\n                VCFragment result = fragments.Find(x => x.ByteBitPos == bitCursor);\n                if (result is null)\n                {\n                    bitGapPositions.Add(bitCursor);\n                    bitCursor++;\n                    if (bitCursor > expectedLengthInBits) \n                    {\n                        throw new Exception(\"wtf\");\n                    }\n                }\n                else \n                {\n                    bitCursor += result.BitLength;\n                    fragments.Remove(result);\n                }\n            }\n        }\n\n        public void PrintDebug() \n        {\n\n            Console.WriteLine($\"VCD Name: {Qualifier}\");\n            Console.WriteLine($\"{nameof(Name_CTF)} : {Name_CTF}\");\n            Console.WriteLine($\"{nameof(Description_CTF)} : {Description_CTF}\");\n            Console.WriteLine($\"{nameof(ReadServiceName)} : {ReadServiceName}\");\n            Console.WriteLine($\"{nameof(WriteServiceName)} : {WriteServiceName}\");\n\n            Console.WriteLine($\"{nameof(FragmentCount)} : {FragmentCount}\");\n            Console.WriteLine($\"{nameof(FragmentTableOffset)} : 0x{FragmentTableOffset:X}\");\n            Console.WriteLine($\"{nameof(DumpSize)} : {DumpSize}\");\n            Console.WriteLine($\"{nameof(DefaultStringCount)} : {DefaultStringCount}\");\n            Console.WriteLine($\"{nameof(StringTableOffset)} : {StringTableOffset}\");\n            Console.WriteLine($\"{nameof(Unk1)} : {Unk1}\");\n\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/VCFragment.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.IO;\n\nnamespace Caesar\n{\n    public class VCFragment\n    {\n        public int ByteBitPos;\n        public ushort ImplementationType;\n\n        public int Name_CTF;\n        public int Description_CTF;\n        public int ReadAccessLevel;\n        public int WriteAccessLevel;\n        public int ByteOrder;\n        public int RawBitLength;\n        public int IttOffset;\n        public int InfoPoolIndex;\n        public int MeaningB;\n        public int MeaningC;\n        public int CCFHandle;\n        public int VarcodeDumpSize;\n        public byte[] VarcodeDump;\n        private int SubfragmentCount; // exposed as Subfragments.Count\n        private long SubfragmentFileOffset; // exposed as Subfragments\n        public string Qualifier;\n\n        public int ImplementationUpper;\n        public int ImplementationLower;\n\n        public int BitLength;\n\n        public List<VCSubfragment> Subfragments = new List<VCSubfragment>();\n\n        [Newtonsoft.Json.JsonIgnore]\n        private static readonly byte[] FragmentLengthTable = new byte[] { 0, 1, 4, 8, 0x10, 0x20, 0x40 };\n        [Newtonsoft.Json.JsonIgnore]\n        public VCDomain ParentDomain;\n        [Newtonsoft.Json.JsonIgnore]\n        public ECU ParentECU;\n\n        public void Restore(ECU parentEcu, VCDomain parentDomain, CTFLanguage language) \n        {\n            ParentECU = parentEcu;\n            ParentDomain = parentDomain;\n            foreach (VCSubfragment subfragment in Subfragments) \n            {\n                subfragment.Restore(language);\n            }\n        }\n\n        public VCFragment() { }\n\n        public VCFragment(BinaryReader reader, VCDomain parentDomain, long fragmentTable, int fragmentIndex, CTFLanguage language, ECU parentEcu) \n        {\n            // see DIOpenVarCodeFrag\n            ParentDomain = parentDomain;\n            ParentECU = parentEcu;\n\n            long fragmentTableEntry = fragmentTable + (10 * fragmentIndex);\n            reader.BaseStream.Seek(fragmentTableEntry, SeekOrigin.Begin);\n            // no bitflag required for 10-byte table entry since it is mandatory\n            int fragmentNewBaseOffset = reader.ReadInt32();\n\n            ByteBitPos = reader.ReadInt32();\n            ImplementationType = reader.ReadUInt16();\n\n            // Console.WriteLine($\"Fragment new base @ 0x{fragmentNewBaseOffset:X}, byteBitPos 0x{fragmentByteBitPos:X}, implementationType: 0x{implementationType:X}\");\n            long fragmentBaseAddress = fragmentTable + fragmentNewBaseOffset;\n            reader.BaseStream.Seek(fragmentBaseAddress, SeekOrigin.Begin);\n            ulong fragmentBitflags = reader.ReadUInt32();\n            // Console.WriteLine($\"Fragment new bitflag @ 0x{fragmentBitflags:X}\");\n\n            Name_CTF = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader, -1);\n            Description_CTF = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader, -1);\n            ReadAccessLevel = CaesarReader.ReadBitflagUInt8(ref fragmentBitflags, reader);\n            WriteAccessLevel = CaesarReader.ReadBitflagUInt8(ref fragmentBitflags, reader);\n            ByteOrder = CaesarReader.ReadBitflagUInt16(ref fragmentBitflags, reader);\n            RawBitLength = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader);\n            IttOffset = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader);\n            InfoPoolIndex = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader, -1);\n            MeaningB = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader, -1);\n            MeaningC = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader, -1);\n            CCFHandle = CaesarReader.ReadBitflagInt16(ref fragmentBitflags, reader, -1);\n            VarcodeDumpSize = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader);\n            VarcodeDump = CaesarReader.ReadBitflagDumpWithReader(ref fragmentBitflags, reader, VarcodeDumpSize, fragmentBaseAddress);\n            SubfragmentCount = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader);\n            SubfragmentFileOffset = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader);\n            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref fragmentBitflags, reader, fragmentBaseAddress);\n\n            // Console.WriteLine($\"{nameof(fragmentName)} : {fragmentName}, child {fragmentNoOfSubFragments} @ 0x{fragmentSubfragmentFileOffset:X} base {fragmentBaseAddress:X}\");\n\n            \n            if ((ByteOrder != 0) && (BitLength > 0)) \n            {\n                //throw new Exception(\"Currently assumes everything is little-endian\");\n                Console.WriteLine($\"WARNING: {Qualifier} (Size: {BitLength}) has an unsupported byte order. Please proceed with caution\");\n                //PrintDebug(true);\n            }\n            \n\n            long subfragmentTableAddress = SubfragmentFileOffset + fragmentBaseAddress;\n            Subfragments.Clear();\n            for (int subfragmentIndex = 0; subfragmentIndex < SubfragmentCount; subfragmentIndex++)\n            {\n                reader.BaseStream.Seek(subfragmentTableAddress + (subfragmentIndex * 4), SeekOrigin.Begin);\n                long subfragmentAddress = reader.ReadInt32() + subfragmentTableAddress;\n                VCSubfragment subfragment = new VCSubfragment(reader, this, language, subfragmentAddress);\n                Subfragments.Add(subfragment);\n            }\n            // PrintDebug();\n            // Console.WriteLine($\"implementation-default : {implementationType:X4} upper: {(implementationType & 0xFF0):X4} lower: {(implementationType & 0xF):X4}\");\n            FindFragmentSize(reader);\n        }\n\n        public VCSubfragment GetSubfragmentConfiguration(byte[] variantCodingValue)\n        {\n            byte[] variantBits = BitUtility.ByteArrayToBitArray(variantCodingValue);\n            byte[] affectedBits = variantBits.Skip(ByteBitPos).Take(BitLength).ToArray();\n\n            foreach (VCSubfragment subfragment in Subfragments)\n            {\n                byte[] sfToCompare = BitUtility.ByteArrayToBitArray(subfragment.Dump).Take(BitLength).ToArray();\n                if (sfToCompare.SequenceEqual(affectedBits))\n                {\n                    return subfragment;\n                }\n            }\n            return null;\n        }\n        public byte[] SetSubfragmentConfiguration(byte[] variantCodingValue, string subfragmentName)\n        {\n            foreach (VCSubfragment subfragment in Subfragments)\n            {\n                if (subfragment.NameResolved == subfragmentName)\n                {\n                    return SetSubfragmentConfiguration(variantCodingValue, subfragment);\n                }\n            }\n            throw new FormatException($\"Requested subfragment {subfragmentName} could not be found in {Qualifier}\");\n        }\n\n        public byte[] SetSubfragmentConfiguration(byte[] variantCodingValue, VCSubfragment subfragment)\n        {\n            byte[] variantBits = BitUtility.ByteArrayToBitArray(variantCodingValue);\n            List<byte> result = new List<byte>(variantBits.Take(ByteBitPos));\n            variantBits = variantBits.Skip(BitLength + ByteBitPos).ToArray();\n            byte[] sfToSet = BitUtility.ByteArrayToBitArray(subfragment.Dump).Take(BitLength).ToArray();\n            result.AddRange(sfToSet);\n            result.AddRange(variantBits);\n            return BitUtility.BitArrayToByteArray(result.ToArray());\n        }\n\n        private void FindFragmentSize(BinaryReader reader) \n        {\n            ImplementationUpper = ImplementationType & 0xFF0;\n            ImplementationLower = ImplementationType & 0xF;\n            BitLength = 0;\n\n            // fixup the bit length\n            if (ImplementationLower > 6)\n            {\n                throw new NotImplementedException(\"The disassembly throws an exception when fragmentImplementationLower > 6, copying verbatim\");\n            }\n\n            if (ImplementationUpper > 0x420)\n            {\n                // Console.WriteLine($\"fragment value upper: {fragmentImplementationUpper:X}\");\n                ECU ecu = ParentDomain.ParentECU;\n                byte[] infoPool = ecu.ReadECUInfoPool(reader);\n                // int infoEntryWidth = ecu.ecuInfoPool_tableEntrySize;\n                // Console.WriteLine($\"Info entry width: {infoEntryWidth}\"); // 8\n\n                using (BinaryReader poolReader = new BinaryReader(new MemoryStream(infoPool))) \n                {\n                    DiagPresentation pres = ParentECU.GlobalInternalPresentations[InfoPoolIndex];\n                    /*\n                    // depreciate use of ReadCBFWithOffset\n                    poolReader.BaseStream.Seek(ecu.Info_EntrySize * InfoPoolIndex, SeekOrigin.Begin);\n                    int presentationStructOffset = poolReader.ReadInt32();\n                    int presentationStructSize = poolReader.ReadInt32();\n\n                    //Console.WriteLine($\"struct offset: 0x{presentationStructOffset:X} , size: {presentationStructSize} , meaningA 0x{fragmentMeaningA_Presentation:X} infoBase 0x{ecu.ecuInfoPool_fileoffset_7:X}\\n\");\n\n                    reader.BaseStream.Seek(presentationStructOffset + ecu.Info_BlockOffset, SeekOrigin.Begin);\n                    byte[] presentationStruct = reader.ReadBytes(presentationStructSize);\n\n                    int presentationMode = CaesarStructure.ReadCBFWithOffset(0x1C, CaesarStructure.StructureName.PRESENTATION_STRUCTURE, presentationStruct); // PRESS_Type\n                    int presentationLength = CaesarStructure.ReadCBFWithOffset(0x1A, CaesarStructure.StructureName.PRESENTATION_STRUCTURE, presentationStruct); // PRESS_TypeLength\n                    if (presentationLength > 0)\n                    {\n                        BitLength = presentationLength;\n                    }\n                    else \n                    {\n                        BitLength = CaesarStructure.ReadCBFWithOffset(0x21, CaesarStructure.StructureName.PRESENTATION_STRUCTURE, presentationStruct); // ???\n                    }\n                    */\n                    BitLength = pres.TypeLength_1A > 0 ? pres.TypeLength_1A : pres.TypeLengthBytesMaybe_21;\n                    // if value was specified in bytes, convert to bits\n                    if (pres.Type_1C == 0)\n                    {\n                        BitLength *= 8;\n                    }\n                }\n            }\n            else\n            {\n                if (ImplementationUpper == 0x420)\n                {\n                    BitLength = FragmentLengthTable[ImplementationLower];\n                }\n                else if (ImplementationUpper == 0x320)\n                {\n                    BitLength = FragmentLengthTable[ImplementationLower];\n                }\n                else if (ImplementationUpper == 0x330)\n                {\n                    BitLength = RawBitLength;\n                }\n                else if (ImplementationUpper == 0x340)\n                {\n                    //throw new NotImplementedException(\"Requires implementation of ITT handle\");\n                    Console.WriteLine($\"[!] Warning: Please avoid {ParentDomain.Qualifier} -> {Qualifier} as it could not be parsed (requires ITT).\");\n                }\n                else\n                {\n                    throw new NotImplementedException($\"No known fragment length format. Fragment upper: 0x{ImplementationUpper:X}\");\n                }\n            }\n\n            if (BitLength == 0)\n            {\n                // not sure if there are dummy entries that might trip below exception\n                // throw new NotImplementedException(\"Fragment length cannot be zero\");\n            }\n        }\n\n        public void PrintDebug(bool verbose=false)\n        {\n            if (verbose)\n            {\n\n                Console.WriteLine($\"{nameof(ByteBitPos)} : {ByteBitPos}\");\n                Console.WriteLine($\"{nameof(BitLength)} : {BitLength}\");\n                Console.WriteLine($\"{nameof(ImplementationType)} : {ImplementationType}\");\n                Console.WriteLine($\"{nameof(ImplementationUpper)} : 0x{ImplementationUpper:X}\");\n\n                Console.WriteLine($\"{nameof(Name_CTF)} : {Name_CTF}\");\n                Console.WriteLine($\"{nameof(Description_CTF)} : {Description_CTF}\");\n                Console.WriteLine($\"{nameof(ReadAccessLevel)} : {ReadAccessLevel}\");\n                Console.WriteLine($\"{nameof(WriteAccessLevel)} : {WriteAccessLevel}\");\n                Console.WriteLine($\"{nameof(ByteOrder)} : {ByteOrder}\");\n                Console.WriteLine($\"{nameof(RawBitLength)} : {RawBitLength}\");\n                Console.WriteLine($\"{nameof(IttOffset)} : {IttOffset}\");\n                Console.WriteLine($\"{nameof(InfoPoolIndex)} : {InfoPoolIndex}\");\n                Console.WriteLine($\"{nameof(MeaningB)} : {MeaningB}\");\n                Console.WriteLine($\"{nameof(MeaningC)} : {MeaningC}\");\n                Console.WriteLine($\"{nameof(CCFHandle)} : {CCFHandle}\");\n                Console.WriteLine($\"{nameof(VarcodeDumpSize)} : {VarcodeDumpSize}\");\n                Console.WriteLine($\"{nameof(VarcodeDump)} : {BitUtility.BytesToHex(VarcodeDump)}\");\n                Console.WriteLine($\"{nameof(SubfragmentCount)} : {SubfragmentCount}\");\n                Console.WriteLine($\"{nameof(SubfragmentFileOffset)} : 0x{SubfragmentFileOffset:X}\");\n                Console.WriteLine($\"{nameof(Qualifier)} : {Qualifier}\");\n            }\n            else \n            {\n                Console.WriteLine($\"{Qualifier}%{ByteBitPos}%{BitLength}%[{ImplementationUpper:X}/{ImplementationLower:X}]\");\n            }\n\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/VCSubfragment.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.IO;\n\nnamespace Caesar\n{\n    public class VCSubfragment\n    {\n        public int Name_CTF;\n        public byte[] Dump;\n        public int Description_CTF;\n        public string QualifierUsuallyDisabled;\n        public int Unk3;\n        public int Unk4;\n        public string SupplementKey;\n\n\n        [Newtonsoft.Json.JsonIgnore]\n        public string NameResolved { get { return Language.GetString(Description_CTF); } }\n\n        [Newtonsoft.Json.JsonIgnore]\n        CTFLanguage Language;\n\n        public void Restore(CTFLanguage language) \n        {\n            Language = language;\n        }\n\n        public VCSubfragment() { }\n\n        public VCSubfragment(BinaryReader reader, VCFragment parentFragment, CTFLanguage language, long baseAddress)\n        {\n            // see DIOpenCBF_FragValHandle\n            Language = language;\n            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);\n            ulong bitflags = reader.ReadUInt16();\n\n            Name_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);\n            if (parentFragment.CCFHandle == 5) \n            {\n                // fragment should be parsed as PBSGetDumpAsStringFn, though internally we perceive this as the same\n            }\n            Dump = CaesarReader.ReadBitflagDumpWithReader(ref bitflags, reader, parentFragment.VarcodeDumpSize, baseAddress);\n            Description_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);\n            QualifierUsuallyDisabled = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);\n            Unk3 = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);\n            Unk4 = CaesarReader.ReadBitflagInt16(ref bitflags, reader, -1);\n            SupplementKey = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);\n\n            //int subfragmentIdk2 = reader.ReadInt32();\n            //int subfragmentName = reader.ReadInt32();\n            //int subfragmentIdkIncremented = reader.ReadInt32();\n            //Console.WriteLine($\"Subfragment: {subfragmentIdk1:X} {subfragmentIdk2:X} {language.GetString(subfragmentName)} {subfragmentIdkIncremented:X}\");\n            //PrintDebug();\n        }\n\n        private void PrintDebug(bool verbose = false) \n        {\n            if (verbose)\n            {\n                Console.WriteLine(\"------------- subfragment ------------- \");\n                Console.WriteLine($\"{nameof(Name_CTF)}, {Name_CTF}\");\n                Console.WriteLine($\"{nameof(Dump)}, {BitUtility.BytesToHex(Dump)}\");\n                Console.WriteLine($\"{nameof(Description_CTF)}, {Description_CTF}\");\n                Console.WriteLine($\"{nameof(NameResolved)}, {NameResolved}\");\n                Console.WriteLine($\"{nameof(QualifierUsuallyDisabled)}, {QualifierUsuallyDisabled}\");\n                Console.WriteLine($\"{nameof(Unk3)}, {Unk3}\");\n                Console.WriteLine($\"{nameof(Unk4)}, {Unk4}\");\n                Console.WriteLine($\"{nameof(SupplementKey)}, {SupplementKey}\");\n            }\n            else\n            {\n                Console.WriteLine($\">> {BitUtility.BytesToHex(Dump)} : {NameResolved}\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Caesar/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Newtonsoft.Json\" version=\"12.0.3\" targetFramework=\"net46\" />\n</packages>"
  },
  {
    "path": "Caesar/Caesar.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 16\nVisualStudioVersion = 16.0.30309.148\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Caesar\", \"Caesar\\Caesar.csproj\", \"{71C43C61-7DC7-4D47-9947-1DD73E559911}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Trafo\", \"Trafo\\Trafo.csproj\", \"{42A6F1FD-82CC-4721-BF0C-1658AE902875}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Diogenes\", \"Diogenes\\Diogenes.csproj\", \"{2216DB99-EAAC-46A8-B99A-28D659907DE7}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{71C43C61-7DC7-4D47-9947-1DD73E559911}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{71C43C61-7DC7-4D47-9947-1DD73E559911}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{71C43C61-7DC7-4D47-9947-1DD73E559911}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{71C43C61-7DC7-4D47-9947-1DD73E559911}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{42A6F1FD-82CC-4721-BF0C-1658AE902875}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{42A6F1FD-82CC-4721-BF0C-1658AE902875}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{42A6F1FD-82CC-4721-BF0C-1658AE902875}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{42A6F1FD-82CC-4721-BF0C-1658AE902875}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{2216DB99-EAAC-46A8-B99A-28D659907DE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{2216DB99-EAAC-46A8-B99A-28D659907DE7}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{2216DB99-EAAC-46A8-B99A-28D659907DE7}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{2216DB99-EAAC-46A8-B99A-28D659907DE7}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {5BE4FB05-511E-4470-8F3E-9BEC3256EB69}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "Caesar/Diogenes/App.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<configuration>\n    <startup> \n        <supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.6\" />\n    </startup>\n</configuration>"
  },
  {
    "path": "Caesar/Diogenes/DiagnosticProtocol/BaseProtocol.cs",
    "content": "﻿using Caesar;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Diogenes.DiagnosticProtocol\n{\n    public class BaseProtocol\n    {\n        public virtual void ConnectionEstablishedHandler(ECUConnection connection)\n        {\n\n        }\n        public virtual void ConnectionClosingHandler(ECUConnection connection)\n        {\n\n        }\n\n        public virtual void SendTesterPresent(ECUConnection connection) \n        {\n        \n        }\n\n        public virtual bool IsResponseToTesterPresent(byte[] inBuffer) \n        {\n            return false;\n        }\n\n        public virtual string GetProtocolName() \n        {\n            return \"UninitializedProtocol\";\n        }\n        public virtual bool SupportsUnlocking()\n        {\n            return false;\n        }\n\n        public virtual ECUMetadata QueryECUMetadata(ECUConnection connection) \n        {\n            return new ECUMetadata() { };\n        }\n\n        public virtual List<DTCContext> ReportDtcsByStatusMask(ECUConnection connection, ECUVariant variant, byte inMask = 0)\n        {\n            return new List<DTCContext>();\n        }\n\n        public virtual bool GetDtcSnapshot(DTC dtc, ECUConnection connection, out byte[] snapshotBytes) \n        {\n            snapshotBytes = new byte[] { };\n            return false;\n        }\n\n        public static BaseProtocol GetProtocol(string profileName)\n        {\n            // fixme: this depends on the cbf author's consistency and so far it's been reliable BUT there should be a better way of specifying the protocol?\n            if (profileName.Contains(\"_UDS_\"))\n            {\n                return new UDS();\n            }\n            else if (profileName.Contains(\"_KW2C3PE_\"))\n            {\n                return new KW2C3PE();\n            }\n            return new UnsupportedProtocol();\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/DiagnosticProtocol/KW2C3PE.cs",
    "content": "﻿using Caesar;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Diogenes.DiagnosticProtocol\n{\n    public class KW2C3PE : BaseProtocol\n    {\n        private static bool EnterDiagnosticSession(ECUConnection connection)\n        {\n            Console.WriteLine(\"KW2C3PE: Switching session states\");\n            byte[] sessionSwitchResponse = connection.SendMessage(new byte[] { 0x10, 0x92 });\n            byte[] sessionExpectedResponse = new byte[] { 0x50, 0x92 };\n            if (!sessionSwitchResponse.Take(2).SequenceEqual(sessionExpectedResponse))\n            {\n                Console.WriteLine($\"Failed to switch session : target responded with [{BitUtility.BytesToHex(sessionSwitchResponse, true)}]\");\n                return false;\n            }\n            return true;\n        }\n        \n        private static bool ExitDiagnosticSession(ECUConnection connection)\n        {\n            Console.WriteLine(\"KW2C3PE: Switching session states\");\n            byte[] sessionSwitchResponse = connection.SendMessage(new byte[] { 0x10, 0x81 });\n            byte[] sessionExpectedResponse = new byte[] { 0x50, 0x81 };\n            if (!sessionSwitchResponse.Take(2).SequenceEqual(sessionExpectedResponse))\n            {\n                Console.WriteLine($\"Failed to switch session : target responded with [{BitUtility.BytesToHex(sessionSwitchResponse, true)}]\");\n                return false;\n            }\n            return true;\n        }\n\n        private static bool GetVariantID_1A86(ECUConnection connection, out int variantId)\n        {\n            byte[] variantQueryResponse = connection.SendMessage(new byte[] { 0x1A, 0x86 });\n            byte[] variantExpectedResponse = new byte[] { 0x5A, 0x86 };\n\n            if (!variantQueryResponse.Take(2).SequenceEqual(variantExpectedResponse))\n            {\n                variantId = 0;\n                return false;\n            }\n            else\n            {\n                variantId = (variantQueryResponse[12] << 8) | variantQueryResponse[13];\n                return true;\n            }\n        }\n        private static bool GetVariantID_1A87(ECUConnection connection, out int variantId)\n        {\n            byte[] variantQueryResponse = connection.SendMessage(new byte[] { 0x1A, 0x87 });\n            byte[] variantExpectedResponse = new byte[] { 0x5A, 0x87 };\n\n            if (!variantQueryResponse.Take(2).SequenceEqual(variantExpectedResponse))\n            {\n                variantId = 0;\n                return false;\n            }\n            else\n            {\n                variantId = (variantQueryResponse[4] << 8) | variantQueryResponse[5];\n                return true;\n            }\n        }\n\n        private static bool GetVariantID(ECUConnection connection, out int variantId)\n        {\n            if (GetVariantID_1A86(connection, out int idFor1A86))\n            {\n                variantId = idFor1A86;\n                return true;\n            }\n            if (GetVariantID_1A87(connection, out int idFor1A87))\n            {\n                variantId = idFor1A87;\n                return true;\n            }\n            variantId = 0;\n            return false;\n        }\n\n        public override List<DTCContext> ReportDtcsByStatusMask(ECUConnection connection, ECUVariant variant, byte inMask = 0)\n        {\n            // FIXME : KW2C3PE probably uses a different set of commands at 0x18\n            return base.ReportDtcsByStatusMask(connection, variant, inMask);\n        }\n\n        public override bool GetDtcSnapshot(DTC dtc, ECUConnection connection, out byte[] snapshotBytes)\n        {\n            // FIXME\n            return base.GetDtcSnapshot(dtc, connection, out snapshotBytes);\n        }\n\n        public override void ConnectionEstablishedHandler(ECUConnection connection)\n        {\n            if (!EnterDiagnosticSession(connection))\n            {\n                return;\n            }\n            if (GetVariantID(connection, out int variantId))\n            {\n                connection.VariantIsAvailable = true;\n                connection.ECUVariantID = variantId;\n                Console.WriteLine($\"Variant has been successfully configured as {(variantId & 0xFFFF):X4}\");\n            }\n            else\n            {\n                Console.WriteLine(\"KW2C3PE: Could not identify variant (1A86, 1A87)\");\n                return;\n            }\n        }\n\n        public override void SendTesterPresent(ECUConnection connection)\n        {\n            // looks like 3E 01 for KW2C3PE \n            connection.SendMessage(new byte[] { 0x3E, 0x01 }, true);\n        }\n\n        public override bool IsResponseToTesterPresent(byte[] inBuffer)\n        {\n            return inBuffer.SequenceEqual(new byte[] { 0x7E, 0x01 });\n        }\n\n        public override void ConnectionClosingHandler(ECUConnection connection)\n        {\n            ExitDiagnosticSession(connection);\n        }\n\n\n        public override string GetProtocolName()\n        {\n            return \"KW2C3PE\";\n        }\n\n        public override bool SupportsUnlocking()\n        {\n            return true;\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/DiagnosticProtocol/UDS.cs",
    "content": "﻿using Caesar;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing static Caesar.DTC;\n\nnamespace Diogenes.DiagnosticProtocol\n{\n    public class UDS : BaseProtocol\n    {\n        private static string[] NegativeResponseDescriptions = new string[] { };\n        private static Dictionary<int, string> MessageDescriptions = new Dictionary<int, string>();\n\n        private static string[] GetNegativeResponseDescriptions() \n        {\n            if (NegativeResponseDescriptions.Length == 0) \n            {\n                NegativeResponseDescriptions = new string[0xFF];\n                for (int i = 0; i < 0xFF; i++) \n                {\n                    NegativeResponseDescriptions[i] = \"ISO SAE Reserved\";\n                }\n                for (int i = 0x38; i <= 0x4F; i++)\n                {\n                    NegativeResponseDescriptions[i] = \"Reserved By Extended Data Link Security Document\";\n                }\n                for (int i = 0x94; i <= 0xEF; i++)\n                {\n                    NegativeResponseDescriptions[i] = \"Reserved For Specific Conditions Not Correct\";\n                }\n                for (int i = 0xF0; i <= 0xFE; i++)\n                {\n                    NegativeResponseDescriptions[i] = \"Vehicle Manufacturer Specific Conditions Not Correct\";\n                }\n                NegativeResponseDescriptions[0x00] = \"Positive Response\";\n                NegativeResponseDescriptions[0x10] = \"General Reject\";\n                NegativeResponseDescriptions[0x11] = \"Service Not Supported\";\n                NegativeResponseDescriptions[0x12] = \"Sub-function Not Supported\";\n                NegativeResponseDescriptions[0x13] = \"Incorrect Message Length Or Invalid Format\";\n                NegativeResponseDescriptions[0x14] = \"Response Too Long\";\n                NegativeResponseDescriptions[0x21] = \"Busy Repeat Request\";\n                NegativeResponseDescriptions[0x22] = \"Conditions Not Correct\";\n                NegativeResponseDescriptions[0x24] = \"Request Sequence Error\";\n                NegativeResponseDescriptions[0x25] = \"No Response From Sub-net Component\";\n                NegativeResponseDescriptions[0x26] = \"Failure Prevents Execution Of Requested Action\";\n                NegativeResponseDescriptions[0x31] = \"Request Out Of Range\";\n                NegativeResponseDescriptions[0x33] = \"Security Access Denied\";\n                NegativeResponseDescriptions[0x35] = \"Invalid Key\";\n                NegativeResponseDescriptions[0x36] = \"Exceed Number Of Attempts\";\n                NegativeResponseDescriptions[0x37] = \"Required Time Delay Not Expired\";\n                NegativeResponseDescriptions[0x70] = \"Upload Download Not Accepted\";\n                NegativeResponseDescriptions[0x71] = \"Transfer Data Suspended\";\n                NegativeResponseDescriptions[0x72] = \"General Programming Failure\";\n                NegativeResponseDescriptions[0x73] = \"Wrong Block Sequence Counter\";\n                NegativeResponseDescriptions[0x78] = \"Request Correctly Received-Response Pending\";\n                NegativeResponseDescriptions[0x7E] = \"Sub-function Not Supported In Active Session\";\n                NegativeResponseDescriptions[0x7F] = \"Service Not Supported In Active Session\";\n                NegativeResponseDescriptions[0x81] = \"Rpm Too High\";\n                NegativeResponseDescriptions[0x82] = \"Rpm Too Low\";\n                NegativeResponseDescriptions[0x83] = \"Engine Is Running\";\n                NegativeResponseDescriptions[0x84] = \"Engine Is Not Running\";\n                NegativeResponseDescriptions[0x85] = \"Engine Run Time Too Low\";\n                NegativeResponseDescriptions[0x86] = \"Temperature is Too High\";\n                NegativeResponseDescriptions[0x87] = \"Temperature is Too Low\";\n                NegativeResponseDescriptions[0x88] = \"Vehicle Speed is Too High\";\n                NegativeResponseDescriptions[0x89] = \"Vehicle Speed is Too Low\";\n                NegativeResponseDescriptions[0x8A] = \"Throttle/Pedal is Too High\";\n                NegativeResponseDescriptions[0X8B] = \"Throttle/Pedal IS Too Low\";\n                NegativeResponseDescriptions[0X8C] = \"Transmission Range Is Not In Neutral\";\n                NegativeResponseDescriptions[0x8D] = \"Transmission Range is Not In Gear\";\n                NegativeResponseDescriptions[0x8F] = \"Brake Switch(es) Not Closed (Brake Pedal not pressed or not applied)\";\n                NegativeResponseDescriptions[0x90] = \"Shifter Lever Not In Park\";\n                NegativeResponseDescriptions[0x91] = \"Torque Converter Clutch is Locked\";\n                NegativeResponseDescriptions[0x92] = \"Voltage is Too High\";\n                NegativeResponseDescriptions[0x93] = \"Voltage Too Low\";\n            }\n\n            return NegativeResponseDescriptions;\n        }\n\n        private static Dictionary<int, string> GetMessageDescriptions() \n        {\n            if (MessageDescriptions.Count == 0) \n            {\n                MessageDescriptions.Add(0x10, \"Diagnostic Session Control\");\n                MessageDescriptions.Add(0x11, \"ECU Reset\");\n                MessageDescriptions.Add(0x27, \"Security Access\");\n                MessageDescriptions.Add(0x28, \"Communication Control\");\n                MessageDescriptions.Add(0x29, \"Authentication\");\n                MessageDescriptions.Add(0x3E, \"Tester Present\");\n                MessageDescriptions.Add(0x83, \"Access Timing Parameters\");\n                MessageDescriptions.Add(0x84, \"Secured Data Transmission\");\n                MessageDescriptions.Add(0x85, \"Control DTC Settings\");\n                MessageDescriptions.Add(0x86, \"Response On Event\");\n                MessageDescriptions.Add(0x87, \"Link Control\");\n                MessageDescriptions.Add(0x22, \"Read Data By Identifier\");\n                MessageDescriptions.Add(0x23, \"Read Memory By Address\");\n                MessageDescriptions.Add(0x24, \"Read Scaling Data By Identifier\");\n                MessageDescriptions.Add(0x2A, \"Read Data By Identifier Periodic\");\n                MessageDescriptions.Add(0x2C, \"Dynamically Define Data Identifier\");\n                MessageDescriptions.Add(0x2E, \"Write Data By Identifier\");\n                MessageDescriptions.Add(0x3D, \"Write Memory By Address\");\n                MessageDescriptions.Add(0x14, \"Clear Diagnostic Information\");\n                MessageDescriptions.Add(0x19, \"Read DTC Information\");\n                MessageDescriptions.Add(0x2F, \"Input Output Control By Identifier\");\n                MessageDescriptions.Add(0x31, \"Routine Control\");\n                MessageDescriptions.Add(0x34, \"Request Download\");\n                MessageDescriptions.Add(0x35, \"Request Upload\");\n                MessageDescriptions.Add(0x36, \"Transfer Data\");\n                MessageDescriptions.Add(0x37, \"Request Transfer Exit\");\n                MessageDescriptions.Add(0x38, \"Request File Transfer\");\n            }\n            return MessageDescriptions;\n        }\n\n\n        public static string GetCommandDescription(byte[] command) \n        {\n            if (command.Length == 0) \n            {\n                return \"Internal error: command buffer is empty\";\n            }\n\n            // handle NR first\n            if (command[0] == 0x7F) \n            {\n                string response = \"Negative Response\";\n                if (command.Length > 1) \n                {\n                    response = $\"{response}: {GetNegativeResponseDescriptions()[command[1]]}\";\n                }\n                return response;\n            }\n\n            Dictionary<int, string> descriptions = GetMessageDescriptions();\n            if (descriptions.ContainsKey(command[0]))\n            {\n                return $\"Request: {descriptions[command[0]]}\";\n            }\n\n            int tryAsResponse = command[0] - 0x40;\n\n            if (descriptions.ContainsKey(tryAsResponse))\n            {\n                return $\"Response: {descriptions[tryAsResponse]}\";\n            }\n            return \"Unknown\";\n        }\n\n        private static bool IsNegativeResponse(byte[] command)\n        {\n            return ((command.Length > 0) && (command[0] == 0x7F));\n        }\n\n        private static bool EnterDiagnosticSession(ECUConnection connection)\n        {\n            Console.WriteLine(\"UDS: Switching session states\");\n            byte[] sessionSwitchResponse = connection.SendMessage(new byte[] { 0x10, 0x03 });\n            byte[] sessionExpectedResponse = new byte[] { 0x50, 0x03 };\n            if (!sessionSwitchResponse.Take(2).SequenceEqual(sessionExpectedResponse))\n            {\n                Console.WriteLine($\"Failed to switch session : target responded with [{BitUtility.BytesToHex(sessionSwitchResponse, true)}]\");\n                return false;\n            }\n            return true;\n        }\n        \n        private static bool ExitDiagnosticSession(ECUConnection connection)\n        {\n            Console.WriteLine(\"UDS: Switching session states\");\n            byte[] sessionSwitchResponse = connection.SendMessage(new byte[] { 0x10, 0x01 });\n            byte[] sessionExpectedResponse = new byte[] { 0x50, 0x01 };\n            if (!sessionSwitchResponse.Take(2).SequenceEqual(sessionExpectedResponse))\n            {\n                Console.WriteLine($\"Failed to switch session : target responded with [{BitUtility.BytesToHex(sessionSwitchResponse, true)}]\");\n                return false;\n            }\n            return true;\n        }\n\n        private static bool GetVariantID(ECUConnection connection, out int variantId) \n        {\n            byte[] variantQueryResponse = connection.SendMessage(new byte[] { 0x22, 0xF1, 0x00 });\n            byte[] variantExpectedResponse = new byte[] { 0x62, 0xF1 };\n\n            if (!variantQueryResponse.Take(2).SequenceEqual(variantExpectedResponse))\n            {\n                Console.WriteLine($\"Failed to identify variant (unexpected response) : target responded with [{BitUtility.BytesToHex(variantQueryResponse, true)}]\");\n                variantId = 0;\n                return false;\n            }\n            else \n            {\n                // found a variant id, check loaded ecus if any of them have a match\n                variantId = (variantQueryResponse[3] << 16) | (variantQueryResponse[4] << 8) | variantQueryResponse[5];\n                return true;\n            }\n        }\n\n        public override List<DTCContext> ReportDtcsByStatusMask(ECUConnection connection, ECUVariant variant, byte inMask = 0)\n        {\n            List<DTCContext> dtcCtx = new List<DTCContext>();\n\n            byte mask = (byte)(DTCStatusByte.TestFailedAtRequestTime |\n                DTCStatusByte.TestFailedAtCurrentCycle |\n                DTCStatusByte.PendingDTC |\n                DTCStatusByte.ConfirmedDTC |\n                DTCStatusByte.TestFailedSinceLastClear);\n            byte[] request = new byte[] { 0x19, 0x02, inMask == 0 ? mask : inMask };\n            byte[] expectedResponse = new byte[] { 0x59, 0x02 };\n\n            byte[] response = connection.SendMessage(request);\n            if (!response.Take(expectedResponse.Length).SequenceEqual(expectedResponse))\n            {\n                return new List<DTCContext>();\n            }\n            for (int i = 3; i < response.Length; i += 4)\n            {\n                byte[] dtcRow = new byte[4];\n                Array.ConstrainedCopy(response, i, dtcRow, 0, 4);\n                byte statusMask = dtcRow[3];\n                long dtcIdRaw = ((dtcRow[0] << 16) | (dtcRow[1] << 8) | dtcRow[2]);\n                // fixup DTC prefix in https://github.com/jglim/CaesarSuite/issues/36\n                int dtcId = (int)dtcIdRaw & 0x3FFFFF; // id is the lowest 22 bits\n                int dtcPrefix = (int)(dtcIdRaw >> 22) & 3; // prefix is the next 2 bits\n\n                string[] prefixTable = new string[] {\n                    \"P\", // powertrain\n                    \"C\", // chassis\n                    \"B\", // body\n                    \"U\"  // network\n                };\n\n                string dtcIdentifier = $\"{prefixTable[dtcPrefix]}{dtcId:X6}\";\n\n                DTC foundDtc = FindDTCById(dtcIdentifier, variant);\n                if (foundDtc is null)\n                {\n                    Console.WriteLine($\"DTC: No matching DTC available for {dtcIdentifier}\");\n                }\n                else\n                {\n                    dtcCtx.Add(new DTCContext() { DTC = foundDtc, StatusByte = statusMask, EnvironmentContext = new List<string[]>() });\n                }\n            }\n            return dtcCtx;\n        }\n\n        public override bool GetDtcSnapshot(DTC dtc, ECUConnection connection, out byte[] snapshotBytes)\n        {\n            byte[] identifier = BitUtility.BytesFromHex(dtc.Qualifier.Substring(1));\n\n            // apparently the existing dtc's mask should be ignored, use FF instead\n            byte[] request = new byte[] { 0x19, 0x06, identifier[0], identifier[1], identifier[2], 0xFF };\n            byte[] expectedResponse = new byte[] { 0x59, 0x06 };\n\n            byte[] response = connection.SendMessage(request);\n            if (response.Take(expectedResponse.Length).SequenceEqual(expectedResponse))\n            {\n                snapshotBytes = response;\n                return true;\n            }\n            else\n            {\n                snapshotBytes = new byte[] { };\n                return false;\n            }\n        }\n\n        public override ECUMetadata QueryECUMetadata(ECUConnection connection)\n        {\n            ECUMetadata metadata = new ECUMetadata();\n            if (ReadDataByIdentifier(connection, 0xF100, out byte[] diagInfoRaw))\n            {\n                byte session = diagInfoRaw[3];\n                byte gateway = diagInfoRaw[0];\n                uint variant = (uint)((diagInfoRaw[1] << 8) | diagInfoRaw[2]);\n                metadata.GatewayMode = gateway == 2;\n                metadata.VariantID = variant;\n            }\n\n            if (ReadDataByIdentifier(connection, 0xF111, out byte[] hardwareId))\n            {\n                metadata.HardwarePartNumber = Encoding.ASCII.GetString(hardwareId);\n            }\n            if (ReadDataByIdentifier(connection, 0xF150, out byte[] hardwareVersion))\n            {\n                metadata.HardwareVersion = $\"{hardwareVersion[0]:D2}/{hardwareVersion[1]:D2}.{hardwareVersion[2]:D2}\";\n            }\n            if (ReadDataByIdentifier(connection, 0xF154, out byte[] hardwareVendor))\n            {\n                metadata.VendorID = hardwareVendor[1]; // first byte for vendor is usually discarded; value does not fit BE\n            }\n            if (ReadDataByIdentifier(connection, 0xF153, out byte[] bootVersion))\n            {\n                metadata.BootVersion = $\"{bootVersion[0]:D2}/{bootVersion[1]:D2}.{bootVersion[2]:D2}\";\n            }\n            if (ReadDataByIdentifier(connection, 0xF18C, out byte[] serialNumber))\n            {\n                metadata.SerialNumber = Encoding.ASCII.GetString(serialNumber);\n            }\n            if (ReadDataByIdentifier(connection, 0xF190, out byte[] vinOriginal))\n            {\n                metadata.ChassisNumberOriginal = Encoding.ASCII.GetString(vinOriginal);\n            }\n            if (ReadDataByIdentifier(connection, 0xF1A0, out byte[] vinCurrent))\n            {\n                metadata.ChassisNumberCurrent = Encoding.ASCII.GetString(vinCurrent);\n            }\n\n            // read flash blocks, normally code/data/flash\n\n            if (ReadDataByIdentifier(connection, 0xF121, out byte[] fwIdentifier))\n            {\n                ReadDataByIdentifier(connection, 0xF151, out byte[] aggregateFwVersion);\n                ReadDataByIdentifier(connection, 0xF155, out byte[] aggregateSupplierIdent);\n                ReadDataByIdentifier(connection, 0xF15B, out byte[] aggregateFingerprint);\n\n                int versionWidth = 3;\n                int vendorWidth = 2;\n                int fingerprintWidth = 10;\n                int pnWidth = 10;\n\n                if (fwIdentifier.Length % pnWidth != 0) \n                {\n                    Console.WriteLine(\"[!] Block PartNumber is not boundary aligned\");\n                }\n                int blockCount = fwIdentifier.Length / pnWidth;\n\n                metadata.FlashMetadata = new List<ECUFlashMetadata>();\n                for (int i = 0; i < blockCount; i++)\n                {\n                    byte[] localPn = fwIdentifier.Skip(i * pnWidth).Take(pnWidth).ToArray();\n                    byte[] localFwVersion = aggregateFwVersion.Skip(i * versionWidth).Take(versionWidth).ToArray();\n                    byte[] localSupplierIdent = aggregateSupplierIdent.Skip(i * vendorWidth).Take(vendorWidth).ToArray();\n                    byte[] localFingerprint = aggregateFingerprint.Skip(i * fingerprintWidth).Take(fingerprintWidth).ToArray();\n\n                    ECUFlashMetadata flashMetadata = new ECUFlashMetadata();\n                    flashMetadata.Index = i;\n                    flashMetadata.PartNumber = Encoding.ASCII.GetString(localPn);\n                    flashMetadata.Version = $\"{localFwVersion[0]:D2}/{localFwVersion[1]:D2}.{localFwVersion[2]:D2}\";\n                    flashMetadata.VendorID = localSupplierIdent[1];\n                    flashMetadata.StatusID = localFingerprint[0];\n                    flashMetadata.LastFlashVendor = localFingerprint[2];\n                    flashMetadata.FlashDate = $\"{localFingerprint[3]:D2}-{localFingerprint[4]:D2}-{localFingerprint[5]:D2}\"; // no idea what sort of date format; all 3 fields can hold values above 12\n                    flashMetadata.FlashFingerprint = BitUtility.BytesToHex(localFingerprint.Skip(6).ToArray());\n                    metadata.FlashMetadata.Add(flashMetadata);\n                }\n            }\n\n            return metadata;\n        }\n\n        private static bool ReadDataByIdentifier(ECUConnection connection, ushort identifier, out byte[] buffer)\n        {\n            buffer = new byte[] { };\n            byte identifierMsb = (byte)((identifier >> 8) & 0xFF);\n            byte identifierLsb = (byte)(identifier & 0xFF);\n            byte[] response = connection.SendMessage(new byte[] { 0x22, identifierMsb, identifierLsb });\n            if (response.Length < 3) \n            {\n                return false;\n            }\n            if (response[0] != 0x62) \n            {\n                return false;\n            }\n            buffer = response.Skip(3).ToArray();\n            return true;\n        }\n\n        public override void ConnectionEstablishedHandler(ECUConnection connection)\n        {\n            if (!EnterDiagnosticSession(connection))\n            {\n                return;\n            }\n            if (GetVariantID(connection, out int variantId))\n            {\n                connection.VariantIsAvailable = true;\n                connection.ECUVariantID = variantId;\n                Console.WriteLine($\"Variant has been successfully configured as {(variantId & 0xFFFF):X4}\");\n            }\n            else \n            {\n                return;\n            }\n        }\n\n        public override void SendTesterPresent(ECUConnection connection)\n        {\n            connection.SendMessage(new byte[] { 0x3E, 0x00 }, true);\n        }\n\n        public override bool IsResponseToTesterPresent(byte[] inBuffer)\n        {\n            return inBuffer.SequenceEqual(new byte[] { 0x7E, 0x00 });\n        }\n\n        public override void ConnectionClosingHandler(ECUConnection connection)\n        {\n            ExitDiagnosticSession(connection);\n        }\n\n        public override string GetProtocolName()\n        {\n            return \"UDS\";\n        }\n\n        public override bool SupportsUnlocking()\n        {\n            return true;\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/DiagnosticProtocol/UnsupportedProtocol.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Diogenes.DiagnosticProtocol\n{\n    public class UnsupportedProtocol : BaseProtocol\n    {\n        public override void ConnectionEstablishedHandler(ECUConnection connection)\n        {\n            //Console.WriteLine(\"The current protocol is unsupported. Most functions will not be available.\");\n        }\n\n        public override string GetProtocolName()\n        {\n            return \"UnsupportedProtocol\";\n        }\n\n        public override bool SupportsUnlocking()\n        {\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/Diogenes.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{2216DB99-EAAC-46A8-B99A-28D659907DE7}</ProjectGuid>\n    <OutputType>WinExe</OutputType>\n    <RootNamespace>Diogenes</RootNamespace>\n    <AssemblyName>Diogenes</AssemblyName>\n    <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>\n    <Deterministic>true</Deterministic>\n    <IsWebBootstrapper>false</IsWebBootstrapper>\n    <PublishUrl>publish\\</PublishUrl>\n    <Install>true</Install>\n    <InstallFrom>Disk</InstallFrom>\n    <UpdateEnabled>false</UpdateEnabled>\n    <UpdateMode>Foreground</UpdateMode>\n    <UpdateInterval>7</UpdateInterval>\n    <UpdateIntervalUnits>Days</UpdateIntervalUnits>\n    <UpdatePeriodically>false</UpdatePeriodically>\n    <UpdateRequired>false</UpdateRequired>\n    <MapFileExtensions>true</MapFileExtensions>\n    <ApplicationRevision>0</ApplicationRevision>\n    <ApplicationVersion>1.1.0.%2a</ApplicationVersion>\n    <UseApplicationTrust>false</UseApplicationTrust>\n    <BootstrapperEnabled>true</BootstrapperEnabled>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup>\n    <StartupObject />\n  </PropertyGroup>\n  <PropertyGroup>\n    <ApplicationIcon>diogenes-256.ico</ApplicationIcon>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Be.Windows.Forms.HexBox, Version=1.6.1.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Be.Windows.Forms.HexBox.1.6.1\\lib\\net40\\Be.Windows.Forms.HexBox.dll</HintPath>\n    </Reference>\n    <Reference Include=\"J2534-Sharp, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\J2534-Sharp.1.0.0-CI00026\\lib\\net46\\J2534-Sharp.dll</HintPath>\n    </Reference>\n    <Reference Include=\"PresentationCore\" />\n    <Reference Include=\"PresentationFramework\" />\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Deployment\" />\n    <Reference Include=\"System.Drawing\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Windows.Forms\" />\n    <Reference Include=\"System.Xml\" />\n    <Reference Include=\"WindowsFormsIntegration\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Forms\\BlockDownload.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Forms\\BlockDownload.Designer.cs\">\n      <DependentUpon>BlockDownload.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"DiagnosticProtocol\\KW2C3PE.cs\" />\n    <Compile Include=\"DiagnosticProtocol\\UDS.cs\" />\n    <Compile Include=\"DiagnosticProtocol\\UnsupportedProtocol.cs\" />\n    <Compile Include=\"ECUIdentification.cs\" />\n    <Compile Include=\"Reports\\DTCReport.cs\" />\n    <Compile Include=\"ECUFlashMetadata.cs\" />\n    <Compile Include=\"ECUMetadata.cs\" />\n    <Compile Include=\"Forms\\AboutForm.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Forms\\AboutForm.Designer.cs\">\n      <DependentUpon>AboutForm.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"ECUConnection.cs\" />\n    <Compile Include=\"Forms\\DTCForm.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Forms\\DTCForm.Designer.cs\">\n      <DependentUpon>DTCForm.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"Forms\\FlashSplicer.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Forms\\FlashSplicer.Designer.cs\">\n      <DependentUpon>FlashSplicer.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"Forms\\GenericLoader.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Forms\\GenericLoader.Designer.cs\">\n      <DependentUpon>GenericLoader.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"Forms\\GenericPicker.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Forms\\GenericPicker.Designer.cs\">\n      <DependentUpon>GenericPicker.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"Forms\\PickDiagForm.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Forms\\PickDiagForm.Designer.cs\">\n      <DependentUpon>PickDiagForm.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"Forms\\RunDiagForm.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Forms\\RunDiagForm.Designer.cs\">\n      <DependentUpon>RunDiagForm.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"DiagnosticProtocol\\BaseProtocol.cs\" />\n    <Compile Include=\"Preferences.cs\" />\n    <Compile Include=\"SecurityAccess\\DllContext.cs\" />\n    <Compile Include=\"SecurityAccess\\ExportDefinition.cs\" />\n    <Compile Include=\"Forms\\MainForm.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Forms\\MainForm.Designer.cs\">\n      <DependentUpon>MainForm.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"Program.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <Compile Include=\"Forms\\SecurityLevelForm.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Forms\\SecurityLevelForm.Designer.cs\">\n      <DependentUpon>SecurityLevelForm.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"SecurityAccess\\SecurityAutoLogin.cs\" />\n    <Compile Include=\"Simulation\\SimulatedDevice.cs\" />\n    <Compile Include=\"Simulation\\Simulated_CRD3.cs\" />\n    <Compile Include=\"TextboxWriter.cs\" />\n    <Compile Include=\"Forms\\TraceForm.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Forms\\TraceForm.Designer.cs\">\n      <DependentUpon>TraceForm.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"Forms\\UDSHexEditor.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Forms\\UDSHexEditor.Designer.cs\">\n      <DependentUpon>UDSHexEditor.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"UnmanagedUtility.cs\" />\n    <Compile Include=\"Forms\\VCForm.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Forms\\VCForm.Designer.cs\">\n      <DependentUpon>VCForm.cs</DependentUpon>\n    </Compile>\n    <Compile Include=\"VariantCoding.cs\" />\n    <Compile Include=\"Reports\\VCReport.cs\" />\n    <EmbeddedResource Include=\"Forms\\AboutForm.resx\">\n      <DependentUpon>AboutForm.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Forms\\BlockDownload.resx\">\n      <DependentUpon>BlockDownload.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Forms\\DTCForm.resx\">\n      <DependentUpon>DTCForm.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Forms\\FlashSplicer.resx\">\n      <DependentUpon>FlashSplicer.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Forms\\GenericLoader.resx\">\n      <DependentUpon>GenericLoader.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Forms\\GenericPicker.resx\">\n      <DependentUpon>GenericPicker.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Forms\\MainForm.resx\">\n      <DependentUpon>MainForm.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Forms\\PickDiagForm.resx\">\n      <DependentUpon>PickDiagForm.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Properties\\Resources.resx\">\n      <Generator>ResXFileCodeGenerator</Generator>\n      <LastGenOutput>Resources.Designer.cs</LastGenOutput>\n      <SubType>Designer</SubType>\n    </EmbeddedResource>\n    <Compile Include=\"Properties\\Resources.Designer.cs\">\n      <AutoGen>True</AutoGen>\n      <DependentUpon>Resources.resx</DependentUpon>\n      <DesignTime>True</DesignTime>\n    </Compile>\n    <EmbeddedResource Include=\"Forms\\RunDiagForm.resx\">\n      <DependentUpon>RunDiagForm.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Forms\\SecurityLevelForm.resx\">\n      <DependentUpon>SecurityLevelForm.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Forms\\TraceForm.resx\">\n      <DependentUpon>TraceForm.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Forms\\VCForm.resx\">\n      <DependentUpon>VCForm.cs</DependentUpon>\n    </EmbeddedResource>\n    <EmbeddedResource Include=\"Forms\\UDSHexEditor.resx\">\n      <DependentUpon>UDSHexEditor.cs</DependentUpon>\n    </EmbeddedResource>\n    <None Include=\"packages.config\" />\n    <None Include=\"Properties\\Settings.settings\">\n      <Generator>SettingsSingleFileGenerator</Generator>\n      <LastGenOutput>Settings.Designer.cs</LastGenOutput>\n    </None>\n    <Compile Include=\"Properties\\Settings.Designer.cs\">\n      <AutoGen>True</AutoGen>\n      <DependentUpon>Settings.settings</DependentUpon>\n      <DesignTimeSharedInput>True</DesignTimeSharedInput>\n    </Compile>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"App.config\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\Caesar\\Caesar.csproj\">\n      <Project>{71c43c61-7dc7-4d47-9947-1dd73e559911}</Project>\n      <Name>Caesar</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\brick.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\house.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\cog.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\blank.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\box.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\connect.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\information.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\bullet_black.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\bullet_blue.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\bullet_go.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\bullet_green.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\bullet_orange.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\bullet_pink.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\bullet_purple.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\bullet_red.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\bullet_star.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\bullet_white.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\bullet_yellow.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\computer_go.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\lock_edit.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\key.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\application_xp_terminal.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <BootstrapperPackage Include=\".NETFramework,Version=v4.6\">\n      <Visible>False</Visible>\n      <ProductName>Microsoft .NET Framework 4.6 %28x86 and x64%29</ProductName>\n      <Install>true</Install>\n    </BootstrapperPackage>\n    <BootstrapperPackage Include=\"Microsoft.Net.Framework.3.5.SP1\">\n      <Visible>False</Visible>\n      <ProductName>.NET Framework 3.5 SP1</ProductName>\n      <Install>false</Install>\n    </BootstrapperPackage>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\page_white_edit.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\asterisk_orange.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\folder.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\accept.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Resources\\report.png\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Content Include=\"diogenes-256.ico\" />\n    <None Include=\"Resources\\diogenes.png\" />\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n</Project>"
  },
  {
    "path": "Caesar/Diogenes/ECUConnection.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing SAE.J2534;\nusing Caesar;\nusing System.Timers;\nusing System.Diagnostics;\nusing Diogenes.DiagnosticProtocol;\nusing Diogenes.SecurityAccess;\n\nnamespace Diogenes\n{\n    /*\n    example communication params:\n\n    HSCAN_UDS_500\n\n    CP_BAUDRATE : 500000 (0x7A120)\n\n    CP_GLOBAL_REQUEST_CANIDENTIFIER : 1089 (0x441)\n    CP_FUNCTIONAL_REQUEST_CANIDENTIFIER : 1089 (0x441)\n    CP_REQUEST_CANIDENTIFIER : 2016 (0x7E0)\n    CP_RESPONSE_CANIDENTIFIER : 2024 (0x7E8)\n    \n    CP_PARTNUMBERID : 0 (0x0)\n    CP_PARTBLOCK : 1 (0x1)\n    \n    CP_HWVERSIONID : 0 (0x0)\n    CP_SWVERSIONID : 0 (0x0)\n    CP_SWVERSIONBLOCK : 1 (0x1)\n    CP_SUPPLIERID : 61780 (0xF154)\n    CP_SWSUPPLIERBLOCK : 1 (0x1)\n    \n    CP_ADDRESSMODE : 0 (0x0)\n    CP_ADDRESSEXTENSION : 0 (0x0)\n    \n    CP_ROE_RESPONSE_CANIDENTIFIER : 0 (0x0)\n    CP_USE_TIMING_RECEIVED_FROM_ECU : 0 (0x0)\n    \n    CP_STMIN_SUG : 0 (0x0)\n    CP_BLOCKSIZE_SUG : 8 (0x8)\n    \n    CP_P2_TIMEOUT : 2100 (0x834)\n    CP_P2_EXT_TIMEOUT_7F_78 : 4500 (0x1194)\n    CP_S3_TP_PHYS_TIMER : 2000 (0x7D0)\n    CP_S3_TP_FUNC_TIMER : 2000 (0x7D0)\n    \n    CP_BR_SUG : 0 (0x0)\n    CP_CAN_TRANSMIT : 0 (0x0)\n    CP_BS_MAX : 2000 (0x7D0)\n    CP_CS_MAX : 2000 (0x7D0)\n    \n    CP_P2_EXT_TIMEOUT_7F_21 : 200 (0xC8)\n    CPI_ROUTINECOUNTER : 30 (0x1E)\n    CP_REQREPCOUNT : 3 (0x3)\n\n     */\n    public class ECUConnection\n    {\n        public API ConnectionAPI;\n        public Device ConnectionDevice;\n        public Channel ConnectionChannel;\n        public Simulation.SimulatedDevice SimulationChannel;\n\n        public string DriverPath = \"\";\n\n        public delegate void ConnectionStateChanged(string newStateDescription);\n        public ConnectionStateChanged ConnectionStateChangeEvent;\n\n        public string FriendlyName = \"Simulation\";\n        public string FriendlyProfileName = \"SIMULATION_PROFILE\";\n\n        public ConnectionState State;\n        public byte[] CanIdentifier = new byte[] { 0xDE, 0xAD, 0xBE, 0xEF };\n        public byte[] RxCanIdentifier = new byte[] { 0xDE, 0xAD, 0xBE, 0xEF };\n        public int InternalTimeout = 2000;\n        public ECU EcuContext;\n\n        public int ECUVariantID = 0;\n        public bool VariantIsAvailable = false;\n        public BaseProtocol ConnectionProtocol = null;\n\n        // this should really go into a dedicated logger\n        public StringBuilder CommunicationsLogHighLevel = new StringBuilder();\n        public readonly object WriteLock = new object();\n\n        // constant 2000 ms as recomended by the ISO 15765-3 standard (§6.3.3).\n        public Timer TesterPresentTimer = new Timer(2000);\n\n        // holds out-of-order, non testerpresent bytes since packets (apparently) can be received in any order\n        Queue<byte[]> OutOfOrderBytesList = new Queue<byte[]>();\n\n        public enum ConnectionState\n        {\n            PendingDeviceSelection,\n            DeviceSelectedPendingChannelConnection,\n            ChannelConnectedPendingEcuContact,\n            EcuContacted\n        }\n\n        public enum ConnectResponse \n        {\n            OK,\n            NoValidInterface,\n            UnsupportedProtocol,\n            FailedWithException\n        }\n\n        public ECUConnection()\n        {\n            // create a dummy connection\n            FriendlyName = \"Simulation\";\n            FriendlyProfileName = \"SIMULATION_PROFILE\";\n            State = ConnectionState.PendingDeviceSelection;\n            ConnectionUpdateState();\n        }\n\n        public ECUConnection(string fileName, string friendlyName)\n        {\n            DriverPath = fileName;\n            InternalTimeout = 2000;\n\n            if (!IsSimulation())\n            {\n                // apparently AVDI embeds their hardware identifier in the device's name and path, which might be regarded as sensitive when sharing\n                // this redacts it (somewhat) to help save some time for testers\n                if (DriverIsAVDI())\n                {\n                    FriendlyName = \"AVDI-PT\";\n                    Console.WriteLine($\"Initializing new connection to {friendlyName}\");\n                }\n                else\n                {\n                    FriendlyName = friendlyName;\n                    Console.WriteLine($\"Initializing new connection to {friendlyName} using {fileName}\");\n                }\n                ConnectionAPI = APIFactory.GetAPI(fileName);\n            }\n            else \n            {\n                FriendlyName = \"Simulation\";\n                ConnectionAPI = null;\n            }\n\n            SetConnectionDefaults();\n            State = ConnectionState.PendingDeviceSelection;\n            ConnectionUpdateState();\n            TesterPresentTimer.Elapsed += TesterPresentTimer_Elapsed;\n            TesterPresentTimer.Start();\n        }\n\n        public bool IsSimulation() \n        {\n            return DriverPath == \"SIMULATION\";\n        }\n\n        public static List<Tuple<string, string>> GetAvailableJ2534NamesAndDrivers() \n        {\n            List<Tuple<string, string>> result = new List<Tuple<string, string>>();\n            foreach (APIInfo apiInfo in APIFactory.GetAPIList())\n            {\n                result.Add(new Tuple<string, string>(apiInfo.Name, apiInfo.Filename));\n            }\n#if DEBUG\n            result.Add(new Tuple<string, string>(\"Simulation\", \"SIMULATION\"));\n#endif\n            return result;\n        }\n\n        private void TesterPresentTimer_Elapsed(object sender, ElapsedEventArgs e)\n        {\n            // normally we would wait until the session was switched to extended, but we don't know for sure. seems to be probably OK to send this as-is?\n            if (State > ConnectionState.DeviceSelectedPendingChannelConnection)\n            {\n                // TesterPresent, expects 0x7E, 0x00\n                if (ConnectionProtocol != null)\n                {\n                    ConnectionProtocol.SendTesterPresent(this);\n                }\n            }\n        }\n\n        public void OpenDevice()\n        {\n            if (!IsSimulation())\n            {\n                try\n                {\n                    ConnectionDevice = ConnectionAPI.GetDevice();\n                }\n                catch (Exception ex)\n                {\n                    Console.WriteLine(ex.Message);\n                }\n            }\n            State = ConnectionState.DeviceSelectedPendingChannelConnection;\n            ConnectionUpdateState();\n        }\n\n        private void ConnectionUpdateState()\n        {\n            if (IsSimulation())\n            {\n                ConnectionStateChangeEvent?.Invoke($\"Operating in simulation mode\");\n                return;\n            }\n\n            string connectionState = \"No interface selected (disconnected)\";\n            if (ConnectionDevice != null)\n            {\n                connectionState = $\"Device: {FriendlyName} online\";\n                if (ConnectionChannel != null)\n                {\n                    connectionState = $\"{connectionState}, connected with profile '{FriendlyProfileName}'\";\n                }\n                else\n                {\n                    connectionState = $\"{connectionState}, disconnected\";\n                }\n            }\n            ConnectionStateChangeEvent?.Invoke(connectionState);\n        }\n\n        public void SetConnectionDefaults() \n        {\n            ECUVariantID = 0;\n            VariantIsAvailable = false;\n            ConnectionProtocol = null;\n        }\n\n        public ConnectResponse Connect(ECUInterfaceSubtype profile, ECU ecuContext)\n        {\n            State = ConnectionState.PendingDeviceSelection;\n            EcuContext = ecuContext;\n\n            if (!IsSimulation())\n            {\n                if (ConnectionDevice is null)\n                {\n                    Console.WriteLine(\"No interfaces available : please select a J2534 interface from the Connection menu\");\n                    return ConnectResponse.NoValidInterface;\n                }\n            }\n\n            if (!profile.Qualifier.StartsWith(\"HSCAN\"))\n            {\n                Console.WriteLine(\"Profile not supported: only HSCAN interfaces are supported.\");\n                return ConnectResponse.UnsupportedProtocol;\n            }\n\n            ConnectionProtocol = BaseProtocol.GetProtocol(profile.Qualifier);\n\n            // actually start fixing up the connection\n            if (ConnectionChannel != null)\n            {\n                ConnectionChannel.Dispose();\n                ConnectionChannel = null;\n            }\n            FriendlyProfileName = profile.Qualifier;\n\n            if (IsSimulation()) \n            {\n                SimulationChannel = new Simulation.Simulated_CRD3();\n                Console.WriteLine(\"Connected (Simulation)\");\n            }\n            else \n            {\n                try\n                {\n                    // only ISO15765 is supported\n                    // CAN_ID_BOTH : accepts 11-bit and 29-bit CAN messages\n                    // baudrate is specified by the ECU\n                    ConnectionChannel = ConnectionDevice.GetChannel(Protocol.ISO15765, (Baud)profile.GetComParameterValue(ECUInterfaceSubtype.ParamName.CP_BAUDRATE), ConnectFlag.CAN_ID_BOTH);\n                    Console.WriteLine($\"Target voltage : {ConnectionChannel.MeasureBatteryVoltage()} mV\");\n                    ConnectionChannel.DefaultTxFlag = TxFlag.ISO15765_FRAME_PAD;\n\n                    SetCANIdentifiers(profile);\n                    J2534SetFilters();\n                    J2534SetConfig(profile);\n                    J2534FlushBuffers();\n                }\n                catch (Exception e)\n                {\n                    Console.WriteLine($\"Connection failed with exception : {e.Message}\");\n                    return ConnectResponse.FailedWithException;\n                }\n\n                // this chunk is repeated for AVDI devices; OpenPort2 does not care, Scanmatik refuses to continue if reconfigured without clearing prior filters\n                // wrap the second attempt in a separate try block, so that we can suppress any potential filter errors\n                if (DriverIsAVDI())\n                {\n                    try\n                    {\n                        ConnectionChannel.ClearMsgFilters();\n                        SetCANIdentifiers(profile);\n                        J2534SetFilters();\n                        J2534SetConfig(profile);\n                        J2534FlushBuffers();\n                    }\n                    catch (Exception ex)\n                    {\n                        Console.WriteLine($\"AVDI Second config exception suppressed: {ex.Message}\");\n                    }\n                }\n            }\n            \n            \n            State = ConnectionState.ChannelConnectedPendingEcuContact;\n            ConnectionUpdateState();\n            return ConnectResponse.OK;\n        }\n\n        public bool DriverIsAVDI() \n        {\n            return DriverPath.ToUpper().EndsWith(\"ABRPT32.DLL\");\n        }\n\n        // this (and the overloaded variant) will be an issue when operating in gateway mode;\n        // gateway mode will likely require the two separate can ids to be defined\n        public void SetCANIdentifiers(ECUInterfaceSubtype profile)\n        {\n            SetCANIdentifiers(profile.GetComParameterValue(ECUInterfaceSubtype.ParamName.CP_REQUEST_CANIDENTIFIER), profile.GetComParameterValue(ECUInterfaceSubtype.ParamName.CP_RESPONSE_CANIDENTIFIER));\n        }\n        public void SetCANIdentifiers(int canIdentifier, int rxCanIdentifier)\n        {\n            // convert the CBF's identifier integers to byte arrays\n            CanIdentifier = BitConverter.GetBytes(canIdentifier);\n            RxCanIdentifier = BitConverter.GetBytes(rxCanIdentifier);\n            // input byte data is in big-endian\n            Array.Reverse(CanIdentifier);\n            Array.Reverse(RxCanIdentifier);\n        }\n\n        public void J2534SetFilters()\n        {\n            // setup ecu filter (mimicking vediamo's behavior)\n            MessageFilter filter = new MessageFilter();\n            // Apparently in the EIS series, the RX identifier is !! NOT !! CanIdentifier+8 per ISO15765, so the automatic config in J2534-Sharp will fail\n\n            // manually configure a ISO15765 filter\n            filter.FilterType = Filter.FLOW_CONTROL_FILTER;\n            filter.Mask = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF };\n            filter.Pattern = RxCanIdentifier; // RX address, typically CanIdentifier+8, EXCEPT EIS\n            filter.FlowControl = CanIdentifier; // TX address\n            filter.TxFlags = TxFlag.ISO15765_FRAME_PAD;\n\n            ConnectionChannel.ClearMsgFilters();\n            ConnectionChannel.StartMsgFilter(filter);\n        }\n\n        public void J2534SetConfig(ECUInterfaceSubtype profile)\n        {\n            List<SConfig> sconfigList = new List<SConfig>();\n\n            List<Tuple<Parameter, ECUInterfaceSubtype.ParamName>> comPairs = new List<Tuple<Parameter, ECUInterfaceSubtype.ParamName>>();\n            comPairs.Add(new Tuple<Parameter, ECUInterfaceSubtype.ParamName>(Parameter.STMIN_TX, ECUInterfaceSubtype.ParamName.CP_STMIN_SUG));\n            comPairs.Add(new Tuple<Parameter, ECUInterfaceSubtype.ParamName>(Parameter.ISO15765_STMIN, ECUInterfaceSubtype.ParamName.CP_STMIN_SUG));\n            comPairs.Add(new Tuple<Parameter, ECUInterfaceSubtype.ParamName>(Parameter.ISO15765_BS, ECUInterfaceSubtype.ParamName.CP_BLOCKSIZE_SUG));\n\n            foreach (Tuple<Parameter, ECUInterfaceSubtype.ParamName> comPair in comPairs)\n            {\n                // apparently some are optional so we have to check for the presence of known comparams to configure the target j2534 device\n                if (profile.GetComParameterValue(comPair.Item2, out int comValue))\n                {\n                    sconfigList.Add(new SConfig(comPair.Item1, comValue));\n                }\n            }\n            ConnectionChannel.SetConfig(sconfigList.ToArray());\n        }\n\n        public void J2534FlushBuffers()\n        {\n            ConnectionChannel.ClearRxBuffer();\n            ConnectionChannel.ClearTxBuffer();\n        }\n\n        public byte[] SendDiagRequest(DiagService diag) \n        {\n            Console.WriteLine($\"Running diagnostic request : {diag.Qualifier} ({BitUtility.BytesToHex(diag.RequestBytes, true)})\");\n            byte[] response = SendMessage(diag.RequestBytes);\n            return response;\n        }\n\n        public void ExecUserDiagJob(byte[] request, DiagService diagService)\n        {\n            Console.WriteLine($\"\\r\\n{diagService.Qualifier}\");\n            byte[] response = SendMessage(request);\n            foreach (List<DiagPreparation> wtf in diagService.OutputPreparations)\n            {\n                foreach (DiagPreparation outputPreparation in wtf)\n                {\n                    //outputPreparation.PrintDebug();\n                    DiagPresentation presentation = outputPreparation.ParentECU.GlobalPresentations[outputPreparation.PresPoolIndex];\n                    // presentation.PrintDebug();\n                    Console.WriteLine($\"{presentation.InterpretData(response, outputPreparation)}\");\n                }\n            }\n            // check if the response was an ECU seed\n            if ((ConnectionProtocol?.SupportsUnlocking() ?? false) && (response.Length >= 2) && (response[0] == 0x67))\n            {\n                SecurityAutoLogin.ReceiveSecurityResponse(response, diagService.ParentECU, this);\n            }\n        }\n\n        public byte[] SendMessage(IEnumerable<byte> message, bool testerPresenceRequest = false)\n        {\n            LogWrite(message);\n            if (IsSimulation()) \n            {\n                if (SimulationChannel is null) \n                {\n                    throw new Exception(\"Simulation channel was not initialized\");\n                }\n                byte[] simResponse = SimulationChannel.ReceiveRequest(message);\n                LogRead(simResponse);\n                return simResponse;\n            }\n\n            byte[] response = Array.Empty<byte>();\n\n\n            // prepare data to send\n            List<byte> packet = new List<byte>(CanIdentifier);\n            packet.AddRange(message);\n            string messageAsString = BitUtility.BytesToHex(message.ToArray(), true);\n            if (!testerPresenceRequest)\n            {\n                // LogPacket(message, true);\n            }\n\n            if (ConnectionDevice is null)\n            {\n                Console.WriteLine($\"[!] Attempted to write into an invalid device, data: {messageAsString}\");\n                return response;\n            }\n            if (ConnectionChannel is null) \n            {\n                Console.WriteLine($\"[!] Attempted to write into an invalid channel, data: {messageAsString}\");\n                return response;\n            }\n\n            // try to send the message\n            try\n            {\n                ConnectionChannel.SendMessage(packet);\n            }\n            catch (Exception ex) \n            {\n                Console.WriteLine($\"[!] Exception while sending {messageAsString} : {ex.Message}\");\n                return response;\n            }\n\n            // reset the heartbeat timer; I don't know the actual behavior per the spec\n            TesterPresentTimer.Stop();\n            TesterPresentTimer.Start();\n\n            // this loop catches 7F xx 78 reqeuests from the ecu, where it needs more time to complete an action\n            bool responseIsValid = false;\n            while (!responseIsValid)\n            {\n                response = ReadResponse(messageAsString, testerPresenceRequest);\n                responseIsValid = !IsECURequestingForWait(response);\n            }\n\n            return response;\n        }\n\n        public byte[] ReadResponse(string originalMessageAsStringForDebug, bool testerPresenceRequest) \n        {\n            byte[] response = Array.Empty<byte>();\n            // before reading from ecu, check if there were out-of-order responses that were stored\n            if (OutOfOrderBytesList.Count > 0)\n            {\n                return OutOfOrderBytesList.Dequeue();\n            }\n\n            // read response from ecu\n            Stopwatch sw = new Stopwatch();\n            sw.Start();\n\n            bool waitingForPacket = true;\n            while (waitingForPacket)\n            {\n                if (sw.ElapsedMilliseconds > 18500) // is this P2_TIMEOUT? initially picked 2000 since that is the minimum for tester presence \n                {\n                    Console.WriteLine($\"[!] Internally timed out\"); // Console.WriteLine($\"[!] Internally timed out: {originalMessageAsStringForDebug}\");\n                    sw.Stop();\n                    break;\n                }\n\n                GetMessageResults readResult = ConnectionChannel.GetMessage();\n\n                if (readResult.Result == ResultCode.STATUS_NOERROR)\n                {\n                    foreach (Message row in readResult.Messages)\n                    {\n                        if (row.Data.Length < 4)\n                        {\n                            Console.WriteLine($\"[!] Discarding received message (invalid size):  {BitUtility.BytesToHex(row.Data, true)}\");\n                            continue;\n                        }\n                        byte[] identifier = row.Data.Take(4).ToArray();\n                        if (!identifier.SequenceEqual(RxCanIdentifier))\n                        {\n                            if (identifier.SequenceEqual(CanIdentifier))\n                            {\n                                // quietly ignore if it is our can id, usually empty packet\n                                continue;\n                            }\n                            Console.WriteLine($\"[!] Discarding received message (unknown sender):  {BitUtility.BytesToHex(row.Data, true)} expects {BitUtility.BytesToHex(RxCanIdentifier, true)}\");\n                            continue;\n                        }\n\n                        // skip can identifier\n                        byte[] rxMessageBody = row.Data.Skip(4).ToArray();\n\n                        if (rxMessageBody.Length == 0)\n                        {\n                            continue;\n                        }\n\n                        response = rxMessageBody;\n\n                        LogRead(response);\n                        // if it's a tester presence response, skip it and retry for another packet\n                        if (ConnectionProtocol.IsResponseToTesterPresent(response))\n                        {\n                            // if it is a TP request, we can exit now\n                            if (testerPresenceRequest)\n                            {\n                                return Array.Empty<byte>();\n                            }\n                            else\n                            {\n                                // accidentally received an out-of-order TP response, silently discard it\n                                continue;\n                            }\n                        }\n                        else\n                        {\n                            // TP receiving someone else's valid command, push it back into the queue and exit\n                            if (testerPresenceRequest)\n                            {\n                                OutOfOrderBytesList.Enqueue(response);\n                                return Array.Empty<byte>();\n                            }\n                            else\n                            {\n                                // received a packet normally, check in parent caller if the ECU was asking us to wait\n                                waitingForPacket = false;\n                                break;\n                            }\n                        }\n                        //Console.WriteLine($\"ECU:  {BitUtility.BytesToHex(messageBody, true)}\");\n                    }\n                }\n                else if (readResult.Result == ResultCode.BUFFER_EMPTY)\n                {\n                    // nothing in the mailbox, try again\n                    // Console.WriteLine($\"[!] Retrying: empty buffer: {readResult.Result}\"); // Console.WriteLine($\"[!] Retrying: empty buffer: {readResult.Result} for request {originalMessageAsStringForDebug}\");\n                }\n                else\n                {\n                    Console.WriteLine($\"[!] Error in receive result: {readResult.Result}\");\n                    break;\n                }\n            }\n            return response;\n        }\n\n        public bool IsECURequestingForWait(byte[] response)\n        {\n            if ((response.Length == 3) && (response[0] == 0x7F) && (response[2] == 0x78))\n            {\n                if ((ConnectionProtocol.GetProtocolName() == \"UDS\") || (ConnectionProtocol.GetProtocolName() == \"KW2C3PE\"))\n                {\n                    // ecu requesting for more time\n                    return true;\n                }\n                else \n                {\n                    Console.WriteLine(\"Received NR that looks like a wait request, but the current protocol does not seem to support it.\");\n                }\n            }\n            return false;\n        }\n\n        public void LogRead(IEnumerable<byte> inBuffer)\n        {\n            lock (WriteLock) \n            {\n                CommunicationsLogHighLevel.Append($\"R {BitUtility.BytesToHex(inBuffer.ToArray(), true)}\\r\\n\");\n            }\n        }\n        public void LogWrite(IEnumerable<byte> inBuffer)\n        {\n            lock (WriteLock)\n            {\n                CommunicationsLogHighLevel.Append($\"W {BitUtility.BytesToHex(inBuffer.ToArray(), true)}\\r\\n\");\n            }\n        }\n\n        public void TryCleanup()\n        {\n            try\n            {\n                if (FriendlyProfileName != \"SIMULATION_PROFILE\")\n                {\n                    Console.WriteLine(\"Cleaning up existing connection\");\n                }\n                if (ConnectionChannel != null) \n                {\n                    if (ConnectionProtocol != null)\n                    {\n                        ConnectionProtocol?.ConnectionClosingHandler(this);\n                    }\n                    ConnectionChannel.Dispose();\n                    ConnectionChannel = null;\n                }\n                if (ConnectionDevice != null) \n                {\n                    ConnectionDevice.Dispose();\n                    ConnectionDevice = null;\n                }\n                if (ConnectionAPI != null) \n                {\n                    ConnectionAPI.Dispose();\n                    ConnectionAPI = null;\n                }\n                TesterPresentTimer.Stop();\n                TesterPresentTimer.Enabled = false;\n            }\n            catch (Exception ex) \n            {\n                Console.WriteLine($\"Cleanup issues: {ex.Message}\");\n            }\n        }\n\n\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/ECUFlashMetadata.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Diogenes\n{\n    public class ECUFlashMetadata\n    {\n        public int Index = 0;\n        public string PartNumber = \"Unspecified\";\n        public string Version = \"Unspecified\";\n        public byte VendorID = 0;\n        public byte StatusID = 0;\n        public string FlashDate; // string bc i don't know what sort of datetime format they're on\n        public byte LastFlashVendor = 0;\n        public string FlashFingerprint = \"Unspecified\";\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/ECUIdentification.cs",
    "content": "﻿using Caesar;\nusing SAE.J2534;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Diogenes\n{\n    // this whole class makes the assumption that MB is consistent with their request identifiers (which thankfully seems generally true)\n    public class ECUIdentification\n    {\n        // FIN = Fahrzeug-Identifizierungs-Nummer\n        // VIN = Vehicle Identification Number\n        public static bool TryReadChassisNumber(ECUConnection connection, out string chassisNumber) \n        {\n            chassisNumber = \"\";\n\n            // we need a existing hardware connection to a J2534 device\n            if (connection is null) \n            {\n                return false;\n            }\n            if (connection.IsSimulation()) \n            {\n                return false;\n            }\n            if (connection.ConnectionDevice is null)\n            {\n                // no valid j2534 device initialized yet, can't do anything\n                return false;\n            }\n\n            bool connectionWasEstablished = connection.ConnectionProtocol != null;\n\n            // if the connection is already open, we can use the protocol's vin query\n            int[] baudratesToTest = new int[] { 500000, 800000 };\n            foreach (int baudrateToTest in baudratesToTest)\n            {\n                // if there is an established connection (i.e. already connected and identified a target, do not reconfigure the connection\n                if (!connectionWasEstablished) \n                {\n                    SetupConnectionForBaud(connection, baudrateToTest);\n                }\n                \n                // try KW2C3PE first, since it is a legacy protocol; UDS seems to be somewhat aware, and deliberately avoids known KW2C3PE identifiers\n                if (TryReadKW2C3PEChassisNumber(connection, out string KW2C3PEChassisNumber))\n                {\n                    chassisNumber = KW2C3PEChassisNumber;\n                    return true;\n                }\n                \n                if (TryReadUDSChassisNumber(connection, out string udsChassisNumber))\n                {\n                    chassisNumber = udsChassisNumber;\n                    return true;\n                }\n                \n                // if there's an established connection that failed both UDS/KW2C3PE, the loop is no longer required\n                if (connection.ConnectionProtocol != null) \n                {\n                    return false;\n                }\n            }\n\n            // if a connection was unavailable, it would have been established earlier on; clean it up\n            if (!connectionWasEstablished) \n            {\n                connection.TryCleanup();\n                connection = null;\n            }\n\n            return false;\n        }\n\n        public static bool TryReadUDSChassisNumber(ECUConnection connection, out string chassisNumber)\n        {\n            chassisNumber = \"\";\n            byte[] response = connection.SendMessage(new byte[] { 0x22, 0xF1, 0xA0 });\n            if (response.Length != 20) // 62 F1 A0 + 17byte vin\n            {\n                return false;\n            }\n            if (response[0] != 0x62)\n            {\n                return false;\n            }\n            chassisNumber = Encoding.ASCII.GetString(response.Skip(3).ToArray());\n            return true;\n        }\n        public static bool TryReadKW2C3PEChassisNumber(ECUConnection connection, out string chassisNumber)\n        {\n            chassisNumber = \"\";\n            byte[] response = connection.SendMessage(new byte[] { 0x1A, 0x90 }); // VIN current\n            if (response.Length != 19) // 5A 90 + 17byte vin\n            {\n                return false;\n            }\n            if (response[0] != 0x5A)\n            {\n                return false;\n            }\n            chassisNumber = Encoding.ASCII.GetString(response.Skip(2).ToArray());\n            return true;\n        }\n\n        // eventually move this to ecuconnection, since it touches J2534Sharp and this should be kept local\n        public static void SetupConnectionForBaud(ECUConnection connection, int baud) \n        {\n            if (connection.ConnectionChannel != null)\n            {\n                connection.ConnectionChannel.ClearMsgFilters(); // this bit here for good luck since there are some misbehaving j2534 devices\n                connection.ConnectionChannel.Dispose();\n                connection.ConnectionChannel = null;\n            }\n            try\n            {\n                // create a new channel; the protocol is almost always ISO15765\n                connection.ConnectionChannel = connection.ConnectionDevice.GetChannel(Protocol.ISO15765, (Baud)baud, ConnectFlag.CAN_ID_BOTH);\n                connection.ConnectionProtocol = new DiagnosticProtocol.UnsupportedProtocol();\n                connection.ConnectionChannel.DefaultTxFlag = TxFlag.ISO15765_FRAME_PAD;\n                connection.InternalTimeout = 100;\n\n                // setup filters\n                connection.SetCANIdentifiers(0x7E0, 0x7E8);\n                connection.J2534SetFilters();\n\n                // setup config with some sane defaults since we are guessing our target\n                List<SConfig> sconfigList = new List<SConfig>();\n                sconfigList.Add(new SConfig(Parameter.STMIN_TX, 0));\n                sconfigList.Add(new SConfig(Parameter.ISO15765_STMIN, 0));\n                sconfigList.Add(new SConfig(Parameter.ISO15765_BS, 8));\n                connection.ConnectionChannel.SetConfig(sconfigList.ToArray());\n                \n                // flush the buffer\n                connection.ConnectionChannel.ClearRxBuffer();\n                connection.ConnectionChannel.ClearTxBuffer();\n            }\n            catch (Exception e)\n            {\n                Console.WriteLine($\"[!] ECUIdentification exception in SetupConnectionForBaud: {e.Message}\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/ECUMetadata.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Diogenes\n{\n    public class ECUMetadata\n    {\n        public bool GatewayMode = false;\n        public string BootVersion = \"Unspecified\";\n        public string SerialNumber = \"Unspecified\";\n        public string ChassisNumberOriginal = \"Unspecified\";\n        public string ChassisNumberCurrent = \"Unspecified\";\n        public string HardwarePartNumber = \"Unspecified\";\n        public string HardwareVersion = \"Unspecified\";\n        public uint VariantID = 0;\n        public byte VendorID = 0;\n        public List<ECUFlashMetadata> FlashMetadata = new List<ECUFlashMetadata>();\n\n        public string GetHtmlTable(ECUConnection connection) \n        {\n            ECUMetadata metadata = connection.ConnectionProtocol.QueryECUMetadata(connection);\n\n            string[][] rows = new string[][]\n            {\n                new string[]{ \"Variant ID\", metadata.VariantID.ToString(\"X4\") },\n                new string[]{ \"Gateway Mode\", metadata.GatewayMode.ToString() },\n                new string[]{ \"Boot Version\", metadata.BootVersion },\n                new string[]{ \"Serial Number\", metadata.SerialNumber },\n                new string[]{ \"Chassis Number (Current)\", metadata.ChassisNumberCurrent },\n                new string[]{ \"Chassis Number (Original)\", metadata.ChassisNumberOriginal },\n                new string[]{ \"Hardware Part Number\", metadata.HardwarePartNumber },\n                new string[]{ \"Hardware Version\", metadata.HardwareVersion },\n                new string[]{ \"Hardware Supplier\", ECUMetadata.GetVendorName(metadata.VendorID) },\n            };\n\n            StringBuilder ecuTableRows = new StringBuilder();\n            foreach (string[] row in rows) \n            {\n                ecuTableRows.AppendLine($\"<tr><td>{row[0]}</td><td>{row[1]}</td></tr>\");\n            }\n\n            StringBuilder swBlockRows = new StringBuilder();\n            foreach (ECUFlashMetadata flash in metadata.FlashMetadata)\n            {\n                string flashStatus = flash.StatusID == 1 ? \"Valid\" : \"Invalid\";\n                swBlockRows.AppendLine($@\"\n<h3>SW Block #{flash.Index}</h3>\n<table>\n    <tr><td>Part Number</td><td>{flash.PartNumber}</td></tr>\n    <tr><td>Version</td><td>{flash.Version}</td></tr>\n    <tr><td>Vendor</td><td>{ECUMetadata.GetVendorName(flash.VendorID)}</td></tr>\n    <tr><td>Status</td><td>{flashStatus}</td></tr>\n    <tr><td>Last Flash Vendor</td><td>{ECUMetadata.GetVendorName(flash.LastFlashVendor)}</td></tr>\n    <tr><td>Last Flash Date</td><td>{flash.FlashDate}</td></tr>\n    <tr><td>Flash Fingerprint</td><td>{flash.FlashFingerprint}</td></tr>\n</table>\n\");\n            }\n\n            return $@\"\n    <hr>\n    <h3>Hardware</h3>\n    <table>\n        {ecuTableRows}\n    </table>\n    {swBlockRows}\n\";\n        }\n        public static string GetVendorName(byte vendorId) \n        {\n            string vendorName = \"Undefined\";\n            if (Enum.IsDefined(typeof(Vendor), vendorId)) \n            {\n                vendorName = ((Vendor)vendorId).ToString().Replace(\"VENDOR_\", \"\").Replace(\"_\", \" \");\n            }\n            return vendorName;\n        }\n\n        public static void ShowMetadataModal(ECUConnection connection) \n        {\n            if (connection.ConnectionProtocol is null)\n            {\n                Console.WriteLine(\"Please initiate contact with a target first.\");\n                return;\n            }\n            ECUMetadata metadata = connection.ConnectionProtocol.QueryECUMetadata(connection);\n\n            string[][] rows = new string[][]\n            {\n                new string[]{ \"Variant ID\", metadata.VariantID.ToString(\"X4\") },\n                new string[]{ \"Gateway Mode\", metadata.GatewayMode.ToString() },\n                new string[]{ \"Boot Version\", metadata.BootVersion },\n                new string[]{ \"Serial Number\", metadata.SerialNumber },\n                new string[]{ \"Chassis Number (Current)\", metadata.ChassisNumberCurrent },\n                new string[]{ \"Chassis Number (Original)\", metadata.ChassisNumberOriginal },\n                new string[]{ \"Hardware Part Number\", metadata.HardwarePartNumber },\n                new string[]{ \"Hardware Version\", metadata.HardwareVersion },\n                new string[]{ \"Hardware Supplier\", ECUMetadata.GetVendorName(metadata.VendorID) },\n            };\n\n            List<string[]> rowsAsList = new List<string[]>(rows);\n            foreach (ECUFlashMetadata flash in metadata.FlashMetadata)\n            {\n                string blockPrefix = $\"SW Block #{flash.Index} : \";\n                string flashStatus = flash.StatusID == 1 ? \"Valid\" : \"Invalid\";\n\n                rowsAsList.Add(new string[] { $\"{blockPrefix}Descriptor\", $\"{flash.PartNumber} [Version {flash.Version} from {ECUMetadata.GetVendorName(flash.VendorID)}]\" });\n                rowsAsList.Add(new string[] { $\"{blockPrefix}Status\", $\"{flashStatus}, Last flashed by {ECUMetadata.GetVendorName(flash.LastFlashVendor)} on {flash.FlashDate} (Fingerprint: {flash.FlashFingerprint})\" });\n            }\n\n            GenericPicker picker = new GenericPicker(rowsAsList.ToArray(), new string[] { \"Attribute\", \"Value\" });\n            picker.Text = \"ECU Metadata\";\n            picker.ShowDialog();\n        }\n\n        public enum Vendor : byte\n        {\n            VENDOR_Unspecified = 0,\n            VENDOR_Becker = 1,\n            VENDOR_Blaupunkt = 2,\n            VENDOR_Bosch = 3,\n            VENDOR_MB = 4,\n            VENDOR_HuF = 5,\n            VENDOR_Kammerer = 6,\n            VENDOR_Kostal = 7,\n            VENDOR_Siemens = 8,\n            VENDOR_Stribel = 9,\n            VENDOR_MicroHeat = 10,\n            VENDOR_JATCO = 11,\n            VENDOR_SWF = 16,\n            VENDOR_VDO = 17,\n            VENDOR_Webasto = 18,\n            VENDOR_Dornier = 19,\n            VENDOR_TEG = 20,\n            VENDOR_Hella = 21,\n            VENDOR_Lucas = 22,\n            VENDOR_GKR = 23,\n            VENDOR_MBB = 24,\n            VENDOR_Motometer = 25,\n            VENDOR_Borg = 32,\n            VENDOR_Temic = 33,\n            VENDOR_Teves = 34,\n            VENDOR_Borg_Warner = 35,\n            VENDOR_MED_SPA = 36,\n            VENDOR_DENSO = 37,\n            VENDOR_ZF = 38,\n            VENDOR_TRW = 39,\n            VENDOR_Dunlop = 40,\n            VENDOR_LUK = 41,\n            VENDOR_Magneti_Marelli = 48,\n            VENDOR_DODUCO = 49,\n            VENDOR_Alpine = 50,\n            VENDOR_AMC_AEG_Mobile = 51,\n            VENDOR_Bose = 52,\n            VENDOR_Dasa = 53,\n            VENDOR_Motorola = 54,\n            VENDOR_Nokia = 55,\n            VENDOR_Panasonic = 56,\n            VENDOR_APAG = 57,\n            VENDOR_Rialtosoft = 58,\n            VENDOR_Applicom = 59,\n            VENDOR_Conti_Temic = 60,\n            VENDOR_Cherry = 61,\n            VENDOR_TI_Automotive = 62,\n            VENDOR_Kongsberg_Company = 63,\n            VENDOR_Delphi = 64,\n            VENDOR_Alfmeier = 65,\n            VENDOR_Sidler = 66,\n            VENDOR_Marquardt = 67,\n            VENDOR_Wehrle = 68,\n            VENDOR_megamos = 69,\n            VENDOR_ADC = 70,\n            VENDOR_BERU = 71,\n            VENDOR_Valeo = 72,\n            VENDOR_Magna = 73,\n            VENDOR_Allison = 74,\n            VENDOR_Isringhausen = 75,\n            VENDOR_Grammer = 76,\n            VENDOR_Funkwerk_Dabendorf = 77,\n            VENDOR_Hella_Behr = 78,\n            VENDOR_Pollak = 79,\n            VENDOR_AKG = 80,\n            VENDOR_Automotive_Lighting = 81,\n            VENDOR_TAG = 82,\n            VENDOR_UNITED_PARTS = 83,\n            VENDOR_catem = 84,\n            VENDOR_Alge = 85,\n            VENDOR_Pierburg = 86,\n            VENDOR_Brusa = 87,\n            VENDOR_Ecostar = 88,\n            VENDOR_Xcellsis = 89,\n            VENDOR_Wabco_Automotive = 90,\n            VENDOR_Voith = 91,\n            VENDOR_Knorr = 92,\n            VENDOR_TVI = 93,\n            VENDOR_Stoneridge = 94,\n            VENDOR_Telma = 95,\n            VENDOR_STW = 96,\n            VENDOR_Koyo = 97,\n            VENDOR_Eberspacher = 98,\n            VENDOR_ADVICS = 99,\n            VENDOR_OMRON = 100,\n            VENDOR_Mitsubishi_Heavy_Industry = 101,\n            VENDOR_Methode = 102,\n            VENDOR_UNISIAJECS = 103,\n            VENDOR_UNISIA_JKC_Steering_Systems = 104,\n            VENDOR_AISIN = 105,\n            VENDOR_Zexel_Valeo = 106,\n            VENDOR_Schrader = 107,\n            VENDOR_Ballard = 108,\n            VENDOR_SFT = 112,\n            VENDOR_Kieckert_AG = 113,\n            VENDOR_Behr = 114,\n            VENDOR_MB_Lenkungen = 115,\n            VENDOR_Sachs_Automotive = 116,\n            VENDOR_Peiker = 117,\n            VENDOR_Petri = 118,\n            VENDOR_Autoliv = 119,\n            VENDOR_Thien_Electronic = 120,\n            VENDOR_Siemens_VDO = 121,\n            VENDOR_Dornier_Consulting_GmbH = 122,\n            VENDOR_Alps = 123,\n            VENDOR_PREH = 124,\n            VENDOR_Hitachi_Unisia = 125,\n            VENDOR_Hitachi = 126,\n            VENDOR_Reserved_127 = 127,\n            VENDOR_Huntsville = 128,\n            VENDOR_Yazaki = 129,\n            VENDOR_Lear = 130,\n            VENDOR_Johnson_Controls = 131,\n            VENDOR_HarmanBecker = 132,\n            VENDOR_Mitsubishi_Electric = 133,\n            VENDOR_Tokico_USA_Inc = 134,\n            VENDOR_Nippon_Seiki_International = 135,\n            VENDOR_Inalfa = 136,\n            VENDOR_Nippon_Seiki_UK = 137,\n            VENDOR_GHSP = 138,\n            VENDOR_Vector = 139,\n            VENDOR_Gentex = 140,\n            VENDOR_Visteon = 141,\n            VENDOR_Tochigi_Fuji = 142,\n            VENDOR_DCA = 143,\n            VENDOR_May_and_Scofield = 144,\n            VENDOR_DaimlerChrysler_Hamburg_Plant = 145,\n            VENDOR_AISIN_AW = 146,\n            VENDOR_TOYODA_MACHINE_WORKS = 147,\n            VENDOR_Solectron_Invotronics = 148,\n            VENDOR_Kicker = 149,\n            VENDOR_American_Axle_Company = 150,\n            VENDOR_GETRAG = 151,\n            VENDOR_Promate = 152,\n            VENDOR_ArvinMeritor = 153,\n            VENDOR_Reserved_MMC = 160,\n            VENDOR_Reserved_MMC_SMART = 161,\n            VENDOR_Reserved_162 = 162,\n            VENDOR_After_Market_Supplier = 254,\n            VENDOR_Unidentified = 255,\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/Forms/AboutForm.Designer.cs",
    "content": "﻿\nnamespace Diogenes\n{\n    partial class AboutForm\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.pbLogo = new System.Windows.Forms.PictureBox();\n            this.lblDescName = new System.Windows.Forms.Label();\n            this.lblVersion = new System.Windows.Forms.Label();\n            this.linkLabel1 = new System.Windows.Forms.LinkLabel();\n            this.btnClose = new System.Windows.Forms.Button();\n            this.lbCredits = new System.Windows.Forms.ListBox();\n            ((System.ComponentModel.ISupportInitialize)(this.pbLogo)).BeginInit();\n            this.SuspendLayout();\n            // \n            // pbLogo\n            // \n            this.pbLogo.Image = global::Diogenes.Properties.Resources.diogenes;\n            this.pbLogo.Location = new System.Drawing.Point(20, 20);\n            this.pbLogo.Name = \"pbLogo\";\n            this.pbLogo.Size = new System.Drawing.Size(80, 80);\n            this.pbLogo.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;\n            this.pbLogo.TabIndex = 0;\n            this.pbLogo.TabStop = false;\n            // \n            // lblDescName\n            // \n            this.lblDescName.AutoSize = true;\n            this.lblDescName.Font = new System.Drawing.Font(\"Segoe UI Semilight\", 36F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.lblDescName.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(84)))), ((int)(((byte)(157)))), ((int)(((byte)(220)))));\n            this.lblDescName.Location = new System.Drawing.Point(106, 24);\n            this.lblDescName.Name = \"lblDescName\";\n            this.lblDescName.Size = new System.Drawing.Size(249, 65);\n            this.lblDescName.TabIndex = 1;\n            this.lblDescName.Text = \"DIOGENES\";\n            // \n            // lblVersion\n            // \n            this.lblVersion.AutoSize = true;\n            this.lblVersion.Font = new System.Drawing.Font(\"Segoe UI Semibold\", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.lblVersion.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(84)))), ((int)(((byte)(157)))), ((int)(((byte)(220)))));\n            this.lblVersion.Location = new System.Drawing.Point(16, 119);\n            this.lblVersion.Name = \"lblVersion\";\n            this.lblVersion.Size = new System.Drawing.Size(167, 21);\n            this.lblVersion.TabIndex = 2;\n            this.lblVersion.Text = \"v0.0.0 (Caesar: v0.0.0)\";\n            // \n            // linkLabel1\n            // \n            this.linkLabel1.AutoSize = true;\n            this.linkLabel1.Font = new System.Drawing.Font(\"Segoe UI Semibold\", 12F, System.Drawing.FontStyle.Bold);\n            this.linkLabel1.LinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(84)))), ((int)(((byte)(157)))), ((int)(((byte)(220)))));\n            this.linkLabel1.Location = new System.Drawing.Point(16, 140);\n            this.linkLabel1.Name = \"linkLabel1\";\n            this.linkLabel1.Size = new System.Drawing.Size(285, 21);\n            this.linkLabel1.TabIndex = 3;\n            this.linkLabel1.TabStop = true;\n            this.linkLabel1.Text = \"https://github.com/jglim/CaesarSuite\";\n            this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked);\n            // \n            // btnClose\n            // \n            this.btnClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.btnClose.Font = new System.Drawing.Font(\"Segoe UI\", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.btnClose.Location = new System.Drawing.Point(493, 361);\n            this.btnClose.Name = \"btnClose\";\n            this.btnClose.Size = new System.Drawing.Size(75, 23);\n            this.btnClose.TabIndex = 4;\n            this.btnClose.Text = \"Close\";\n            this.btnClose.UseVisualStyleBackColor = true;\n            this.btnClose.Click += new System.EventHandler(this.btnClose_Click);\n            // \n            // lbCredits\n            // \n            this.lbCredits.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.lbCredits.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40)))));\n            this.lbCredits.BorderStyle = System.Windows.Forms.BorderStyle.None;\n            this.lbCredits.Font = new System.Drawing.Font(\"Segoe UI\", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.lbCredits.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(84)))), ((int)(((byte)(157)))), ((int)(((byte)(220)))));\n            this.lbCredits.FormattingEnabled = true;\n            this.lbCredits.ItemHeight = 17;\n            this.lbCredits.Items.AddRange(new object[] {\n            \"Made possible with the help and support of these projects and individuals:\",\n            \"\",\n            \"Mark James : http://www.famfamfam.com/about/\",\n            \"Brian Humlicek : https://github.com/BrianHumlicek/J2534-Sharp/\",\n            \"s30shiro (しーちゃん) : http://blog.livedoor.jp/s30shiro/\",\n            \"@VladLupashevskyi (Vladyslav Lupashevskyi)\",\n            \"@N0cynym (@N0cynym)\",\n            \"@Feezex (Сергей)\",\n            \"@rnd-ash (Ashcon Mohseninia)\",\n            \"@prj (@prj)\"});\n            this.lbCredits.Location = new System.Drawing.Point(20, 180);\n            this.lbCredits.Name = \"lbCredits\";\n            this.lbCredits.Size = new System.Drawing.Size(548, 170);\n            this.lbCredits.TabIndex = 5;\n            // \n            // AboutForm\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40)))));\n            this.ClientSize = new System.Drawing.Size(580, 396);\n            this.Controls.Add(this.lbCredits);\n            this.Controls.Add(this.btnClose);\n            this.Controls.Add(this.linkLabel1);\n            this.Controls.Add(this.lblVersion);\n            this.Controls.Add(this.lblDescName);\n            this.Controls.Add(this.pbLogo);\n            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;\n            this.Name = \"AboutForm\";\n            this.ShowIcon = false;\n            this.ShowInTaskbar = false;\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\n            this.Text = \"About\";\n            ((System.ComponentModel.ISupportInitialize)(this.pbLogo)).EndInit();\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.PictureBox pbLogo;\n        private System.Windows.Forms.Label lblDescName;\n        private System.Windows.Forms.Label lblVersion;\n        private System.Windows.Forms.LinkLabel linkLabel1;\n        private System.Windows.Forms.Button btnClose;\n        private System.Windows.Forms.ListBox lbCredits;\n    }\n}"
  },
  {
    "path": "Caesar/Diogenes/Forms/AboutForm.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\n\nnamespace Diogenes\n{\n    public partial class AboutForm : Form\n    {\n        public AboutForm(string displayedVersion)\n        {\n            InitializeComponent();\n            lblVersion.Text = displayedVersion;\n        }\n\n        private void btnClose_Click(object sender, EventArgs e)\n        {\n            this.Close();\n        }\n\n        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)\n        {\n            System.Diagnostics.Process.Start(((LinkLabel)sender).Text);\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/Forms/AboutForm.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "Caesar/Diogenes/Forms/BlockDownload.Designer.cs",
    "content": "﻿\nnamespace Diogenes\n{\n    partial class BlockDownload\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(BlockDownload));\n            this.groupBox1 = new System.Windows.Forms.GroupBox();\n            this.dgvMain = new System.Windows.Forms.DataGridView();\n            this.gbInputOutput = new System.Windows.Forms.GroupBox();\n            this.txtIOPrefixHex = new System.Windows.Forms.TextBox();\n            this.lblDescCmdRead = new System.Windows.Forms.Label();\n            this.nudPayloadWidth = new System.Windows.Forms.NumericUpDown();\n            this.lblDescIOWidth = new System.Windows.Forms.Label();\n            this.nudAddressWidth = new System.Windows.Forms.NumericUpDown();\n            this.lblDescPrefix = new System.Windows.Forms.Label();\n            this.gbOperation = new System.Windows.Forms.GroupBox();\n            this.btnExportAsMono = new System.Windows.Forms.Button();\n            this.btnDownload = new System.Windows.Forms.Button();\n            this.btnRemoveBlocks = new System.Windows.Forms.Button();\n            this.btnAddBlock = new System.Windows.Forms.Button();\n            this.gbMemo = new System.Windows.Forms.GroupBox();\n            this.lblWarning = new System.Windows.Forms.Label();\n            this.groupBox1.SuspendLayout();\n            ((System.ComponentModel.ISupportInitialize)(this.dgvMain)).BeginInit();\n            this.gbInputOutput.SuspendLayout();\n            ((System.ComponentModel.ISupportInitialize)(this.nudPayloadWidth)).BeginInit();\n            ((System.ComponentModel.ISupportInitialize)(this.nudAddressWidth)).BeginInit();\n            this.gbOperation.SuspendLayout();\n            this.gbMemo.SuspendLayout();\n            this.SuspendLayout();\n            // \n            // groupBox1\n            // \n            this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.groupBox1.Controls.Add(this.dgvMain);\n            this.groupBox1.Location = new System.Drawing.Point(282, 12);\n            this.groupBox1.Name = \"groupBox1\";\n            this.groupBox1.Size = new System.Drawing.Size(506, 455);\n            this.groupBox1.TabIndex = 2;\n            this.groupBox1.TabStop = false;\n            this.groupBox1.Text = \"Flash Payload\";\n            // \n            // dgvMain\n            // \n            this.dgvMain.AllowDrop = true;\n            this.dgvMain.AllowUserToAddRows = false;\n            this.dgvMain.AllowUserToDeleteRows = false;\n            this.dgvMain.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;\n            this.dgvMain.Dock = System.Windows.Forms.DockStyle.Fill;\n            this.dgvMain.Location = new System.Drawing.Point(3, 16);\n            this.dgvMain.MultiSelect = false;\n            this.dgvMain.Name = \"dgvMain\";\n            this.dgvMain.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;\n            this.dgvMain.ShowEditingIcon = false;\n            this.dgvMain.Size = new System.Drawing.Size(500, 436);\n            this.dgvMain.TabIndex = 1;\n            this.dgvMain.DragDrop += new System.Windows.Forms.DragEventHandler(this.dgvMain_DragDrop);\n            this.dgvMain.DragEnter += new System.Windows.Forms.DragEventHandler(this.dgvMain_DragEnter);\n            // \n            // gbInputOutput\n            // \n            this.gbInputOutput.Controls.Add(this.txtIOPrefixHex);\n            this.gbInputOutput.Controls.Add(this.lblDescCmdRead);\n            this.gbInputOutput.Controls.Add(this.nudPayloadWidth);\n            this.gbInputOutput.Controls.Add(this.lblDescIOWidth);\n            this.gbInputOutput.Controls.Add(this.nudAddressWidth);\n            this.gbInputOutput.Controls.Add(this.lblDescPrefix);\n            this.gbInputOutput.Location = new System.Drawing.Point(12, 12);\n            this.gbInputOutput.Name = \"gbInputOutput\";\n            this.gbInputOutput.Size = new System.Drawing.Size(264, 214);\n            this.gbInputOutput.TabIndex = 8;\n            this.gbInputOutput.TabStop = false;\n            this.gbInputOutput.Text = \"I/O\";\n            // \n            // txtIOPrefixHex\n            // \n            this.txtIOPrefixHex.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.txtIOPrefixHex.Font = new System.Drawing.Font(\"Consolas\", 16F);\n            this.txtIOPrefixHex.Location = new System.Drawing.Point(6, 37);\n            this.txtIOPrefixHex.Name = \"txtIOPrefixHex\";\n            this.txtIOPrefixHex.Size = new System.Drawing.Size(250, 32);\n            this.txtIOPrefixHex.TabIndex = 10;\n            this.txtIOPrefixHex.Text = \"34 00\";\n            // \n            // lblDescCmdRead\n            // \n            this.lblDescCmdRead.AutoSize = true;\n            this.lblDescCmdRead.Location = new System.Drawing.Point(5, 149);\n            this.lblDescCmdRead.Name = \"lblDescCmdRead\";\n            this.lblDescCmdRead.Size = new System.Drawing.Size(76, 13);\n            this.lblDescCmdRead.TabIndex = 7;\n            this.lblDescCmdRead.Text = \"Payload Width\";\n            // \n            // nudPayloadWidth\n            // \n            this.nudPayloadWidth.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.nudPayloadWidth.Font = new System.Drawing.Font(\"Consolas\", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.nudPayloadWidth.Hexadecimal = true;\n            this.nudPayloadWidth.Location = new System.Drawing.Point(6, 168);\n            this.nudPayloadWidth.Maximum = new decimal(new int[] {\n            4,\n            0,\n            0,\n            0});\n            this.nudPayloadWidth.Minimum = new decimal(new int[] {\n            1,\n            0,\n            0,\n            0});\n            this.nudPayloadWidth.Name = \"nudPayloadWidth\";\n            this.nudPayloadWidth.Size = new System.Drawing.Size(250, 32);\n            this.nudPayloadWidth.TabIndex = 6;\n            this.nudPayloadWidth.Value = new decimal(new int[] {\n            4,\n            0,\n            0,\n            0});\n            // \n            // lblDescIOWidth\n            // \n            this.lblDescIOWidth.AutoSize = true;\n            this.lblDescIOWidth.Location = new System.Drawing.Point(5, 85);\n            this.lblDescIOWidth.Name = \"lblDescIOWidth\";\n            this.lblDescIOWidth.Size = new System.Drawing.Size(76, 13);\n            this.lblDescIOWidth.TabIndex = 5;\n            this.lblDescIOWidth.Text = \"Address Width\";\n            // \n            // nudAddressWidth\n            // \n            this.nudAddressWidth.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.nudAddressWidth.Font = new System.Drawing.Font(\"Consolas\", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.nudAddressWidth.Hexadecimal = true;\n            this.nudAddressWidth.Location = new System.Drawing.Point(6, 104);\n            this.nudAddressWidth.Maximum = new decimal(new int[] {\n            4,\n            0,\n            0,\n            0});\n            this.nudAddressWidth.Minimum = new decimal(new int[] {\n            1,\n            0,\n            0,\n            0});\n            this.nudAddressWidth.Name = \"nudAddressWidth\";\n            this.nudAddressWidth.Size = new System.Drawing.Size(250, 32);\n            this.nudAddressWidth.TabIndex = 4;\n            this.nudAddressWidth.Value = new decimal(new int[] {\n            4,\n            0,\n            0,\n            0});\n            // \n            // lblDescPrefix\n            // \n            this.lblDescPrefix.AutoSize = true;\n            this.lblDescPrefix.Location = new System.Drawing.Point(6, 21);\n            this.lblDescPrefix.Name = \"lblDescPrefix\";\n            this.lblDescPrefix.Size = new System.Drawing.Size(61, 13);\n            this.lblDescPrefix.TabIndex = 3;\n            this.lblDescPrefix.Text = \"Prefix (Hex)\";\n            // \n            // gbOperation\n            // \n            this.gbOperation.Controls.Add(this.btnExportAsMono);\n            this.gbOperation.Controls.Add(this.btnDownload);\n            this.gbOperation.Controls.Add(this.btnRemoveBlocks);\n            this.gbOperation.Controls.Add(this.btnAddBlock);\n            this.gbOperation.Location = new System.Drawing.Point(12, 232);\n            this.gbOperation.Name = \"gbOperation\";\n            this.gbOperation.Size = new System.Drawing.Size(264, 139);\n            this.gbOperation.TabIndex = 9;\n            this.gbOperation.TabStop = false;\n            this.gbOperation.Text = \"Operation\";\n            // \n            // btnExportAsMono\n            // \n            this.btnExportAsMono.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.btnExportAsMono.Location = new System.Drawing.Point(9, 106);\n            this.btnExportAsMono.Name = \"btnExportAsMono\";\n            this.btnExportAsMono.Size = new System.Drawing.Size(250, 23);\n            this.btnExportAsMono.TabIndex = 3;\n            this.btnExportAsMono.Text = \"Save as monolithic binary\";\n            this.btnExportAsMono.UseVisualStyleBackColor = true;\n            this.btnExportAsMono.Visible = false;\n            this.btnExportAsMono.Click += new System.EventHandler(this.btnExportAsMono_Click);\n            // \n            // btnDownload\n            // \n            this.btnDownload.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.btnDownload.Location = new System.Drawing.Point(8, 77);\n            this.btnDownload.Name = \"btnDownload\";\n            this.btnDownload.Size = new System.Drawing.Size(250, 23);\n            this.btnDownload.TabIndex = 2;\n            this.btnDownload.Text = \"Download\";\n            this.btnDownload.UseVisualStyleBackColor = true;\n            this.btnDownload.Click += new System.EventHandler(this.btnDownload_Click);\n            // \n            // btnRemoveBlocks\n            // \n            this.btnRemoveBlocks.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.btnRemoveBlocks.Location = new System.Drawing.Point(8, 48);\n            this.btnRemoveBlocks.Name = \"btnRemoveBlocks\";\n            this.btnRemoveBlocks.Size = new System.Drawing.Size(250, 23);\n            this.btnRemoveBlocks.TabIndex = 1;\n            this.btnRemoveBlocks.Text = \"Clear All Blocks\";\n            this.btnRemoveBlocks.UseVisualStyleBackColor = true;\n            this.btnRemoveBlocks.Click += new System.EventHandler(this.btnRemoveBlocks_Click);\n            // \n            // btnAddBlock\n            // \n            this.btnAddBlock.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.btnAddBlock.Location = new System.Drawing.Point(8, 19);\n            this.btnAddBlock.Name = \"btnAddBlock\";\n            this.btnAddBlock.Size = new System.Drawing.Size(250, 23);\n            this.btnAddBlock.TabIndex = 0;\n            this.btnAddBlock.Text = \"Add Block\";\n            this.btnAddBlock.UseVisualStyleBackColor = true;\n            this.btnAddBlock.Click += new System.EventHandler(this.btnAddBlock_Click);\n            // \n            // gbMemo\n            // \n            this.gbMemo.Controls.Add(this.lblWarning);\n            this.gbMemo.Location = new System.Drawing.Point(12, 377);\n            this.gbMemo.Name = \"gbMemo\";\n            this.gbMemo.Size = new System.Drawing.Size(264, 88);\n            this.gbMemo.TabIndex = 10;\n            this.gbMemo.TabStop = false;\n            this.gbMemo.Text = \"Warning\";\n            // \n            // lblWarning\n            // \n            this.lblWarning.AutoSize = true;\n            this.lblWarning.Location = new System.Drawing.Point(6, 16);\n            this.lblWarning.Name = \"lblWarning\";\n            this.lblWarning.Size = new System.Drawing.Size(252, 65);\n            this.lblWarning.TabIndex = 0;\n            this.lblWarning.Text = \"This feature is intended for developers only.\\r\\nThe target must be in a state that\" +\n    \" is ready to receive\\r\\nflash blocks to use this feature.\\r\\n\\r\\nPlease check the docs\" +\n    \" for more information\";\n            // \n            // BlockDownload\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(800, 479);\n            this.Controls.Add(this.gbMemo);\n            this.Controls.Add(this.gbOperation);\n            this.Controls.Add(this.gbInputOutput);\n            this.Controls.Add(this.groupBox1);\n            this.Icon = ((System.Drawing.Icon)(resources.GetObject(\"$this.Icon\")));\n            this.Name = \"BlockDownload\";\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\n            this.Text = \"Block Download\";\n            this.Load += new System.EventHandler(this.BlockDownload_Load);\n            this.groupBox1.ResumeLayout(false);\n            ((System.ComponentModel.ISupportInitialize)(this.dgvMain)).EndInit();\n            this.gbInputOutput.ResumeLayout(false);\n            this.gbInputOutput.PerformLayout();\n            ((System.ComponentModel.ISupportInitialize)(this.nudPayloadWidth)).EndInit();\n            ((System.ComponentModel.ISupportInitialize)(this.nudAddressWidth)).EndInit();\n            this.gbOperation.ResumeLayout(false);\n            this.gbMemo.ResumeLayout(false);\n            this.gbMemo.PerformLayout();\n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.GroupBox groupBox1;\n        private System.Windows.Forms.DataGridView dgvMain;\n        private System.Windows.Forms.GroupBox gbInputOutput;\n        private System.Windows.Forms.Label lblDescCmdRead;\n        private System.Windows.Forms.NumericUpDown nudPayloadWidth;\n        private System.Windows.Forms.Label lblDescIOWidth;\n        private System.Windows.Forms.NumericUpDown nudAddressWidth;\n        private System.Windows.Forms.Label lblDescPrefix;\n        private System.Windows.Forms.TextBox txtIOPrefixHex;\n        private System.Windows.Forms.GroupBox gbOperation;\n        private System.Windows.Forms.Button btnDownload;\n        private System.Windows.Forms.Button btnRemoveBlocks;\n        private System.Windows.Forms.Button btnAddBlock;\n        private System.Windows.Forms.GroupBox gbMemo;\n        private System.Windows.Forms.Label lblWarning;\n        private System.Windows.Forms.Button btnExportAsMono;\n    }\n}"
  },
  {
    "path": "Caesar/Diogenes/Forms/BlockDownload.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\nusing Caesar;\nusing SAE.J2534;\n\nnamespace Diogenes\n{\n    public partial class BlockDownload : Form\n    {\n        List<FlashBlock> FlashBlocks = new List<FlashBlock>();\n        ECUConnection connection;\n        public BlockDownload(ECUConnection connection)\n        {\n            this.connection = connection;\n            InitializeComponent();\n        }\n\n        private void BlockDownload_Load(object sender, EventArgs e)\n        {\n\n        }\n\n        private void dgvMain_DragEnter(object sender, DragEventArgs e)\n        {\n            if (e.Data.GetDataPresent(DataFormats.FileDrop))\n            {\n                e.Effect = DragDropEffects.Copy;\n            }\n        }\n\n        private void dgvMain_DragDrop(object sender, DragEventArgs e)\n        {\n            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);\n            foreach (string file in files)\n            {\n                TryLoadBlock(file);\n            }\n            FlashBlocks = FlashBlocks.OrderBy(x => x.Address).ToList();\n            PresentRows();\n        }\n\n        private void TryLoadBlock(string fileName) \n        {\n            string[] fileNameChunks = Path.GetFileNameWithoutExtension(fileName).Split(new string[] { \"_\" }, StringSplitOptions.RemoveEmptyEntries);\n            if (fileNameChunks.Length > 0)\n            {\n                if (uint.TryParse(fileNameChunks[fileNameChunks.Length - 1], System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture,  out uint result))\n                {\n                    if (FlashBlocks.FindAll(x => x.Path == fileName).Count > 0)\n                    {\n                        MessageBox.Show($\"Skipping repeated block : {fileName}\");\n                    }\n                    else \n                    {\n                        FlashBlocks.Add(new FlashBlock { Address = result, Payload = File.ReadAllBytes(fileName), Path = fileName });\n                    }\n                }\n                else\n                {\n                    MessageBox.Show($\"Could not load {fileName} : unable to parse destination address. Please append a valid hex-value to the filename to specify the address (e.g. file_1FFFFF.bin)\");\n                }\n            }\n            else \n            {\n                MessageBox.Show($\"Could not load {fileName} : unable to parse name. Please append a valid hex-value to the filename to specify the address (e.g. file_1FFFFF.bin)\");\n            }\n        }\n\n\n        private void PresentRows()\n        {\n            if (FlashBlocks is null)\n            {\n                return;\n            }\n\n            DataTable dt = new DataTable();\n\n            foreach (string header in new string[] { \"Block #\", \"Name\", \"Address\" })\n            {\n                dt.Columns.Add(header, typeof(string));\n            }\n            dgvMain.DataSource = dt;\n\n            for (int i = 0; i < FlashBlocks.Count; i++)\n            {\n                dt.Rows.Add(\n                    i.ToString(),\n                    Path.GetFileNameWithoutExtension(FlashBlocks[i].Path),\n                    $\"{FlashBlocks[i].Address:X}\"\n                    );\n            }\n\n            dgvMain.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;\n\n            dgvMain.Columns[0].ReadOnly = true;\n            dgvMain.Columns[1].ReadOnly = true;\n            dgvMain.Columns[2].ReadOnly = true;\n\n            dgvMain.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;\n        }\n\n        private void btnDownload_Click(object sender, EventArgs e)\n        {\n            if (MessageBox.Show(\"Please note that the STMin and BS values are hardcoded. This process will also take some time. Continue?\", \"Download\", MessageBoxButtons.YesNo) == DialogResult.Yes) \n            {\n                StartDownload();\n            }\n        }\n\n        private void StartDownload() \n        {\n            int sumBytesTransferred = 0;\n            int sumBytes = 0;\n            foreach (FlashBlock block in FlashBlocks)\n            {\n                sumBytes += block.Payload.Length;\n            }\n\n            GenericLoader loader = new GenericLoader();\n            loader.Text = \"Reading from ECU\";\n            loader.TopMost = true;\n            loader.Show();\n            Application.DoEvents();\n\n            foreach (FlashBlock block in FlashBlocks)\n            {\n                byte[] startDownloadCmd = CreateDownloadRequest(block.Address, (uint)block.Payload.Length);\n\n                byte[] response = connection.SendMessage(startDownloadCmd); // comment this, uncomment below if dryrun\n                //byte[] response = BitUtility.BytesFromHex(\"74 20 00 03\");\n                if (response.Length < 2)\n                {\n                    MessageBox.Show($\"Error: ECU sent an incorrectly sized response when initiating download for block {Path.GetFileNameWithoutExtension(block.Path)}\");\n                    break;\n                }\n                if (response[0] != startDownloadCmd[0] + 0x40)\n                {\n                    MessageBox.Show($\"Error: ECU sent a non-positive response ({BitUtility.BytesToHex(response)}) for block {Path.GetFileNameWithoutExtension(block.Path)}\");\n                    break;\n                }\n                // read alfid to know memory size description's width\n                byte rxAlfid = response[1];\n                // we are only expecting a size value\n                if ((rxAlfid & 0xF) > 0)\n                {\n                    MessageBox.Show($\"Error: Could not understand ECU ALFID response ({BitUtility.BytesToHex(response)}) for block {Path.GetFileNameWithoutExtension(block.Path)}\");\n                    break;\n                }\n                // find out how wide the memory size description is\n                int memSize = rxAlfid >> 4;\n                List<byte> memBytes = response.Skip(2).Take(memSize).ToList();\n                if (memBytes.Count != memSize)\n                {\n                    MessageBox.Show($\"Error: Could not understand ECU ALFID response (size mismatch) ({BitUtility.BytesToHex(response)}) for block {Path.GetFileNameWithoutExtension(block.Path)}\");\n                    break;\n                }\n                // parse the memory size desc as a BE integer\n                uint messageSize = 0;\n                for (int i = 0; i < memBytes.Count; i++)\n                {\n                    messageSize <<= 8;\n                    messageSize |= memBytes[i];\n                }\n                // debug: uncomment to cap msg size at 0x100, normally 0xF02, blocksize = 0xF00\n                // messageSize = 0x102;\n                int blockSize = (int)messageSize - 2;\n                int totalBlockCount = (int)(block.Payload.Length / blockSize);\n                int remainderBytes = block.Payload.Length % blockSize;\n                if (remainderBytes != 0)\n                {\n                    totalBlockCount++;\n                }\n\n                // reconfigure connection for block transfer\n                connection.TesterPresentTimer.Enabled = false;\n                RaiseSTMin();\n\n                byte[] dataBlock = new byte[messageSize];\n\n                loader.SetProgressMax(totalBlockCount);\n\n                for (int blockCounter = 0; blockCounter < totalBlockCount; blockCounter++)\n                {\n                    dataBlock[0] = 0x36;\n                    dataBlock[1] = (byte)((blockCounter + 1) & 0xFF);\n\n                    // if this is the last block, and there is a remainder block, write only the remainder\n                    if (((blockCounter + 1) == totalBlockCount) && (remainderBytes != 0))\n                    {\n                        Array.ConstrainedCopy(block.Payload, blockCounter * blockSize, dataBlock, 2, remainderBytes);\n                        dataBlock = dataBlock.Take(2 + remainderBytes).ToArray();\n                    }\n                    else\n                    {\n                        Array.ConstrainedCopy(block.Payload, blockCounter * blockSize, dataBlock, 2, blockSize);\n                    }\n\n                    byte[] transferResponse = connection.SendMessage(dataBlock); // comment this, uncomment below if dryrun\n                    //byte[] transferResponse = new byte[] { 0x76, 0x00 };\n                    if ((transferResponse.Length > 0) && (transferResponse[0] == 0x76))\n                    {\n                        // no need to check block index, if the ecu accepts it, continue\n                    }\n                    else\n                    {\n                        MessageBox.Show($\"Error: Data transfer rejected by ECU ({BitUtility.BytesToHex(transferResponse)}) for block {Path.GetFileNameWithoutExtension(block.Path)}\");\n                        break;\n                    }\n\n                    // update progress\n                    sumBytesTransferred += dataBlock.Length - 2;\n                    // loader.Text = $\"Writing to ECU : 0x{sumBytesTransferred:X8} of 0x{sumBytes:X8}\";\n                    loader.Text = $\"Writing to ECU : block {blockCounter} of 0x{totalBlockCount}\";\n                    loader.SetProgressValue(blockCounter);\n                    Application.DoEvents();\n                    // fixme: show two progressbars, one for the block# and another for the individual block's %\n                }\n\n                byte[] exitTransferResponse = connection.SendMessage(new byte[] { 0x37 });// ------------------ patch if debugging\n                if (!((exitTransferResponse.Length > 0) && (exitTransferResponse[0] == 0x77)))\n                {\n                    MessageBox.Show($\"Error: Exit transfer rejected by ECU ({BitUtility.BytesToHex(exitTransferResponse)}) for block {Path.GetFileNameWithoutExtension(block.Path)}\");\n                    break;\n                }\n\n            }\n\n            // restore prior connection status\n            connection.TesterPresentTimer.Enabled = true;\n            ResetSTMin();\n\n            loader.Close();\n            MessageBox.Show(\"Download completed\");\n        }\n\n\n        // WARNING: this bit here is hardcoded; should pull the correct values from the connection\n        private void RaiseSTMin()\n        {\n            List<SConfig> sconfigList = new List<SConfig>();\n            sconfigList.Add(new SConfig(Parameter.STMIN_TX, 65535));\n            // todo: check if only STMIN_TX can be raised without affecting the other values\n            sconfigList.Add(new SConfig(Parameter.ISO15765_STMIN, 20));\n            sconfigList.Add(new SConfig(Parameter.ISO15765_BS, 8));\n            connection.ConnectionChannel.SetConfig(sconfigList.ToArray());\n        }\n        private void ResetSTMin()\n        {\n            List<SConfig> sconfigList = new List<SConfig>();\n            sconfigList.Add(new SConfig(Parameter.STMIN_TX, 20));\n            sconfigList.Add(new SConfig(Parameter.ISO15765_STMIN, 20));\n            sconfigList.Add(new SConfig(Parameter.ISO15765_BS, 8));\n            connection.ConnectionChannel.SetConfig(sconfigList.ToArray());\n        }\n\n        private byte[] CreateDownloadRequest(uint address, uint size)\n        {\n            byte[] prefix = BitUtility.BytesFromHex(txtIOPrefixHex.Text.ToUpper().Replace(\" \", \"\"));\n            int addressWidth = (int)nudAddressWidth.Value;\n            int payloadWidth = (int)nudPayloadWidth.Value;\n\n            byte alfid = GetAddressAndLengthFormatIdentifier(addressWidth, payloadWidth);\n            List<byte> command = new List<byte>(prefix);\n            command.Add(alfid);\n            command.AddRange(ValueToBEByteArrayConstrained(address, addressWidth));\n            command.AddRange(ValueToBEByteArrayConstrained(size, payloadWidth));\n            return command.ToArray();\n        }\n\n        // alfid generation copied fro UDS hex editor, (temporarily) preferring to duplicate to avoid coupling\n        private static byte GetAddressAndLengthFormatIdentifier(int addressSizeInBytes, int memorySizeInBytes)\n        {\n            /*\n            address map in bits:\n            8 bits  : 1\n            16 bits : 2\n            24 bits : 3\n            32 bits : 4\n            40 bits : 5\n\n            memory size map in bits:\n            8 bits  : 1\n            16 bits : 2\n            24 bits : 3\n            32 bits : 4\n             */\n            if ((addressSizeInBytes < 1) || (addressSizeInBytes > 5))\n            {\n                throw new ArgumentOutOfRangeException(\"Invalid address size for ALFID\");\n            }\n            if ((memorySizeInBytes < 1) || (memorySizeInBytes > 5))\n            {\n                throw new ArgumentOutOfRangeException(\"Invalid memory size for ALFID\");\n            }\n            return (byte)((memorySizeInBytes << 4) | addressSizeInBytes);\n        }\n\n        // also from uds hex editor\n        private List<byte> ValueToBEByteArrayConstrained(long inValue, int size)\n        {\n            List<byte> result = new List<byte>();\n            for (int i = 0; i < size; i++)\n            {\n                byte row = (byte)(inValue & 0xFF);\n                result.Insert(0, row);\n                inValue >>= 8;\n            }\n            return result;\n        }\n\n        private void btnAddBlock_Click(object sender, EventArgs e)\n        {\n            OpenFileDialog ofd = new OpenFileDialog();\n            ofd.Title = \"Select a BIN File\";\n            ofd.Filter = \"BIN files (*.bin)|*.bin|All files (*.*)|*.*\";\n            ofd.Multiselect = false;\n            if (ofd.ShowDialog() == DialogResult.OK)\n            {\n                TryLoadBlock(ofd.FileName);\n            }\n            FlashBlocks = FlashBlocks.OrderBy(x => x.Address).ToList();\n            PresentRows();\n        }\n\n        private void btnRemoveBlocks_Click(object sender, EventArgs e)\n        {\n            FlashBlocks.Clear();\n            PresentRows();\n        }\n\n        // debug stub, not intended for direct execution\n        private void SetSessionStub(ECUConnection Connection) \n        {\n            return;\n            Console.WriteLine(\"Entering bootmode\");\n            Connection.SendMessage(BitUtility.BytesFromHex(\"1002\"));\n\n            Console.WriteLine(\"Requesting for seed\");\n            byte[] seed = Connection.SendMessage(BitUtility.BytesFromHex(\"2705\"));\n            SecurityAccess.SecurityAutoLogin.QueryUnlockEcu(seed.Skip(2).ToArray(), \"X_4\", 5, out byte[] key);\n\n            Console.Write(\"Authenticating for bootmode.. \");\n            List<byte> keyResponse = new List<byte>(new byte[] { 0x27, 0x06 });\n            keyResponse.AddRange(key);\n            byte[] authResponse = Connection.SendMessage(keyResponse);\n            Console.WriteLine(BitUtility.BytesToHex(authResponse));\n\n            // remind myself to write fingerprint\n            Console.WriteLine($\"2EF15A 00 0004 150213 00000000\\r\\n2EF15A 01 0004 150213 00000000\\r\\n3101FF00\");\n            /*\n            int blockId = 1; // block0: CODE,  block1: DATA\n            Console.WriteLine($\"Writing fingerprint\");\n            //  2e f1 5a 00 00 04 15 02 16 00 00 00 00\n            Connection.SendMessage(BitUtility.BytesFromHex($\"2EF15A {blockId:X2} 0004 150213 00000000\"));\n\n            // 2EF15A 00 0004 150213 00000000\n            // 2EF15A 01 0004 150213 00000000\n\n            Console.WriteLine($\"Erasing block {blockId}\");\n            Connection.SendMessage(BitUtility.BytesFromHex(\"3101FF00\"));\n            Console.WriteLine(\"Ready to accept flash data\");\n            */\n        }\n\n        private void btnExportAsMono_Click(object sender, EventArgs e)\n        {\n            // fixme: buffer allocation\n            // on a good day, the base is 0, however if it's significantly offset, this won't work out of the box\n            // button is currently set as invisible until this is properly fixed\n            byte[] finalBuffer = new byte[0x200000];\n            foreach (FlashBlock b in FlashBlocks) \n            {\n                Array.ConstrainedCopy(b.Payload, 0, finalBuffer, (int)b.Address, b.Payload.Length);\n            }\n            SaveFileDialog sfd = new SaveFileDialog();\n            sfd.Title = \"Specify a location to save your BIN file\";\n            sfd.Filter = \"BIN files (*.bin)|*.bin|All files (*.*)|*.*\";\n            if (sfd.ShowDialog() == DialogResult.OK)\n            {\n                File.WriteAllBytes(sfd.FileName, finalBuffer);\n            }\n        }\n    }\n\n    public class FlashBlock \n    {\n        public string Path;\n        public byte[] Payload;\n        public uint Address;\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/Forms/BlockDownload.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <assembly alias=\"System.Drawing\" name=\"System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\" />\n  <data name=\"$this.Icon\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n    <value>\n        AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAnqNw3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAKaze1Sep3OklptsMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAACuv3wwtrt//K6ve/yWm24oAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK6/fz0+85/9Muub/Jqfc7SSk2xcAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArr9//hNPy/1W95/8uqt7/JKTbkAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALbLgwHDM7v+D0vL/fs7x/0q2\n        5P8kpdvxIqLaFwAAAAAAAAAAAAAAAAAAAAA4wufwNsDm+DW95fgzu+T4Mbjj+C+24viG1/P/L7br/0q8\n        7P+AzvH/Ubnm/yyo3f8jotqdAAAAAAAAAAAAAAAAOsTo6XXa8v+T5vj/keP3/43g9v+K3PX/itv1/4jX\n        9P+E0/L/f8/x/3zM8P96ye//SLTj/yOj2vUgntgjAAAAADvH6TdPzez/mOn5/0rV8/9Fz/H/QMrw/zjC\n        7v+J2fT/LrTh/iyx4Pgrrt/4Kaze+Cep3Pglptv4I6Pa6QAAAAAAAAAAO8fp9IDh9f+O5vj/Q9Lz/z/N\n        8f85x+//jNz1/1jG6v8utOF0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD3J6lRb1O//mer5/0fW\n        9P9C0PL/Pcvw/27V8/9/1/P/SsDn/y+04UoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPcrq+ZPp\n        +f9y4ff/RdTz/0HO8v88yfD/itz1/3DQ7/89u+T/L7XhIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/M\n        64Nk2fH/muv6/0jY9P9E0/P/P87x/zrI8P+M3PX/Ysvt/zG44/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAP8zr/Zrt+v+Z6/n/l+j5/5Tl+P+R4vf/jt/2/4vb9f9Wx+v/Mbjj8wAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAEDO7KI/zOv/Psvq/zzJ6f87x+n/OsTo/zjC5/82wOb/Nb3l/zO75P8xuOPhAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAA7/8AAOP/AADh/wAA8H8AAPg/AAD4DwAAAAcAAAABAAAAAQAAgD8AAIAfAADADwAAwA8AAOAH\n        AADgAwAA//8AAA==\n</value>\n  </data>\n</root>"
  },
  {
    "path": "Caesar/Diogenes/Forms/DTCForm.Designer.cs",
    "content": "﻿\nnamespace Diogenes\n{\n    partial class DTCForm\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DTCForm));\n            this.splitContainer1 = new System.Windows.Forms.SplitContainer();\n            this.dgvMain = new System.Windows.Forms.DataGridView();\n            this.dgvContext = new System.Windows.Forms.DataGridView();\n            this.menuStrip1 = new System.Windows.Forms.MenuStrip();\n            this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.exportDTCsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.dTCToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.clearSelectedDTCToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.clearAllDTCsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.refreshDataToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.viewAllAvailableDTCsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();\n            this.splitContainer1.Panel1.SuspendLayout();\n            this.splitContainer1.Panel2.SuspendLayout();\n            this.splitContainer1.SuspendLayout();\n            ((System.ComponentModel.ISupportInitialize)(this.dgvMain)).BeginInit();\n            ((System.ComponentModel.ISupportInitialize)(this.dgvContext)).BeginInit();\n            this.menuStrip1.SuspendLayout();\n            this.SuspendLayout();\n            // \n            // splitContainer1\n            // \n            this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;\n            this.splitContainer1.Location = new System.Drawing.Point(0, 24);\n            this.splitContainer1.Name = \"splitContainer1\";\n            this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;\n            // \n            // splitContainer1.Panel1\n            // \n            this.splitContainer1.Panel1.Controls.Add(this.dgvMain);\n            // \n            // splitContainer1.Panel2\n            // \n            this.splitContainer1.Panel2.Controls.Add(this.dgvContext);\n            this.splitContainer1.Size = new System.Drawing.Size(1490, 735);\n            this.splitContainer1.SplitterDistance = 224;\n            this.splitContainer1.TabIndex = 0;\n            // \n            // dgvMain\n            // \n            this.dgvMain.AllowUserToAddRows = false;\n            this.dgvMain.AllowUserToDeleteRows = false;\n            this.dgvMain.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;\n            this.dgvMain.Dock = System.Windows.Forms.DockStyle.Fill;\n            this.dgvMain.Location = new System.Drawing.Point(0, 0);\n            this.dgvMain.MultiSelect = false;\n            this.dgvMain.Name = \"dgvMain\";\n            this.dgvMain.ReadOnly = true;\n            this.dgvMain.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;\n            this.dgvMain.ShowEditingIcon = false;\n            this.dgvMain.Size = new System.Drawing.Size(1490, 224);\n            this.dgvMain.TabIndex = 1;\n            this.dgvMain.SelectionChanged += new System.EventHandler(this.dgvMain_SelectionChanged);\n            // \n            // dgvContext\n            // \n            this.dgvContext.AllowUserToAddRows = false;\n            this.dgvContext.AllowUserToDeleteRows = false;\n            this.dgvContext.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;\n            this.dgvContext.Dock = System.Windows.Forms.DockStyle.Fill;\n            this.dgvContext.Location = new System.Drawing.Point(0, 0);\n            this.dgvContext.Name = \"dgvContext\";\n            this.dgvContext.ReadOnly = true;\n            this.dgvContext.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;\n            this.dgvContext.ShowEditingIcon = false;\n            this.dgvContext.Size = new System.Drawing.Size(1490, 507);\n            this.dgvContext.TabIndex = 2;\n            // \n            // menuStrip1\n            // \n            this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.fileToolStripMenuItem,\n            this.dTCToolStripMenuItem});\n            this.menuStrip1.Location = new System.Drawing.Point(0, 0);\n            this.menuStrip1.Name = \"menuStrip1\";\n            this.menuStrip1.RenderMode = System.Windows.Forms.ToolStripRenderMode.System;\n            this.menuStrip1.Size = new System.Drawing.Size(1490, 24);\n            this.menuStrip1.TabIndex = 1;\n            this.menuStrip1.Text = \"menuStrip1\";\n            // \n            // fileToolStripMenuItem\n            // \n            this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.exportDTCsToolStripMenuItem,\n            this.viewAllAvailableDTCsToolStripMenuItem});\n            this.fileToolStripMenuItem.Name = \"fileToolStripMenuItem\";\n            this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);\n            this.fileToolStripMenuItem.Text = \"File\";\n            // \n            // exportDTCsToolStripMenuItem\n            // \n            this.exportDTCsToolStripMenuItem.Name = \"exportDTCsToolStripMenuItem\";\n            this.exportDTCsToolStripMenuItem.Size = new System.Drawing.Size(192, 22);\n            this.exportDTCsToolStripMenuItem.Text = \"Export DTCs\";\n            this.exportDTCsToolStripMenuItem.Click += new System.EventHandler(this.exportDTCsToolStripMenuItem_Click);\n            // \n            // dTCToolStripMenuItem\n            // \n            this.dTCToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.clearSelectedDTCToolStripMenuItem,\n            this.clearAllDTCsToolStripMenuItem,\n            this.refreshDataToolStripMenuItem});\n            this.dTCToolStripMenuItem.Name = \"dTCToolStripMenuItem\";\n            this.dTCToolStripMenuItem.Size = new System.Drawing.Size(40, 20);\n            this.dTCToolStripMenuItem.Text = \"DTC\";\n            // \n            // clearSelectedDTCToolStripMenuItem\n            // \n            this.clearSelectedDTCToolStripMenuItem.Name = \"clearSelectedDTCToolStripMenuItem\";\n            this.clearSelectedDTCToolStripMenuItem.Size = new System.Drawing.Size(180, 22);\n            this.clearSelectedDTCToolStripMenuItem.Text = \"Clear Selected DTC\";\n            this.clearSelectedDTCToolStripMenuItem.Click += new System.EventHandler(this.clearSelectedDTCToolStripMenuItem_Click);\n            // \n            // clearAllDTCsToolStripMenuItem\n            // \n            this.clearAllDTCsToolStripMenuItem.Name = \"clearAllDTCsToolStripMenuItem\";\n            this.clearAllDTCsToolStripMenuItem.Size = new System.Drawing.Size(180, 22);\n            this.clearAllDTCsToolStripMenuItem.Text = \"Clear All DTCs\";\n            this.clearAllDTCsToolStripMenuItem.Click += new System.EventHandler(this.clearAllDTCsToolStripMenuItem_Click);\n            // \n            // refreshDataToolStripMenuItem\n            // \n            this.refreshDataToolStripMenuItem.Name = \"refreshDataToolStripMenuItem\";\n            this.refreshDataToolStripMenuItem.Size = new System.Drawing.Size(180, 22);\n            this.refreshDataToolStripMenuItem.Text = \"Refresh Data\";\n            this.refreshDataToolStripMenuItem.Click += new System.EventHandler(this.refreshDataToolStripMenuItem_Click);\n            // \n            // viewAllAvailableDTCsToolStripMenuItem\n            // \n            this.viewAllAvailableDTCsToolStripMenuItem.Name = \"viewAllAvailableDTCsToolStripMenuItem\";\n            this.viewAllAvailableDTCsToolStripMenuItem.Size = new System.Drawing.Size(192, 22);\n            this.viewAllAvailableDTCsToolStripMenuItem.Text = \"View all available DTCs\";\n            this.viewAllAvailableDTCsToolStripMenuItem.Click += new System.EventHandler(this.viewAllAvailableDTCsToolStripMenuItem_Click);\n            // \n            // DTCForm\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(1490, 759);\n            this.Controls.Add(this.splitContainer1);\n            this.Controls.Add(this.menuStrip1);\n            this.Icon = ((System.Drawing.Icon)(resources.GetObject(\"$this.Icon\")));\n            this.MainMenuStrip = this.menuStrip1;\n            this.Name = \"DTCForm\";\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\n            this.Text = \"Diagnostic Trouble Codes\";\n            this.Load += new System.EventHandler(this.DTCForm_Load);\n            this.splitContainer1.Panel1.ResumeLayout(false);\n            this.splitContainer1.Panel2.ResumeLayout(false);\n            ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();\n            this.splitContainer1.ResumeLayout(false);\n            ((System.ComponentModel.ISupportInitialize)(this.dgvMain)).EndInit();\n            ((System.ComponentModel.ISupportInitialize)(this.dgvContext)).EndInit();\n            this.menuStrip1.ResumeLayout(false);\n            this.menuStrip1.PerformLayout();\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.SplitContainer splitContainer1;\n        private System.Windows.Forms.DataGridView dgvMain;\n        private System.Windows.Forms.MenuStrip menuStrip1;\n        private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem exportDTCsToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem dTCToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem clearSelectedDTCToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem clearAllDTCsToolStripMenuItem;\n        private System.Windows.Forms.DataGridView dgvContext;\n        private System.Windows.Forms.ToolStripMenuItem refreshDataToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem viewAllAvailableDTCsToolStripMenuItem;\n    }\n}"
  },
  {
    "path": "Caesar/Diogenes/Forms/DTCForm.cs",
    "content": "﻿using Caesar;\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nusing System.Linq;\nusing System.Reflection;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\nusing static Caesar.DTC;\n\nnamespace Diogenes\n{\n    public partial class DTCForm : Form\n    {\n        ECUConnection Connection;\n        ECUVariant Variant;\n        \n        //List<Tuple<DTC, byte>> DisplayedDTCs;\n        \n        List<DTCContext> DTCContexts = new List<DTCContext>();\n\n        public DTCForm(ECUConnection connection, ECUVariant variant)\n        {\n            Connection = connection;\n            Variant = variant;\n            InitializeComponent();\n        }\n\n        private void DTCForm_Load(object sender, EventArgs e)\n        {\n            EnableDoubleBuffer(dgvMain, true);\n            EnableDoubleBuffer(dgvContext, true);\n\n            QueryDTC();\n\n            PresentDtcData();\n        }\n\n        private void PresentDtcData()\n        {\n            if (DTCContexts.Count == 0)\n            {\n                MessageBox.Show(\"ECU reports zero Diagnostic Trouble Codes\", \"No DTCs\");\n            }\n            PresentDTCs();\n            PresentEnvironmentContext();\n        }\n\n        private void QueryDTC() \n        {\n            GenericLoader loader = new GenericLoader();\n            loader.Text = \"Querying DTCs\";\n            loader.Show();\n            Application.DoEvents();\n\n            // fetch the base dtc value first\n            DTCContexts = Connection.ConnectionProtocol.ReportDtcsByStatusMask(Connection, Variant);\n            loader.SetProgressMax(DTCContexts.Count);\n            Application.DoEvents();\n\n            // query individual dtcs to retrieve the environment context\n            for (int j = 0; j < DTCContexts.Count; j++)\n            {\n                DTCContext dtcCtx = DTCContexts[j];\n                loader.Text = $\"Querying DTC {dtcCtx.DTC.Qualifier} [{j + 1}/{DTCContexts.Count}]\";\n                loader.SetProgressValue(j);\n                Application.DoEvents();\n\n                if (!Connection.ConnectionProtocol.GetDtcSnapshot(dtcCtx.DTC, Connection, out byte[] snapshot)) \n                {\n                    dtcCtx.EnvironmentContext = new List<string[]>();\n                    dtcCtx.EnvironmentContext.Add(new string[] { \"N/A\", \"N/A\" });\n                    continue;\n                }\n                List<DiagService> dtcEnvs = Variant.GetEnvironmentContextsForDTC(dtcCtx.DTC);\n                List<string[]> envCtx = new List<string[]>();\n\n                for (int i = 0; i < dtcEnvs.Count; i++)\n                {\n                    DiagService currentService = dtcEnvs[i];\n\n                    StringBuilder presentationOutput = new StringBuilder();\n                    foreach (List<DiagPreparation> wtf in currentService.OutputPreparations)\n                    {\n                        foreach (DiagPreparation outputPreparation in wtf)\n                        {\n                            /*\n                            // crd3: uncomment to find a misbehaving presentation; enum does not have the correct scales, maybe there's something shaped like a scale that needs parsing\n                            if (currentService.GetName().Contains(\"ufigkeitsz\")) \n                            {\n                                Console.WriteLine(\"dbg\");\n                            }\n                            */\n                            DiagPresentation presentation = outputPreparation.ParentECU.GlobalPresentations[outputPreparation.PresPoolIndex];\n#if DEBUG\n                            // way too verbose\n                            /*\n                            if (false)\n                            {\n                                presentationOutput.Append($\"Position: {outputPreparation.BitPosition}, BitWidth: {outputPreparation.SizeInBits}, \");\n                                presentationOutput.Append($\"\\r\\n{ presentation.CopyMinDebug()}\\r\\n\");\n                            }\n                            */\n#endif\n                            presentationOutput.Append(presentation.InterpretData(snapshot, outputPreparation, false));\n                        }\n                    }\n                    envCtx.Add(new string[] { currentService.GetName(), presentationOutput.ToString() });\n                }\n                dtcCtx.EnvironmentContext = envCtx;\n            }\n\n            loader.Close();\n        }\n\n\n        private void PresentDTCs()\n        {\n            string[] Headers = new string[] { \"Code\", \"Description\", \"Status\", \"Current\", \"Stored\", \"MIL On\",\n                \"Failed: Request Time\", \"Failed: Current Cycle\", \"Failed: Last Clear\", \"Incomplete: Current Cycle\", \"Incomplete: Last Clear\" };\n            DataTable dt = new DataTable();\n\n            dt.Columns.Add(\"Index\", typeof(int));\n            foreach (string header in Headers)\n            {\n                dt.Columns.Add(header, typeof(String));\n            }\n            dgvMain.DataSource = dt;\n\n            for (int i = 0; i < DTCContexts.Count; i++)\n            {\n                List<string> row = new List<string>();\n                DTC currentDtc = DTCContexts[i].DTC;\n                byte statusByte = DTCContexts[i].StatusByte;\n\n                bool dtcStatusIsCurrent = (statusByte & (int)DTCStatusByte.PendingDTC) > 0;\n                bool dtcStatusIsStored = (statusByte & (int)DTCStatusByte.ConfirmedDTC) > 0;\n                bool dtcStatusIsMILActive = (statusByte & (int)DTCStatusByte.WarningIndicatorActive) > 0;\n\n                bool dtcStatusFailedAtRequestTime = (statusByte & (int)DTCStatusByte.TestFailedAtRequestTime) > 0;\n                bool dtcStatusFailedAtCurrentCycle = (statusByte & (int)DTCStatusByte.TestFailedAtCurrentCycle) > 0;\n                bool dtcStatusFailedSinceLastClear = (statusByte & (int)DTCStatusByte.TestFailedSinceLastClear) > 0;\n                bool dtcStatusIncompleteAtCurrentCycle = (statusByte & (int)DTCStatusByte.TestIncompleteAtCurrentCycle) > 0;\n                bool dtcStatusIncompleteSinceLastClear = (statusByte & (int)DTCStatusByte.TestIncompleteSinceLastClear) > 0;\n\n                row.Add(currentDtc.Qualifier);\n                row.Add(currentDtc.Description);\n                row.Add($\"{statusByte:X2}\");\n\n                row.Add($\"{dtcStatusIsCurrent}\");\n                row.Add($\"{dtcStatusIsStored}\");\n                row.Add($\"{dtcStatusIsMILActive}\");\n\n                row.Add($\"{dtcStatusFailedAtRequestTime}\");\n                row.Add($\"{dtcStatusFailedAtCurrentCycle}\");\n                row.Add($\"{dtcStatusFailedSinceLastClear}\");\n                row.Add($\"{dtcStatusIncompleteAtCurrentCycle}\");\n                row.Add($\"{dtcStatusIncompleteSinceLastClear}\");\n\n                row.Insert(0, i.ToString());\n                dt.Rows.Add(row.ToArray());\n            }\n\n            for (int i = 3; i < Headers.Length; i++)\n            {\n                dgvMain.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;\n            }\n\n            dgvMain.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;\n            dgvMain.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;\n            dgvMain.Columns[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; // was Fill, \n            dgvMain.Columns[0].Visible = false;\n        }\n\n\n        private void PresentEnvironmentContext()\n        {\n            if (dgvMain.SelectedRows.Count != 1)\n            {\n                return;\n            }\n\n            int selectedIndex = int.Parse(dgvMain.SelectedRows[0].Cells[0].Value.ToString());\n            List<string[]> envCtx = DTCContexts[selectedIndex].EnvironmentContext;\n\n            string[] Headers = new string[] { \"Environment\", \"Description\" };\n            DataTable dt = new DataTable();\n\n            dt.Columns.Add(\"Index\", typeof(int));\n            foreach (string header in Headers)\n            {\n                dt.Columns.Add(header, typeof(String));\n            }\n            dgvContext.DataSource = dt;\n            for (int i = 0; i < envCtx.Count; i++)\n            {\n                List<string> row = new List<string>();\n                row.Insert(0, i.ToString());\n                row.AddRange(envCtx[i]);\n                dt.Rows.Add(row.ToArray());\n            }\n\n            dgvContext.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;\n            dgvContext.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;\n            dgvContext.Columns[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;\n            dgvContext.Columns[2].DefaultCellStyle.WrapMode = DataGridViewTriState.True;\n            dgvContext.AutoResizeRows();\n\n            dgvContext.Columns[0].Visible = false;\n        }\n\n        public static void EnableDoubleBuffer(DataGridView dgv, bool setting)\n        {\n            Type dgvType = dgv.GetType();\n            PropertyInfo pi = dgvType.GetProperty(\"DoubleBuffered\", BindingFlags.Instance | BindingFlags.NonPublic);\n            pi.SetValue(dgv, setting, null);\n        }\n\n        private void clearAllDTCsToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            if (MessageBox.Show($\"Clear all DTCs?\", \"Confirm DTC Clear\", MessageBoxButtons.YesNo) == DialogResult.Yes)\n            {\n                ClearAllDTCs();\n            }\n        }\n\n        private void clearSelectedDTCToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            if (dgvMain.SelectedRows.Count == 1)\n            {\n                int selectedIndex = int.Parse(dgvMain.SelectedRows[0].Cells[0].Value.ToString());\n                DTC selectedDtc = DTCContexts[selectedIndex].DTC;\n                if (MessageBox.Show($\"Clear {selectedDtc.Qualifier}?\", \"Confirm DTC Clear\", MessageBoxButtons.YesNo) == DialogResult.Yes)\n                {\n                    ClearDTC(selectedDtc);\n                }\n            }\n        }\n\n        private void ClearAllDTCs()\n        {\n            byte[] request = new byte[] { 0x14, 0xFF, 0xFF, 0xFF }; // essentially ClearDTC a mask of FFFFFF\n            byte[] expectedResponse = new byte[] { 0x59 };\n            byte[] response = Connection.SendMessage(request);\n            if (!(response.Take(expectedResponse.Length).SequenceEqual(expectedResponse)))\n            {\n                MessageBox.Show($\"Clear request (for all DTCs) was rejected\", \"Negative Response\");\n            }\n            else\n            {\n                QueryDTC();\n                PresentDtcData();\n            }\n        }\n\n        private void ClearDTC(DTC dtc)\n        {\n            if (dtc.Qualifier.Length != 7)\n            {\n                MessageBox.Show(\"Internal error: DTC qualifier is invalid, exiting prematurely.\");\n                return;\n            }\n            byte[] identifier = BitUtility.BytesFromHex(dtc.Qualifier.Substring(1));\n            byte[] request = new byte[] { 0x14, identifier[0], identifier[1], identifier[2] };\n            byte[] expectedResponse = new byte[] { 0x59 };\n            byte[] response = Connection.SendMessage(request);\n            if (!(response.Take(expectedResponse.Length).SequenceEqual(expectedResponse)))\n            {\n                MessageBox.Show($\"Clear request ({dtc.Qualifier}) was rejected\", \"Negative Response\");\n            }\n            else\n            {\n                QueryDTC();\n                PresentDtcData();\n            }\n        }\n\n        private void refreshDataToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            QueryDTC();\n            PresentDtcData();\n        }\n\n        private void dgvMain_SelectionChanged(object sender, EventArgs e)\n        {\n            PresentEnvironmentContext();\n        }\n\n        private void exportDTCsToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            DTCReport.CreateDTCReport(DTCContexts, Connection, Variant);\n        }\n\n        private void viewAllAvailableDTCsToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            List<string[]> rows = new List<string[]>();\n            foreach (DTC dtc in Variant.DTCs) \n            {\n                rows.Add(new string[] { dtc.Qualifier, dtc.Description });\n            }\n            GenericPicker picker = new GenericPicker(rows.ToArray(), new string[] { \"Identifier\", \"Description\" }, 0, true);\n            picker.Text = $\"All DTCs for {Variant.Qualifier}\";\n            picker.Show();\n        }\n    }\n\n    public class DTCContext\n    {\n        public DTC DTC;\n        public byte StatusByte;\n        public List<string[]> EnvironmentContext;\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/Forms/DTCForm.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <metadata name=\"menuStrip1.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>17, 17</value>\n  </metadata>\n  <assembly alias=\"System.Drawing\" name=\"System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\" />\n  <data name=\"$this.Icon\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n    <value>\n        AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAADKKxewwh8T2L4XD9i2DwvYrgcH2KX/A9ih9v/Yme772JXm99iN3\n        vfYidrzDAAAAAAAAAAAAAAAAAAAAAAAAAAA4kcnk3ez2/73u+f+s6vj/q+r4/6vq+P+r6vj/rer4/9Tz\n        +/+kyOT/Jnu+qwAAAAAAAAAAAAAAAAAAAAAAAAAAP5nNa47C4f+X6Pn/Ydz2/1vb9f8yiML/W9v1/2re\n        9v+x5/b/LYPC6SuBwSqmpqa3oKCg/5qamv+Tk5P/jY2N/4SHiP9PmL//q9vv/3Tg9/9Y2vX/WNr1/13b\n        9f+Q5vj/ksHh/0dyj/9aWlq3rq6u/+np6f/T09P/0tLS/9HR0f/Q0ND/qMPP/3u93/+i6vn/Ydz2/zGH\n        wv934ff/tt7w/1Gcyv/Z3uH/W1tb/7W1tf/W1tb/u7u7/7m5uf+2trb/tLS0/7Gysv9xrcj/rNns/4Lj\n        +P8ziML/rO36/0Oez/+Go7T/yMjI/19fX/+8vLz/2dnZ/76+vv+7u7v/jo6O/4+Pj/+QkJD/hpWc/1Wt\n        0v+06/j/jub4/7Xd7v9mp8f/p6mq/8rKyv9kZGT/w8PD/93d3f/CwsL/vr6+/5GRkf+SkpL/lJSU/5SU\n        lP91pLf/pNfr/9z0+/9VrdL/ma22/62trf/Pz8//aWlp/8nJyb3d3d3/yMjI/8HBwf/AwMD/vr6+/7u7\n        u/+5ubn/s7i6/2i51/+r2+3/f7TI/7CwsP+0tLT/wMDA/29vb73Pz8+96Ojo/+fn5//h4eH/4ODg/+Dg\n        4P/f39//39/f/97e3v+z097/eMTe/9HZ3P/b29v/4ODg/83Nzf91dXW909PTP9nZ2f/s7Oz/3t7e/9jY\n        2P/S0tL/zMzM/8jIyP/Hx8f/yMjI/8vLy//Q0ND/3d3d/+jo6P+goKD/fHx8QgAAAADU1NS96Ojo/9vb\n        2//i4uL/4uLi/+Hh4f/g4OD/4ODg/+Dg4P/f39//w8PD/9HR0f/S0tL/ioqKvQAAAAAAAAAA2NjYP97e\n        3v/z8/P/7e3t/+3t7f/t7e3/7e3t/+3t7f/s7Oz/7Ozs/+zs7P/x8fH/sbGx/5KSkkIAAAAAAAAAAAAA\n        AADY2Ni91dXV/9LS0v/Ozs7/ycnJ/8TExP+/v7//ubm5/7Ozs/+tra3/pqam/6CgoL0AAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAA+AAAAPgAAAD4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAAgAEAAMAD\n        AAD//wAA//8AAA==\n</value>\n  </data>\n</root>"
  },
  {
    "path": "Caesar/Diogenes/Forms/FlashSplicer.Designer.cs",
    "content": "﻿\nnamespace Diogenes\n{\n    partial class FlashSplicer\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FlashSplicer));\n            this.menuStrip1 = new System.Windows.Forms.MenuStrip();\n            this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.openCFFFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.exportSplicedFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.groupBox1 = new System.Windows.Forms.GroupBox();\n            this.dgvMain = new System.Windows.Forms.DataGridView();\n            this.groupBox2 = new System.Windows.Forms.GroupBox();\n            this.txtLog = new System.Windows.Forms.TextBox();\n            this.menuStrip1.SuspendLayout();\n            this.groupBox1.SuspendLayout();\n            ((System.ComponentModel.ISupportInitialize)(this.dgvMain)).BeginInit();\n            this.groupBox2.SuspendLayout();\n            this.SuspendLayout();\n            // \n            // menuStrip1\n            // \n            this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.fileToolStripMenuItem});\n            this.menuStrip1.Location = new System.Drawing.Point(0, 0);\n            this.menuStrip1.Name = \"menuStrip1\";\n            this.menuStrip1.Size = new System.Drawing.Size(991, 24);\n            this.menuStrip1.TabIndex = 0;\n            this.menuStrip1.Text = \"menuStrip1\";\n            // \n            // fileToolStripMenuItem\n            // \n            this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.openCFFFileToolStripMenuItem,\n            this.exportSplicedFileToolStripMenuItem});\n            this.fileToolStripMenuItem.Name = \"fileToolStripMenuItem\";\n            this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);\n            this.fileToolStripMenuItem.Text = \"File\";\n            // \n            // openCFFFileToolStripMenuItem\n            // \n            this.openCFFFileToolStripMenuItem.Name = \"openCFFFileToolStripMenuItem\";\n            this.openCFFFileToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O)));\n            this.openCFFFileToolStripMenuItem.Size = new System.Drawing.Size(209, 22);\n            this.openCFFFileToolStripMenuItem.Text = \"Open CFF File\";\n            this.openCFFFileToolStripMenuItem.Click += new System.EventHandler(this.openCFFFileToolStripMenuItem_Click);\n            // \n            // exportSplicedFileToolStripMenuItem\n            // \n            this.exportSplicedFileToolStripMenuItem.Name = \"exportSplicedFileToolStripMenuItem\";\n            this.exportSplicedFileToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S)));\n            this.exportSplicedFileToolStripMenuItem.Size = new System.Drawing.Size(209, 22);\n            this.exportSplicedFileToolStripMenuItem.Text = \"Export Spliced File\";\n            this.exportSplicedFileToolStripMenuItem.Click += new System.EventHandler(this.exportSplicedFileToolStripMenuItem_Click);\n            // \n            // groupBox1\n            // \n            this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.groupBox1.Controls.Add(this.dgvMain);\n            this.groupBox1.Location = new System.Drawing.Point(12, 288);\n            this.groupBox1.Name = \"groupBox1\";\n            this.groupBox1.Size = new System.Drawing.Size(967, 228);\n            this.groupBox1.TabIndex = 1;\n            this.groupBox1.TabStop = false;\n            this.groupBox1.Text = \"Flash Payload\";\n            // \n            // dgvMain\n            // \n            this.dgvMain.AllowUserToAddRows = false;\n            this.dgvMain.AllowUserToDeleteRows = false;\n            this.dgvMain.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;\n            this.dgvMain.Dock = System.Windows.Forms.DockStyle.Fill;\n            this.dgvMain.Location = new System.Drawing.Point(3, 16);\n            this.dgvMain.MultiSelect = false;\n            this.dgvMain.Name = \"dgvMain\";\n            this.dgvMain.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;\n            this.dgvMain.ShowEditingIcon = false;\n            this.dgvMain.Size = new System.Drawing.Size(961, 209);\n            this.dgvMain.TabIndex = 1;\n            this.dgvMain.CellBeginEdit += new System.Windows.Forms.DataGridViewCellCancelEventHandler(this.dgvMain_CellBeginEdit);\n            // \n            // groupBox2\n            // \n            this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.groupBox2.Controls.Add(this.txtLog);\n            this.groupBox2.Location = new System.Drawing.Point(12, 27);\n            this.groupBox2.Name = \"groupBox2\";\n            this.groupBox2.Size = new System.Drawing.Size(964, 255);\n            this.groupBox2.TabIndex = 2;\n            this.groupBox2.TabStop = false;\n            this.groupBox2.Text = \"CFF Description\";\n            // \n            // txtLog\n            // \n            this.txtLog.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.txtLog.Font = new System.Drawing.Font(\"Segoe UI\", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.txtLog.Location = new System.Drawing.Point(6, 19);\n            this.txtLog.Multiline = true;\n            this.txtLog.Name = \"txtLog\";\n            this.txtLog.ScrollBars = System.Windows.Forms.ScrollBars.Both;\n            this.txtLog.Size = new System.Drawing.Size(952, 230);\n            this.txtLog.TabIndex = 0;\n            // \n            // FlashSplicer\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(991, 528);\n            this.Controls.Add(this.groupBox2);\n            this.Controls.Add(this.groupBox1);\n            this.Controls.Add(this.menuStrip1);\n            this.Icon = ((System.Drawing.Icon)(resources.GetObject(\"$this.Icon\")));\n            this.MainMenuStrip = this.menuStrip1;\n            this.Name = \"FlashSplicer\";\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\n            this.Text = \"Flash Splicer\";\n            this.menuStrip1.ResumeLayout(false);\n            this.menuStrip1.PerformLayout();\n            this.groupBox1.ResumeLayout(false);\n            ((System.ComponentModel.ISupportInitialize)(this.dgvMain)).EndInit();\n            this.groupBox2.ResumeLayout(false);\n            this.groupBox2.PerformLayout();\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.MenuStrip menuStrip1;\n        private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem openCFFFileToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem exportSplicedFileToolStripMenuItem;\n        private System.Windows.Forms.GroupBox groupBox1;\n        private System.Windows.Forms.DataGridView dgvMain;\n        private System.Windows.Forms.GroupBox groupBox2;\n        private System.Windows.Forms.TextBox txtLog;\n    }\n}"
  },
  {
    "path": "Caesar/Diogenes/Forms/FlashSplicer.cs",
    "content": "﻿using Caesar;\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\n\nnamespace Diogenes\n{\n    public partial class FlashSplicer : Form\n    {\n\n        List<List<byte[]>> FlashData = new List<List<byte[]>>();\n        CaesarFlashContainer FlashContainer = null;\n        List<List<string>> SplicePath = new List<List<string>>();\n        List<List<int>> MappedAddresses = new List<List<int>>();\n        byte[] FlashBytes = new byte[] { };\n\n        public FlashSplicer()\n        {\n            InitializeComponent();\n        }\n\n        private void openCFFFileToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            OpenFileDialog ofd = new OpenFileDialog();\n            ofd.Title = \"Select a CFF File\";\n            ofd.Filter = \"CFF files (*.cff)|*.cff|All files (*.*)|*.*\";\n            ofd.Multiselect = false;\n            if (ofd.ShowDialog() == DialogResult.OK)\n            {\n                LoadCFF(ofd.FileName);\n                PresentRows();\n            }\n        }\n\n        public void LoadCFF(string filePath)\n        {\n            string directory = Path.GetDirectoryName(filePath);\n\n            FlashBytes = File.ReadAllBytes(filePath);\n            FlashContainer = new CaesarFlashContainer(FlashBytes);\n\n            FlashData = new List<List<byte[]>>();\n            SplicePath = new List<List<string>>();\n            MappedAddresses = new List<List<int>>();\n\n            using (BinaryReader reader = new BinaryReader(new MemoryStream(FlashBytes)))\n            {\n                foreach (FlashDataBlock db in FlashContainer.CaesarFlashHeader.DataBlocks)\n                {\n                    long fileCursor = 0;\n\n                    List<byte[]> segmentChunks = new List<byte[]>();\n                    List<string> spliceStub = new List<string>();\n                    List<int> mapStub = new List<int>();\n\n                    foreach (FlashSegment seg in db.FlashSegments)\n                    {\n                        long offset =\n                            db.FlashData +\n                            FlashContainer.CaesarFlashHeader.CffHeaderSize +\n                            FlashContainer.CaesarFlashHeader.LanguageBlockLength +\n                            fileCursor +\n                            0x414;\n\n                        fileCursor += seg.SegmentLength;\n\n                        reader.BaseStream.Seek(offset, SeekOrigin.Begin);\n                        byte[] fileBytes = reader.ReadBytes(seg.SegmentLength);\n\n                        segmentChunks.Add(fileBytes);\n                        spliceStub.Add(\"\");\n                        mapStub.Add(seg.FromAddress);\n                    }\n                    FlashData.Add(segmentChunks);\n                    SplicePath.Add(spliceStub);\n                    MappedAddresses.Add(mapStub);\n                }\n            }\n\n            txtLog.Text = GetLog();\n        }\n\n        private string GetLog() \n        {\n            FlashHeader header = FlashContainer.CaesarFlashHeader;\n            StringBuilder response = new StringBuilder();\n            response.Append($\"Name\\t\\t\\t: {header.FlashName}\\r\\n\" +\n                $\"Author\\t\\t\\t: {header.FileAuthor}\\r\\n\" +\n                $\"Creation Time\\t\\t: {header.FileCreationTime}\\r\\n\" +\n                $\"Authoring Tool Version\\t: {header.AuthoringToolVersion}\\r\\n\" +\n                $\"Trafo Version\\t\\t: {header.FTRAFOVersionString}\\r\\n\" +\n                $\"CFF Version\\t\\t: {header.CFFVersionString}\\r\\n\" +\n                $\"Referenced ECU count\\t: {header.NumberOfECURefs}\\r\\n\" +\n                $\"Generation Parameter:\\n {header.FlashGenerationParams}\\r\\n\" +\n                $\"\\r\\n---------------------\\r\\n\");\n\n            foreach (var blocks in FlashContainer.CaesarFlashHeader.DataBlocks) \n            {\n                response.Append($\"\\r\\nFlash block: {blocks.Qualifier}\");\n\n                for (int secIndex = 0; secIndex < blocks.FlashSecurities.Count; secIndex++) \n                {\n                    var sec = blocks.FlashSecurities[secIndex];\n                    response.Append($\"\\r\\n\\r\\nSecurity [{secIndex}]\");\n\n                    if (sec.MethodValue.Length > 0)\n                    {\n                        response.Append($\"\\r\\n - Method : {BitUtility.BytesToHex(sec.MethodValue)}\");\n                    }\n                    if (sec.SignatureValue.Length > 0)\n                    {\n                        response.Append($\"\\r\\n - Signature : {BitUtility.BytesToHex(sec.SignatureValue)}\");\n                    }\n                    if (sec.ChecksumValue.Length > 0)\n                    {\n                        response.Append($\"\\r\\n - Checksum : {BitUtility.BytesToHex(sec.ChecksumValue)}\");\n                    }\n                    if (sec.EcuKeyValue.Length > 0)\n                    {\n                        response.Append($\"\\r\\n - ECU : {BitUtility.BytesToHex(sec.EcuKeyValue)}\");\n                    }\n                }\n            }\n            return response.ToString();\n        }\n\n        private void PresentRows()\n        {\n            if (FlashContainer is null) \n            {\n                return;\n            }\n\n            DataTable dt = new DataTable();\n\n            foreach (string header in new string[] { \"Block #\", \"Block Name\", \"Block Description\", \"Segment #\", \"Segment Name\", \"ECU Target Address (Editable)\",  \"Original Length\", \"Original Offset\", \"Splice Mode\"})\n            {\n                dt.Columns.Add(header, typeof(string));\n            }\n            dgvMain.DataSource = dt;\n\n            for (int i = 0; i < FlashContainer.CaesarFlashHeader.DataBlocks.Count; i++) \n            {\n                FlashDataBlock db = FlashContainer.CaesarFlashHeader.DataBlocks[i];\n                long fileCursor = 0;\n\n                for (int j = 0; j < db.FlashSegments.Count; j++) \n                {\n                    FlashSegment seg = db.FlashSegments[j];\n\n                    long offset =\n                        db.FlashData +\n                        FlashContainer.CaesarFlashHeader.CffHeaderSize +\n                        FlashContainer.CaesarFlashHeader.LanguageBlockLength +\n                        fileCursor +\n                        0x414;\n\n                    fileCursor += seg.SegmentLength;\n\n                    // Console.WriteLine($\"Segment: {seg.SegmentName} mapped to 0x{seg.FromAddress:X} with size 0x{seg.SegmentLength:X}\");\n                    string spliceModeForRow = SplicePath[i][j].Length == 0 ? \"Inherit Original\" : SplicePath[i][j];\n\n                    dt.Rows.Add(\n                        i.ToString(),  \n                        db.Qualifier, \n                        FlashContainer.CaesarCTFHeader.CtfLanguages[0].GetString(db.Description), \n                        j.ToString(), \n                        seg.SegmentName, \n                        seg.FromAddress.ToString(\"X\"), \n                        seg.SegmentLength.ToString(\"X\"), \n                        offset.ToString(\"X\"),\n                        spliceModeForRow\n                        );\n                }\n            }\n\n            dgvMain.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;\n\n            dgvMain.Columns[0].ReadOnly = true;\n            dgvMain.Columns[1].ReadOnly = true;\n            dgvMain.Columns[2].ReadOnly = true;\n            dgvMain.Columns[3].ReadOnly = true;\n            dgvMain.Columns[4].ReadOnly = true;\n            dgvMain.Columns[5].ReadOnly = false;\n            dgvMain.Columns[6].ReadOnly = true;\n            dgvMain.Columns[7].ReadOnly = true;\n            dgvMain.Columns[8].ReadOnly = false;\n\n            dgvMain.Columns[dgvMain.Columns.Count - 1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;\n        }\n\n        private void GenericPicker_Load(object sender, EventArgs e)\n        {\n            PresentRows();\n        }\n\n        private void dgvMain_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)\n        {\n            if ((e.RowIndex < 0) || (e.RowIndex > dgvMain.Rows.Count)) \n            {\n                return;\n            }\n\n            if (e.ColumnIndex == (dgvMain.Columns.Count - 1))\n            {\n                OpenFileDialog ofd = new OpenFileDialog();\n                ofd.Title = \"Select a replacement binary file\";\n                ofd.Filter = \"BIN files (*.bin)|*.bin|All files (*.*)|*.*\";\n                ofd.Multiselect = false;\n                if (ofd.ShowDialog() == DialogResult.OK)\n                {\n                    int blockIndex = int.Parse(dgvMain.Rows[e.RowIndex].Cells[0].Value.ToString());\n                    int segmentIndex = int.Parse(dgvMain.Rows[e.RowIndex].Cells[3].Value.ToString());\n\n                    SplicePath[blockIndex][segmentIndex] = ofd.FileName;\n                    PresentRows();\n                }\n                e.Cancel = true;\n            }\n        }\n\n        private void exportSplicedFileToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            if (FlashContainer is null)\n            {\n                return;\n            }\n            if (!LoadMappedAddresses()) \n            {\n                return;\n            }\n\n            /*\n             we need to..\n                - get the fileoffsets of the segment sizes\n                - get the fileoffsets of the segment addresses\n                - get the fileoffset of the flash start address\n                \n                - patch all the fileoffsets (size+address) with the new value\n             */\n\n            int flashDataFileOffset = FlashContainer.CaesarFlashHeader.CffHeaderSize + FlashContainer.CaesarFlashHeader.LanguageBlockLength + 0x414;\n            byte[] nonFlashData = FlashBytes.Take(flashDataFileOffset).ToArray();\n\n            using (BinaryReader reader = new BinaryReader(new MemoryStream(FlashBytes, 0, FlashBytes.Length, false, true)))\n            using (BinaryWriter nonFlashWriter = new BinaryWriter(new MemoryStream(nonFlashData)))\n            using (BinaryWriter flashPayloadWriter = new BinaryWriter(new MemoryStream()))\n            {\n                int segmentCursor = 0;\n\n                for (int i = 0; i < FlashContainer.CaesarFlashHeader.DataBlocks.Count; i++)\n                {\n                    FlashDataBlock db = FlashContainer.CaesarFlashHeader.DataBlocks[i];\n                    // read block offset fileoffset\n                    long blockOffsetFileOffset = db.GetFlashDataOffset(reader);\n\n                    // patch segment length on filebytes\n                    nonFlashWriter.BaseStream.Seek(blockOffsetFileOffset, SeekOrigin.Begin);\n                    nonFlashWriter.Write(segmentCursor);\n\n                    int localBlockLength = 0;\n                    for (int j = 0; j < db.FlashSegments.Count; j++)\n                    {\n                        FlashSegment seg = db.FlashSegments[j];\n                        // check: which fields are mutable when splicing\n\n                        long offset =\n                            db.FlashData + // somewhat mutable : probably if there's more than 1 datablock, this value will be nonzero\n                            FlashContainer.CaesarFlashHeader.CffHeaderSize + // constant\n                            FlashContainer.CaesarFlashHeader.LanguageBlockLength + // constant\n                            segmentCursor + // mutable, see below\n                            0x414; // constant\n\n                        byte[] segmentPayload = FlashData[i][j];\n                        if (SplicePath[i][j].Length > 0) \n                        {\n                            segmentPayload = File.ReadAllBytes(SplicePath[i][j]);\n                        }\n\n                        int segmentMappedAddress = MappedAddresses[i][j];\n\n\n                        // read segment length's offset\n                        long segmentLengthFileOffset = seg.GetSegmentLengthFileOffset(reader);\n                        // read segment's mapped address\n                        long segmentMappedAddressFileOffset = seg.GetMappedAddressFileOffset(reader);\n\n                        // patch segment length on filebytes\n                        nonFlashWriter.BaseStream.Seek(segmentLengthFileOffset, SeekOrigin.Begin);\n                        nonFlashWriter.Write(segmentPayload.Length);\n                        // patch segment's mapped address\n                        nonFlashWriter.BaseStream.Seek(segmentMappedAddressFileOffset, SeekOrigin.Begin);\n                        nonFlashWriter.Write(segmentMappedAddress);\n\n                        // increment segment offset for db.flashdata\n                        segmentCursor += segmentPayload.Length;\n                        localBlockLength += segmentPayload.Length;\n\n                        // append flash payload to temp buffer\n                        flashPayloadWriter.Write(segmentPayload);\n\n                    }\n\n                    // refresh the block size\n                    // read block size fileoffset\n                    long blockSizeFileOffset = db.GetBlockLengthOffset(reader);\n\n                    // patch block length\n                    nonFlashWriter.BaseStream.Seek(blockSizeFileOffset, SeekOrigin.Begin);\n                    nonFlashWriter.Write(localBlockLength);\n                }\n\n\n                // take the non-flash part of the bytes that we patched...\n                // .. then merge it with the flash section that we rebuilt\n                byte[] flashPayload = ((MemoryStream)flashPayloadWriter.BaseStream).ToArray();\n                byte[] nonFlashPrefix = ((MemoryStream)nonFlashWriter.BaseStream).ToArray();\n\n                byte[] result = new byte[flashPayload.Length + nonFlashPrefix.Length + 4];\n                Array.ConstrainedCopy(nonFlashPrefix, 0, result, 0, nonFlashPrefix.Length);\n                Array.ConstrainedCopy(flashPayload, 0, result, nonFlashPrefix.Length, flashPayload.Length);\n\n                // restore the checksum\n                uint checksum = CaesarReader.ComputeFileChecksumLazy(result);\n\n                result[result.Length - 4] = (byte)((checksum >> 0) & 0xFF);\n                result[result.Length - 3] = (byte)((checksum >> 8) & 0xFF);\n                result[result.Length - 2] = (byte)((checksum >> 16) & 0xFF);\n                result[result.Length - 1] = (byte)((checksum >> 24) & 0xFF);\n\n                // save the result\n                SaveFileDialog sfd = new SaveFileDialog();\n                sfd.Title = \"Specify a location to save your new CFF file\";\n                sfd.Filter = \"CFF files (*.cff)|*.cff|All files (*.*)|*.*\";\n                if (sfd.ShowDialog() == DialogResult.OK)\n                {\n                    File.WriteAllBytes(sfd.FileName, result);\n                }\n            }\n\n\n        }\n\n        private bool LoadMappedAddresses() \n        {\n            for (int i = 0; i < dgvMain.Rows.Count; i++)\n            {\n                int blockIndex = int.Parse(dgvMain.Rows[i].Cells[0].Value.ToString());\n                int segmentIndex = int.Parse(dgvMain.Rows[i].Cells[3].Value.ToString());\n\n                string inHexString = dgvMain.Rows[i].Cells[5].Value.ToString();\n                if (int.TryParse(inHexString, System.Globalization.NumberStyles.AllowHexSpecifier, System.Globalization.CultureInfo.InvariantCulture, out int result))\n                {\n                    MappedAddresses[blockIndex][segmentIndex] = result;\n                }\n                else\n                {\n                    MessageBox.Show($\"Failed to parse a hex value: {inHexString}\");\n                    return false;\n                }\n            }\n            return true;\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/Forms/FlashSplicer.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <metadata name=\"menuStrip1.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>17, 17</value>\n  </metadata>\n  <assembly alias=\"System.Drawing\" name=\"System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\" />\n  <data name=\"$this.Icon\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n    <value>\n        AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAJabbLiKh2SwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAACir3UklptvfIqLaUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAKlxUanDjmj/wItm/76IZP+7hWH/TqG8/0O14/9Tla//qH1g/655V/+tdlb/q3VU/6lz\n        U/+pcVH/qXFRqQAAAADIkmz///////////////////////P7/f8xr9//Ubrm/zut3v+r2fD/////////\n        /////////////6lyUf8AAAAAypRu//////+k4/T/kNvw/5La7/+M1u7/Pbfi/33Q8P9tx+z/RLLi/3PB\n        5P/f7/X//Pz5//////+qc1P/AAAAAMyXb///////Y9Hs/27Y8P9o0+//Zs/t/4TZ8/+I1/T/fc/x/1i8\n        6P9St+X/Ip3X/6XT6f/1+v3/rHVU/wAAAADRnHP//////9Tz+P9Jyer/kOb4/43j9/9g0vL/hNf0/zy3\n        4v+Gz+r/i8/p/4LK5/+QzOb/5fP6/7B6WP8AAAAA1J51///////6/fz/muLy/2vZ8f+W5/j/R8/y/4nc\n        9P84ueP/pNvs//v49P/79/L/+/Xy//////+yfFr/AAAAANWgdv///////f38/+X3+f9HzOv/k+f4/1/Y\n        9P+Q4Pb/fdby/1LD6f+q2+v/+vPv//jy7P//////tX5c/wAAAADYonn///////39+v/6+/r/jeDx/3Te\n        8/+J4/b/hd71/4HZ9P940/H/UMLo/67a5//07Oj//////7eBXv8AAAAA2aN5///////8+/n//Pv4/8ru\n        9P9d1Oz/WdHr/1fO6v9Vyuj/U8fn/07C5P9YwuP/3OHe//////+6hWD/AAAAANukev//////////////\n        ////////////////////////////////////////////////////////vYdj/wAAAADcp3v/3Kd7/9yn\n        e//cp3v/3Kd7/9yne//cp3v/3Kd7/9yne//cp3v/3Kd7/9yne//cp3v/3Kd7/8CLZv8AAAAA3ayF/ei5\n        kv/ouZL/6LmS/+i5kv/ouZL/6LmS/+i5kv/ouZL/6LmS/+i5kv/ouZL/6LmS/+i5kv/BkG/9AAAAAKlx\n        UWvdsY303Kd7/9ymev/apHr/2KJ5/9Wgdv/UnnX/0p1z/8+acv/OmXD/y5Zv/8mUbP/Emnr0qXFRawAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAA8/8AAPH/AAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAB\n        AAAAAQAA//8AAA==\n</value>\n  </data>\n</root>"
  },
  {
    "path": "Caesar/Diogenes/Forms/GenericLoader.Designer.cs",
    "content": "﻿\nnamespace Diogenes\n{\n    partial class GenericLoader\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.progressBar1 = new System.Windows.Forms.ProgressBar();\n            this.SuspendLayout();\n            // \n            // progressBar1\n            // \n            this.progressBar1.Dock = System.Windows.Forms.DockStyle.Fill;\n            this.progressBar1.Location = new System.Drawing.Point(0, 0);\n            this.progressBar1.Name = \"progressBar1\";\n            this.progressBar1.Size = new System.Drawing.Size(658, 51);\n            this.progressBar1.TabIndex = 0;\n            // \n            // GenericLoader\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(658, 51);\n            this.ControlBox = false;\n            this.Controls.Add(this.progressBar1);\n            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;\n            this.Name = \"GenericLoader\";\n            this.ShowIcon = false;\n            this.ShowInTaskbar = false;\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\n            this.Text = \"Loading..\";\n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.ProgressBar progressBar1;\n    }\n}"
  },
  {
    "path": "Caesar/Diogenes/Forms/GenericLoader.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\n\nnamespace Diogenes\n{\n    public partial class GenericLoader : Form\n    {\n        public GenericLoader()\n        {\n            InitializeComponent();\n        }\n        public void SetProgressValue(int value)\n        {\n            progressBar1.Value = value;\n        }\n        public void SetProgressMax(int value)\n        {\n            progressBar1.Maximum = value;\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/Forms/GenericLoader.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "Caesar/Diogenes/Forms/GenericPicker.Designer.cs",
    "content": "﻿\nnamespace Diogenes\n{\n    partial class GenericPicker\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.dgvMain = new System.Windows.Forms.DataGridView();\n            this.txtFilter = new System.Windows.Forms.TextBox();\n            ((System.ComponentModel.ISupportInitialize)(this.dgvMain)).BeginInit();\n            this.SuspendLayout();\n            // \n            // dgvMain\n            // \n            this.dgvMain.AllowUserToAddRows = false;\n            this.dgvMain.AllowUserToDeleteRows = false;\n            this.dgvMain.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.dgvMain.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;\n            this.dgvMain.Location = new System.Drawing.Point(0, 20);\n            this.dgvMain.MultiSelect = false;\n            this.dgvMain.Name = \"dgvMain\";\n            this.dgvMain.ReadOnly = true;\n            this.dgvMain.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;\n            this.dgvMain.ShowEditingIcon = false;\n            this.dgvMain.Size = new System.Drawing.Size(800, 430);\n            this.dgvMain.TabIndex = 0;\n            this.dgvMain.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dgvMain_CellDoubleClick);\n            // \n            // txtFilter\n            // \n            this.txtFilter.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.txtFilter.Location = new System.Drawing.Point(0, 0);\n            this.txtFilter.Name = \"txtFilter\";\n            this.txtFilter.Size = new System.Drawing.Size(800, 20);\n            this.txtFilter.TabIndex = 3;\n            this.txtFilter.TextChanged += new System.EventHandler(this.txtFilter_TextChanged);\n            // \n            // GenericPicker\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(800, 450);\n            this.Controls.Add(this.txtFilter);\n            this.Controls.Add(this.dgvMain);\n            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow;\n            this.Name = \"GenericPicker\";\n            this.ShowIcon = false;\n            this.ShowInTaskbar = false;\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\n            this.Text = \"Select an item..\";\n            this.Load += new System.EventHandler(this.GenericPicker_Load);\n            ((System.ComponentModel.ISupportInitialize)(this.dgvMain)).EndInit();\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.DataGridView dgvMain;\n        private System.Windows.Forms.TextBox txtFilter;\n    }\n}"
  },
  {
    "path": "Caesar/Diogenes/Forms/GenericPicker.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\n\nnamespace Diogenes\n{\n    public partial class GenericPicker : Form\n    {\n        private string[][] Table;\n        private string[] Headers;\n        public string[] SelectedResult;\n        public int SelectedRowIndex = -1;\n        public int FilterColumnIndex;\n\n        public GenericPicker(string[][] table, string[] headers, int filterColumn = 0, bool allowMultiSelect = false)\n        {\n            InitializeComponent();\n            Table = table;\n            Headers = headers;\n            FilterColumnIndex = filterColumn;\n            dgvMain.MultiSelect = allowMultiSelect;\n        }\n\n        private void PresentRows()\n        {\n            DataTable dt = new DataTable();\n            string namePartialMatch = txtFilter.Text.ToLower();\n\n            dt.Columns.Add(\"Index\", typeof(int));\n            foreach (string header in Headers)\n            {\n                dt.Columns.Add(header, typeof(String));\n            }\n            dgvMain.DataSource = dt;\n\n            for (int i = 0; i < Table.Length; i++)\n            {\n                if (Table[i][FilterColumnIndex].ToLower().Contains(namePartialMatch))\n                {\n                    List<string> row = new List<string>(Table[i]);\n                    row.Insert(0, i.ToString());\n                    dt.Rows.Add(row.ToArray());\n                }\n            }\n\n            for (int i = 1; i < Headers.Length; i++)\n            {\n                dgvMain.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;\n            }\n\n            dgvMain.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;\n            dgvMain.Columns[Headers.Length].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;\n            dgvMain.Columns[0].Visible = false;\n        }\n\n        private void GenericPicker_Load(object sender, EventArgs e)\n        {\n            UnmanagedUtility.SendMessage(txtFilter.Handle, UnmanagedUtility.EM_SETCUEBANNER, 0, \"Type here to filter results\");\n            PresentRows();\n        }\n\n        private void dgvMain_CellDoubleClick(object sender, DataGridViewCellEventArgs e)\n        {\n            if (dgvMain.SelectedRows.Count == 1)\n            {\n                int selectedRowIndex = int.Parse(dgvMain.SelectedRows[0].Cells[0].Value.ToString());\n                SelectedResult = Table[selectedRowIndex];\n                SelectedRowIndex = selectedRowIndex;\n                this.DialogResult = DialogResult.OK;\n                this.Close();\n            }\n        }\n\n        private void txtFilter_TextChanged(object sender, EventArgs e)\n        {\n            PresentRows();\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/Forms/GenericPicker.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "Caesar/Diogenes/Forms/MainForm.Designer.cs",
    "content": "﻿namespace Diogenes\n{\n    partial class MainForm\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.components = new System.ComponentModel.Container();\n            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));\n            this.statusStrip1 = new System.Windows.Forms.StatusStrip();\n            this.lblConnectionType = new System.Windows.Forms.ToolStripStatusLabel();\n            this.menuStrip1 = new System.Windows.Forms.MenuStrip();\n            this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.loadCBFFilesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.unloadExistingFilesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();\n            this.loadCompressedJsonToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.exportContainerAsCompressedJSONToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.loadJSONToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.exportContainerAsJSONToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator();\n            this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();\n            this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.connectionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.j2534InterfacesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.defaultJ2534InterfaceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.disconnectToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.eCUToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.setSecurityLevelToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.fixClientAccessPermissionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator();\n            this.cFFFlashSplicerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.cFFExportFlashSegmentsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();\n            this.uDSHexEditorToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.diagnosticTroubleCodesDTCToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.viewECUMetadataToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator();\n            this.showTraceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.copyConsoleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.clearConsoleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.identifyECUToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.dSCDebugToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.genericDebugToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.listVariantIDsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.downloadBlocksToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.preferencesToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();\n            this.fingerprintModeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.useLastFingerprintToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.customValueToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.sCNModeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.useLastSCNToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.writeZerosVediamoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.allowWriteVariantCodingToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.tvMain = new System.Windows.Forms.TreeView();\n            this.txtLog = new System.Windows.Forms.TextBox();\n            this.splitContainer1 = new System.Windows.Forms.SplitContainer();\n            this.pbResourcePlaceholder = new System.Windows.Forms.PictureBox();\n            this.txtJ2534Input = new System.Windows.Forms.TextBox();\n            this.tmrBlinkConnectionMenu = new System.Windows.Forms.Timer(this.components);\n            this.fixCBFChecksumToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.statusStrip1.SuspendLayout();\n            this.menuStrip1.SuspendLayout();\n            ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();\n            this.splitContainer1.Panel1.SuspendLayout();\n            this.splitContainer1.Panel2.SuspendLayout();\n            this.splitContainer1.SuspendLayout();\n            ((System.ComponentModel.ISupportInitialize)(this.pbResourcePlaceholder)).BeginInit();\n            this.SuspendLayout();\n            // \n            // statusStrip1\n            // \n            this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.lblConnectionType});\n            this.statusStrip1.Location = new System.Drawing.Point(0, 706);\n            this.statusStrip1.Name = \"statusStrip1\";\n            this.statusStrip1.Size = new System.Drawing.Size(1123, 22);\n            this.statusStrip1.TabIndex = 0;\n            this.statusStrip1.Text = \"statusStrip1\";\n            // \n            // lblConnectionType\n            // \n            this.lblConnectionType.Name = \"lblConnectionType\";\n            this.lblConnectionType.Size = new System.Drawing.Size(201, 17);\n            this.lblConnectionType.Text = \"No interface selected (Disconnected)\";\n            // \n            // menuStrip1\n            // \n            this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.fileToolStripMenuItem,\n            this.connectionToolStripMenuItem,\n            this.eCUToolStripMenuItem,\n            this.preferencesToolStripMenuItem1});\n            this.menuStrip1.Location = new System.Drawing.Point(0, 0);\n            this.menuStrip1.Name = \"menuStrip1\";\n            this.menuStrip1.RenderMode = System.Windows.Forms.ToolStripRenderMode.System;\n            this.menuStrip1.Size = new System.Drawing.Size(1123, 24);\n            this.menuStrip1.TabIndex = 1;\n            this.menuStrip1.Text = \"menuStrip1\";\n            // \n            // fileToolStripMenuItem\n            // \n            this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.loadCBFFilesToolStripMenuItem,\n            this.unloadExistingFilesToolStripMenuItem,\n            this.toolStripSeparator1,\n            this.loadCompressedJsonToolStripMenuItem,\n            this.exportContainerAsCompressedJSONToolStripMenuItem,\n            this.loadJSONToolStripMenuItem,\n            this.exportContainerAsJSONToolStripMenuItem,\n            this.toolStripSeparator6,\n            this.aboutToolStripMenuItem,\n            this.toolStripSeparator2,\n            this.exitToolStripMenuItem});\n            this.fileToolStripMenuItem.Name = \"fileToolStripMenuItem\";\n            this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);\n            this.fileToolStripMenuItem.Text = \"File\";\n            // \n            // loadCBFFilesToolStripMenuItem\n            // \n            this.loadCBFFilesToolStripMenuItem.Name = \"loadCBFFilesToolStripMenuItem\";\n            this.loadCBFFilesToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O)));\n            this.loadCBFFilesToolStripMenuItem.Size = new System.Drawing.Size(277, 22);\n            this.loadCBFFilesToolStripMenuItem.Text = \"Load CBF Files\";\n            this.loadCBFFilesToolStripMenuItem.Click += new System.EventHandler(this.loadCBFFilesToolStripMenuItem_Click);\n            // \n            // unloadExistingFilesToolStripMenuItem\n            // \n            this.unloadExistingFilesToolStripMenuItem.Name = \"unloadExistingFilesToolStripMenuItem\";\n            this.unloadExistingFilesToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift) \n            | System.Windows.Forms.Keys.U)));\n            this.unloadExistingFilesToolStripMenuItem.Size = new System.Drawing.Size(277, 22);\n            this.unloadExistingFilesToolStripMenuItem.Text = \"Unload Existing Files\";\n            this.unloadExistingFilesToolStripMenuItem.Click += new System.EventHandler(this.unloadExistingFilesToolStripMenuItem_Click);\n            // \n            // toolStripSeparator1\n            // \n            this.toolStripSeparator1.Name = \"toolStripSeparator1\";\n            this.toolStripSeparator1.Size = new System.Drawing.Size(274, 6);\n            // \n            // loadCompressedJsonToolStripMenuItem\n            // \n            this.loadCompressedJsonToolStripMenuItem.Name = \"loadCompressedJsonToolStripMenuItem\";\n            this.loadCompressedJsonToolStripMenuItem.Size = new System.Drawing.Size(277, 22);\n            this.loadCompressedJsonToolStripMenuItem.Text = \"Load Compressed JSON\";\n            this.loadCompressedJsonToolStripMenuItem.Click += new System.EventHandler(this.loadCompressedJsonToolStripMenuItem_Click);\n            // \n            // exportContainerAsCompressedJSONToolStripMenuItem\n            // \n            this.exportContainerAsCompressedJSONToolStripMenuItem.Name = \"exportContainerAsCompressedJSONToolStripMenuItem\";\n            this.exportContainerAsCompressedJSONToolStripMenuItem.Size = new System.Drawing.Size(277, 22);\n            this.exportContainerAsCompressedJSONToolStripMenuItem.Text = \"Export Container as Compressed JSON\";\n            this.exportContainerAsCompressedJSONToolStripMenuItem.Click += new System.EventHandler(this.exportContainerAsCompressedJSONToolStripMenuItem_Click);\n            // \n            // loadJSONToolStripMenuItem\n            // \n            this.loadJSONToolStripMenuItem.Name = \"loadJSONToolStripMenuItem\";\n            this.loadJSONToolStripMenuItem.Size = new System.Drawing.Size(277, 22);\n            this.loadJSONToolStripMenuItem.Text = \"Load JSON\";\n            this.loadJSONToolStripMenuItem.Click += new System.EventHandler(this.loadJSONToolStripMenuItem_Click);\n            // \n            // exportContainerAsJSONToolStripMenuItem\n            // \n            this.exportContainerAsJSONToolStripMenuItem.Name = \"exportContainerAsJSONToolStripMenuItem\";\n            this.exportContainerAsJSONToolStripMenuItem.Size = new System.Drawing.Size(277, 22);\n            this.exportContainerAsJSONToolStripMenuItem.Text = \"Export Container as JSON\";\n            this.exportContainerAsJSONToolStripMenuItem.Click += new System.EventHandler(this.exportContainerAsJSONToolStripMenuItem_Click);\n            // \n            // toolStripSeparator6\n            // \n            this.toolStripSeparator6.Name = \"toolStripSeparator6\";\n            this.toolStripSeparator6.Size = new System.Drawing.Size(274, 6);\n            // \n            // aboutToolStripMenuItem\n            // \n            this.aboutToolStripMenuItem.Name = \"aboutToolStripMenuItem\";\n            this.aboutToolStripMenuItem.Size = new System.Drawing.Size(277, 22);\n            this.aboutToolStripMenuItem.Text = \"About..\";\n            this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click);\n            // \n            // toolStripSeparator2\n            // \n            this.toolStripSeparator2.Name = \"toolStripSeparator2\";\n            this.toolStripSeparator2.Size = new System.Drawing.Size(274, 6);\n            // \n            // exitToolStripMenuItem\n            // \n            this.exitToolStripMenuItem.Name = \"exitToolStripMenuItem\";\n            this.exitToolStripMenuItem.Size = new System.Drawing.Size(277, 22);\n            this.exitToolStripMenuItem.Text = \"Exit\";\n            this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);\n            // \n            // connectionToolStripMenuItem\n            // \n            this.connectionToolStripMenuItem.BackColor = System.Drawing.SystemColors.Control;\n            this.connectionToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.j2534InterfacesToolStripMenuItem,\n            this.disconnectToolStripMenuItem});\n            this.connectionToolStripMenuItem.ForeColor = System.Drawing.SystemColors.ControlText;\n            this.connectionToolStripMenuItem.Name = \"connectionToolStripMenuItem\";\n            this.connectionToolStripMenuItem.Size = new System.Drawing.Size(81, 20);\n            this.connectionToolStripMenuItem.Text = \"Connection\";\n            this.connectionToolStripMenuItem.DropDownOpening += new System.EventHandler(this.connectionToolStripMenuItem_DropDownOpening);\n            // \n            // j2534InterfacesToolStripMenuItem\n            // \n            this.j2534InterfacesToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.defaultJ2534InterfaceToolStripMenuItem});\n            this.j2534InterfacesToolStripMenuItem.Name = \"j2534InterfacesToolStripMenuItem\";\n            this.j2534InterfacesToolStripMenuItem.Size = new System.Drawing.Size(156, 22);\n            this.j2534InterfacesToolStripMenuItem.Text = \"J2534 Interfaces\";\n            this.j2534InterfacesToolStripMenuItem.DropDownOpening += new System.EventHandler(this.j2534InterfacesToolStripMenuItem_DropDownOpening);\n            // \n            // defaultJ2534InterfaceToolStripMenuItem\n            // \n            this.defaultJ2534InterfaceToolStripMenuItem.Name = \"defaultJ2534InterfaceToolStripMenuItem\";\n            this.defaultJ2534InterfaceToolStripMenuItem.Size = new System.Drawing.Size(192, 22);\n            this.defaultJ2534InterfaceToolStripMenuItem.Text = \"Default J2534 Interface\";\n            // \n            // disconnectToolStripMenuItem\n            // \n            this.disconnectToolStripMenuItem.Name = \"disconnectToolStripMenuItem\";\n            this.disconnectToolStripMenuItem.Size = new System.Drawing.Size(156, 22);\n            this.disconnectToolStripMenuItem.Text = \"Disconnect\";\n            this.disconnectToolStripMenuItem.Click += new System.EventHandler(this.disconnectToolStripMenuItem_Click);\n            // \n            // eCUToolStripMenuItem\n            // \n            this.eCUToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.setSecurityLevelToolStripMenuItem,\n            this.fixClientAccessPermissionsToolStripMenuItem,\n            this.toolStripSeparator4,\n            this.cFFFlashSplicerToolStripMenuItem,\n            this.cFFExportFlashSegmentsToolStripMenuItem,\n            this.toolStripSeparator3,\n            this.uDSHexEditorToolStripMenuItem,\n            this.diagnosticTroubleCodesDTCToolStripMenuItem,\n            this.viewECUMetadataToolStripMenuItem,\n            this.toolStripSeparator5,\n            this.showTraceToolStripMenuItem,\n            this.copyConsoleToolStripMenuItem,\n            this.clearConsoleToolStripMenuItem,\n            this.identifyECUToolStripMenuItem,\n            this.dSCDebugToolStripMenuItem,\n            this.genericDebugToolStripMenuItem,\n            this.listVariantIDsToolStripMenuItem,\n            this.downloadBlocksToolStripMenuItem,\n            this.fixCBFChecksumToolStripMenuItem});\n            this.eCUToolStripMenuItem.Name = \"eCUToolStripMenuItem\";\n            this.eCUToolStripMenuItem.Size = new System.Drawing.Size(46, 20);\n            this.eCUToolStripMenuItem.Text = \"Tools\";\n            // \n            // setSecurityLevelToolStripMenuItem\n            // \n            this.setSecurityLevelToolStripMenuItem.Name = \"setSecurityLevelToolStripMenuItem\";\n            this.setSecurityLevelToolStripMenuItem.Size = new System.Drawing.Size(239, 22);\n            this.setSecurityLevelToolStripMenuItem.Text = \"Set Security Level (DLL)\";\n            this.setSecurityLevelToolStripMenuItem.Click += new System.EventHandler(this.setSecurityLevelToolStripMenuItem_Click);\n            // \n            // fixClientAccessPermissionsToolStripMenuItem\n            // \n            this.fixClientAccessPermissionsToolStripMenuItem.Name = \"fixClientAccessPermissionsToolStripMenuItem\";\n            this.fixClientAccessPermissionsToolStripMenuItem.Size = new System.Drawing.Size(239, 22);\n            this.fixClientAccessPermissionsToolStripMenuItem.Text = \"Fix Client Access Permissions\";\n            this.fixClientAccessPermissionsToolStripMenuItem.Click += new System.EventHandler(this.fixClientAccessPermissionsToolStripMenuItem_Click);\n            // \n            // toolStripSeparator4\n            // \n            this.toolStripSeparator4.Name = \"toolStripSeparator4\";\n            this.toolStripSeparator4.Size = new System.Drawing.Size(236, 6);\n            // \n            // cFFFlashSplicerToolStripMenuItem\n            // \n            this.cFFFlashSplicerToolStripMenuItem.Name = \"cFFFlashSplicerToolStripMenuItem\";\n            this.cFFFlashSplicerToolStripMenuItem.Size = new System.Drawing.Size(239, 22);\n            this.cFFFlashSplicerToolStripMenuItem.Text = \"CFF: Flash Splicer\";\n            this.cFFFlashSplicerToolStripMenuItem.Click += new System.EventHandler(this.cFFFlashSplicerToolStripMenuItem_Click);\n            // \n            // cFFExportFlashSegmentsToolStripMenuItem\n            // \n            this.cFFExportFlashSegmentsToolStripMenuItem.Name = \"cFFExportFlashSegmentsToolStripMenuItem\";\n            this.cFFExportFlashSegmentsToolStripMenuItem.Size = new System.Drawing.Size(239, 22);\n            this.cFFExportFlashSegmentsToolStripMenuItem.Text = \"CFF: Export Flash Segments\";\n            this.cFFExportFlashSegmentsToolStripMenuItem.Click += new System.EventHandler(this.cFFExportFlashSegmentsToolStripMenuItem_Click);\n            // \n            // toolStripSeparator3\n            // \n            this.toolStripSeparator3.Name = \"toolStripSeparator3\";\n            this.toolStripSeparator3.Size = new System.Drawing.Size(236, 6);\n            // \n            // uDSHexEditorToolStripMenuItem\n            // \n            this.uDSHexEditorToolStripMenuItem.Name = \"uDSHexEditorToolStripMenuItem\";\n            this.uDSHexEditorToolStripMenuItem.Size = new System.Drawing.Size(239, 22);\n            this.uDSHexEditorToolStripMenuItem.Text = \"UDS Hex Editor\";\n            this.uDSHexEditorToolStripMenuItem.Click += new System.EventHandler(this.uDSHexEditorToolStripMenuItem_Click);\n            // \n            // diagnosticTroubleCodesDTCToolStripMenuItem\n            // \n            this.diagnosticTroubleCodesDTCToolStripMenuItem.Name = \"diagnosticTroubleCodesDTCToolStripMenuItem\";\n            this.diagnosticTroubleCodesDTCToolStripMenuItem.Size = new System.Drawing.Size(239, 22);\n            this.diagnosticTroubleCodesDTCToolStripMenuItem.Text = \"Diagnostic Trouble Codes (DTC)\";\n            this.diagnosticTroubleCodesDTCToolStripMenuItem.Click += new System.EventHandler(this.diagnosticTroubleCodesDTCToolStripMenuItem_Click);\n            // \n            // viewECUMetadataToolStripMenuItem\n            // \n            this.viewECUMetadataToolStripMenuItem.Name = \"viewECUMetadataToolStripMenuItem\";\n            this.viewECUMetadataToolStripMenuItem.Size = new System.Drawing.Size(239, 22);\n            this.viewECUMetadataToolStripMenuItem.Text = \"View ECU Metadata\";\n            this.viewECUMetadataToolStripMenuItem.Click += new System.EventHandler(this.viewECUMetadataToolStripMenuItem_Click);\n            // \n            // toolStripSeparator5\n            // \n            this.toolStripSeparator5.Name = \"toolStripSeparator5\";\n            this.toolStripSeparator5.Size = new System.Drawing.Size(236, 6);\n            // \n            // showTraceToolStripMenuItem\n            // \n            this.showTraceToolStripMenuItem.Name = \"showTraceToolStripMenuItem\";\n            this.showTraceToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.Q)));\n            this.showTraceToolStripMenuItem.Size = new System.Drawing.Size(239, 22);\n            this.showTraceToolStripMenuItem.Text = \"Show Trace\";\n            this.showTraceToolStripMenuItem.Click += new System.EventHandler(this.showTraceToolStripMenuItem_Click);\n            // \n            // copyConsoleToolStripMenuItem\n            // \n            this.copyConsoleToolStripMenuItem.Name = \"copyConsoleToolStripMenuItem\";\n            this.copyConsoleToolStripMenuItem.Size = new System.Drawing.Size(239, 22);\n            this.copyConsoleToolStripMenuItem.Text = \"Copy Console\";\n            this.copyConsoleToolStripMenuItem.Click += new System.EventHandler(this.copyConsoleToolStripMenuItem_Click);\n            // \n            // clearConsoleToolStripMenuItem\n            // \n            this.clearConsoleToolStripMenuItem.Name = \"clearConsoleToolStripMenuItem\";\n            this.clearConsoleToolStripMenuItem.Size = new System.Drawing.Size(239, 22);\n            this.clearConsoleToolStripMenuItem.Text = \"Clear Console\";\n            this.clearConsoleToolStripMenuItem.Click += new System.EventHandler(this.clearConsoleToolStripMenuItem_Click);\n            // \n            // identifyECUToolStripMenuItem\n            // \n            this.identifyECUToolStripMenuItem.Name = \"identifyECUToolStripMenuItem\";\n            this.identifyECUToolStripMenuItem.Size = new System.Drawing.Size(239, 22);\n            this.identifyECUToolStripMenuItem.Text = \"Identify ECU\";\n            this.identifyECUToolStripMenuItem.Visible = false;\n            this.identifyECUToolStripMenuItem.Click += new System.EventHandler(this.identifyECUToolStripMenuItem_Click);\n            // \n            // dSCDebugToolStripMenuItem\n            // \n            this.dSCDebugToolStripMenuItem.Name = \"dSCDebugToolStripMenuItem\";\n            this.dSCDebugToolStripMenuItem.Size = new System.Drawing.Size(239, 22);\n            this.dSCDebugToolStripMenuItem.Text = \"DSC Debug\";\n            this.dSCDebugToolStripMenuItem.Visible = false;\n            this.dSCDebugToolStripMenuItem.Click += new System.EventHandler(this.dSCDebugToolStripMenuItem_Click);\n            // \n            // genericDebugToolStripMenuItem\n            // \n            this.genericDebugToolStripMenuItem.Name = \"genericDebugToolStripMenuItem\";\n            this.genericDebugToolStripMenuItem.Size = new System.Drawing.Size(239, 22);\n            this.genericDebugToolStripMenuItem.Text = \"Generic Debug Button\";\n            this.genericDebugToolStripMenuItem.Click += new System.EventHandler(this.genericDebugToolStripMenuItem_Click);\n            // \n            // listVariantIDsToolStripMenuItem\n            // \n            this.listVariantIDsToolStripMenuItem.Name = \"listVariantIDsToolStripMenuItem\";\n            this.listVariantIDsToolStripMenuItem.Size = new System.Drawing.Size(239, 22);\n            this.listVariantIDsToolStripMenuItem.Text = \"List Variant IDs\";\n            this.listVariantIDsToolStripMenuItem.Click += new System.EventHandler(this.listVariantIDsToolStripMenuItem_Click);\n            // \n            // downloadBlocksToolStripMenuItem\n            // \n            this.downloadBlocksToolStripMenuItem.Name = \"downloadBlocksToolStripMenuItem\";\n            this.downloadBlocksToolStripMenuItem.Size = new System.Drawing.Size(239, 22);\n            this.downloadBlocksToolStripMenuItem.Text = \"Download Blocks\";\n            this.downloadBlocksToolStripMenuItem.Click += new System.EventHandler(this.downloadBlocksToolStripMenuItem_Click);\n            // \n            // preferencesToolStripMenuItem1\n            // \n            this.preferencesToolStripMenuItem1.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.fingerprintModeToolStripMenuItem,\n            this.sCNModeToolStripMenuItem,\n            this.allowWriteVariantCodingToolStripMenuItem});\n            this.preferencesToolStripMenuItem1.Name = \"preferencesToolStripMenuItem1\";\n            this.preferencesToolStripMenuItem1.Size = new System.Drawing.Size(80, 20);\n            this.preferencesToolStripMenuItem1.Text = \"Preferences\";\n            this.preferencesToolStripMenuItem1.DropDownOpening += new System.EventHandler(this.preferencesToolStripMenuItem1_DropDownOpening);\n            // \n            // fingerprintModeToolStripMenuItem\n            // \n            this.fingerprintModeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.useLastFingerprintToolStripMenuItem,\n            this.customValueToolStripMenuItem});\n            this.fingerprintModeToolStripMenuItem.Name = \"fingerprintModeToolStripMenuItem\";\n            this.fingerprintModeToolStripMenuItem.Size = new System.Drawing.Size(216, 22);\n            this.fingerprintModeToolStripMenuItem.Text = \"Fingerprint Mode\";\n            // \n            // useLastFingerprintToolStripMenuItem\n            // \n            this.useLastFingerprintToolStripMenuItem.Name = \"useLastFingerprintToolStripMenuItem\";\n            this.useLastFingerprintToolStripMenuItem.Size = new System.Drawing.Size(178, 22);\n            this.useLastFingerprintToolStripMenuItem.Text = \"Use Last Fingerprint\";\n            this.useLastFingerprintToolStripMenuItem.Click += new System.EventHandler(this.useLastFingerprintToolStripMenuItem_Click);\n            // \n            // customValueToolStripMenuItem\n            // \n            this.customValueToolStripMenuItem.Name = \"customValueToolStripMenuItem\";\n            this.customValueToolStripMenuItem.Size = new System.Drawing.Size(178, 22);\n            this.customValueToolStripMenuItem.Text = \"Custom Value\";\n            this.customValueToolStripMenuItem.Click += new System.EventHandler(this.customValueToolStripMenuItem_Click);\n            // \n            // sCNModeToolStripMenuItem\n            // \n            this.sCNModeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.useLastSCNToolStripMenuItem,\n            this.writeZerosVediamoToolStripMenuItem});\n            this.sCNModeToolStripMenuItem.Name = \"sCNModeToolStripMenuItem\";\n            this.sCNModeToolStripMenuItem.Size = new System.Drawing.Size(216, 22);\n            this.sCNModeToolStripMenuItem.Text = \"SCN Mode\";\n            // \n            // useLastSCNToolStripMenuItem\n            // \n            this.useLastSCNToolStripMenuItem.Name = \"useLastSCNToolStripMenuItem\";\n            this.useLastSCNToolStripMenuItem.Size = new System.Drawing.Size(191, 22);\n            this.useLastSCNToolStripMenuItem.Text = \"Use Last SCN\";\n            this.useLastSCNToolStripMenuItem.Click += new System.EventHandler(this.useLastSCNToolStripMenuItem_Click);\n            // \n            // writeZerosVediamoToolStripMenuItem\n            // \n            this.writeZerosVediamoToolStripMenuItem.Name = \"writeZerosVediamoToolStripMenuItem\";\n            this.writeZerosVediamoToolStripMenuItem.Size = new System.Drawing.Size(191, 22);\n            this.writeZerosVediamoToolStripMenuItem.Text = \"Write Zeros (Vediamo)\";\n            this.writeZerosVediamoToolStripMenuItem.Click += new System.EventHandler(this.writeZerosVediamoToolStripMenuItem_Click);\n            // \n            // allowWriteVariantCodingToolStripMenuItem\n            // \n            this.allowWriteVariantCodingToolStripMenuItem.Name = \"allowWriteVariantCodingToolStripMenuItem\";\n            this.allowWriteVariantCodingToolStripMenuItem.Size = new System.Drawing.Size(216, 22);\n            this.allowWriteVariantCodingToolStripMenuItem.Text = \"Allow Write Variant Coding\";\n            this.allowWriteVariantCodingToolStripMenuItem.Click += new System.EventHandler(this.allowWriteVariantCodingToolStripMenuItem_Click);\n            // \n            // tvMain\n            // \n            this.tvMain.AllowDrop = true;\n            this.tvMain.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.tvMain.Font = new System.Drawing.Font(\"Segoe UI\", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.tvMain.Location = new System.Drawing.Point(3, 3);\n            this.tvMain.Name = \"tvMain\";\n            this.tvMain.Size = new System.Drawing.Size(1117, 480);\n            this.tvMain.TabIndex = 2;\n            this.tvMain.DragDrop += new System.Windows.Forms.DragEventHandler(this.tvMain_DragDrop);\n            this.tvMain.DragEnter += new System.Windows.Forms.DragEventHandler(this.tvMain_DragEnter);\n            this.tvMain.DoubleClick += new System.EventHandler(this.tvMain_DoubleClick);\n            // \n            // txtLog\n            // \n            this.txtLog.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.txtLog.Font = new System.Drawing.Font(\"Consolas\", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.txtLog.Location = new System.Drawing.Point(3, 3);\n            this.txtLog.Multiline = true;\n            this.txtLog.Name = \"txtLog\";\n            this.txtLog.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;\n            this.txtLog.Size = new System.Drawing.Size(1117, 160);\n            this.txtLog.TabIndex = 3;\n            // \n            // splitContainer1\n            // \n            this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;\n            this.splitContainer1.Location = new System.Drawing.Point(0, 24);\n            this.splitContainer1.Name = \"splitContainer1\";\n            this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;\n            // \n            // splitContainer1.Panel1\n            // \n            this.splitContainer1.Panel1.Controls.Add(this.tvMain);\n            this.splitContainer1.Panel1.Controls.Add(this.pbResourcePlaceholder);\n            // \n            // splitContainer1.Panel2\n            // \n            this.splitContainer1.Panel2.Controls.Add(this.txtJ2534Input);\n            this.splitContainer1.Panel2.Controls.Add(this.txtLog);\n            this.splitContainer1.Size = new System.Drawing.Size(1123, 682);\n            this.splitContainer1.SplitterDistance = 486;\n            this.splitContainer1.TabIndex = 5;\n            // \n            // pbResourcePlaceholder\n            // \n            this.pbResourcePlaceholder.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));\n            this.pbResourcePlaceholder.Image = global::Diogenes.Properties.Resources.report;\n            this.pbResourcePlaceholder.Location = new System.Drawing.Point(1070, 3);\n            this.pbResourcePlaceholder.Name = \"pbResourcePlaceholder\";\n            this.pbResourcePlaceholder.Size = new System.Drawing.Size(50, 50);\n            this.pbResourcePlaceholder.TabIndex = 4;\n            this.pbResourcePlaceholder.TabStop = false;\n            this.pbResourcePlaceholder.Visible = false;\n            // \n            // txtJ2534Input\n            // \n            this.txtJ2534Input.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.txtJ2534Input.Enabled = false;\n            this.txtJ2534Input.Location = new System.Drawing.Point(3, 169);\n            this.txtJ2534Input.Name = \"txtJ2534Input\";\n            this.txtJ2534Input.Size = new System.Drawing.Size(1117, 20);\n            this.txtJ2534Input.TabIndex = 4;\n            this.txtJ2534Input.KeyDown += new System.Windows.Forms.KeyEventHandler(this.txtJ2534Input_KeyDown);\n            // \n            // tmrBlinkConnectionMenu\n            // \n            this.tmrBlinkConnectionMenu.Interval = 60;\n            this.tmrBlinkConnectionMenu.Tick += new System.EventHandler(this.tmrBlinkConnectionMenu_Tick);\n            // \n            // fixCBFChecksumToolStripMenuItem\n            // \n            this.fixCBFChecksumToolStripMenuItem.Name = \"fixCBFChecksumToolStripMenuItem\";\n            this.fixCBFChecksumToolStripMenuItem.Size = new System.Drawing.Size(239, 22);\n            this.fixCBFChecksumToolStripMenuItem.Text = \"Fix CBF Checksum\";\n            this.fixCBFChecksumToolStripMenuItem.Click += new System.EventHandler(this.fixCBFChecksumToolStripMenuItem_Click);\n            // \n            // MainForm\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(1123, 728);\n            this.Controls.Add(this.splitContainer1);\n            this.Controls.Add(this.statusStrip1);\n            this.Controls.Add(this.menuStrip1);\n            this.Icon = ((System.Drawing.Icon)(resources.GetObject(\"$this.Icon\")));\n            this.MainMenuStrip = this.menuStrip1;\n            this.Name = \"MainForm\";\n            this.Text = \"Diogenes\";\n            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing);\n            this.Load += new System.EventHandler(this.MainForm_Load);\n            this.statusStrip1.ResumeLayout(false);\n            this.statusStrip1.PerformLayout();\n            this.menuStrip1.ResumeLayout(false);\n            this.menuStrip1.PerformLayout();\n            this.splitContainer1.Panel1.ResumeLayout(false);\n            this.splitContainer1.Panel2.ResumeLayout(false);\n            this.splitContainer1.Panel2.PerformLayout();\n            ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();\n            this.splitContainer1.ResumeLayout(false);\n            ((System.ComponentModel.ISupportInitialize)(this.pbResourcePlaceholder)).EndInit();\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.StatusStrip statusStrip1;\n        private System.Windows.Forms.MenuStrip menuStrip1;\n        private System.Windows.Forms.ToolStripStatusLabel lblConnectionType;\n        private System.Windows.Forms.TreeView tvMain;\n        private System.Windows.Forms.TextBox txtLog;\n        private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem loadCBFFilesToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem unloadExistingFilesToolStripMenuItem;\n        private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;\n        private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;\n        private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem connectionToolStripMenuItem;\n        private System.Windows.Forms.PictureBox pbResourcePlaceholder;\n        private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem eCUToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem setSecurityLevelToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem j2534InterfacesToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem defaultJ2534InterfaceToolStripMenuItem;\n        private System.Windows.Forms.SplitContainer splitContainer1;\n        private System.Windows.Forms.TextBox txtJ2534Input;\n        private System.Windows.Forms.ToolStripMenuItem cFFExportFlashSegmentsToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem fixClientAccessPermissionsToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem cFFFlashSplicerToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem showTraceToolStripMenuItem;\n        private System.Windows.Forms.ToolStripSeparator toolStripSeparator3;\n        private System.Windows.Forms.ToolStripMenuItem clearConsoleToolStripMenuItem;\n        private System.Windows.Forms.ToolStripSeparator toolStripSeparator4;\n        private System.Windows.Forms.Timer tmrBlinkConnectionMenu;\n        private System.Windows.Forms.ToolStripMenuItem disconnectToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem copyConsoleToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem uDSHexEditorToolStripMenuItem;\n        private System.Windows.Forms.ToolStripSeparator toolStripSeparator5;\n        private System.Windows.Forms.ToolStripMenuItem preferencesToolStripMenuItem1;\n        private System.Windows.Forms.ToolStripMenuItem fingerprintModeToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem useLastFingerprintToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem customValueToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem sCNModeToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem useLastSCNToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem writeZerosVediamoToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem allowWriteVariantCodingToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem diagnosticTroubleCodesDTCToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem viewECUMetadataToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem identifyECUToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem loadCompressedJsonToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem exportContainerAsCompressedJSONToolStripMenuItem;\n        private System.Windows.Forms.ToolStripSeparator toolStripSeparator6;\n        private System.Windows.Forms.ToolStripMenuItem dSCDebugToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem loadJSONToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem exportContainerAsJSONToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem genericDebugToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem listVariantIDsToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem downloadBlocksToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem fixCBFChecksumToolStripMenuItem;\n    }\n}\n\n"
  },
  {
    "path": "Caesar/Diogenes/Forms/MainForm.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\nusing Caesar;\nusing System.IO;\nusing Diogenes.Properties;\nusing System.Runtime.InteropServices;\nusing Diogenes.SecurityAccess;\n\nnamespace Diogenes\n{\n    public partial class MainForm : Form\n    {\n        public ECUConnection Connection = null;\n\n        public MainForm()\n        {\n            InitializeComponent();\n        }\n\n        TraceForm TraceFormSingleInstance;\n        List<CaesarContainer> Containers = new List<CaesarContainer>();\n        ImageList treeImages = null;\n        TextboxWriter LogTextbox;\n\n        private void MainForm_Load(object sender, EventArgs e)\n        {\n            RedirectConsole();\n            LoadContainers();\n            UnmanagedUtility.SendMessage(txtJ2534Input.Handle, UnmanagedUtility.EM_SETCUEBANNER, 0, \"J2534 Console : Enter hex values (01 23 45 57) and press enter to send a raw J2534 command\");\n#if (!DEBUG)\n            genericDebugToolStripMenuItem.Visible = false;\n            downloadBlocksToolStripMenuItem.Visible = false;\n#endif\n            SetDisconnectedState(false);\n        }\n\n        private void RedirectConsole()\n        {\n            LogTextbox = new TextboxWriter(txtLog);\n            Console.SetOut(LogTextbox);\n        }\n\n        private void LoadContainers()\n        {\n            Containers.Clear();\n            foreach (string file in Directory.GetFiles(Application.StartupPath))\n            {\n                if (Path.GetExtension(file).ToLower() == \".cbf\")\n                {\n                    CaesarContainer cbfContainer = new CaesarContainer(File.ReadAllBytes(file));\n                    Containers.Add(cbfContainer);\n                    //PostInitDebug(cbfContainer);\n                }\n            }\n            LoadTree();\n        }\n\n        private void PostInitDebug(CaesarContainer cbfContainer) \n        {\n        }\n\n        private void InitializeTree()\n        {\n            if (treeImages is null)\n            {\n                treeImages = new ImageList();\n                treeImages.Images.Add(Resources.blank); // 0\n                treeImages.Images.Add(Resources.box);\n                treeImages.Images.Add(Resources.brick);\n                treeImages.Images.Add(Resources.cog);\n                treeImages.Images.Add(Resources.house);\n                treeImages.Images.Add(Resources.connect);\n                treeImages.Images.Add(Resources.information); // 6\n\n                treeImages.Images.Add(Resources.bullet_go); // 7\n                treeImages.Images.Add(Resources.bullet_star);\n\n                treeImages.Images.Add(Resources.bullet_black); // 9\n                treeImages.Images.Add(Resources.bullet_blue);\n                treeImages.Images.Add(Resources.bullet_green);\n                treeImages.Images.Add(Resources.bullet_orange);\n                treeImages.Images.Add(Resources.bullet_pink);\n                treeImages.Images.Add(Resources.bullet_purple);\n                treeImages.Images.Add(Resources.bullet_red);\n                treeImages.Images.Add(Resources.bullet_white);\n                treeImages.Images.Add(Resources.bullet_yellow); // 17\n\n                treeImages.Images.Add(Resources.computer_go); // 18\n                treeImages.Images.Add(Resources.lock_edit); // 19\n                treeImages.Images.Add(Resources.key); // 20\n                treeImages.Images.Add(Resources.application_xp_terminal); // 21\n                treeImages.Images.Add(Resources.page_white_edit); // 22\n\n                treeImages.Images.Add(Resources.asterisk_orange); // 23\n                treeImages.Images.Add(Resources.folder); // 24\n                treeImages.Images.Add(Resources.accept); // 25\n                treeImages.Images.Add(Resources.report); // 26\n\n                tvMain.ImageList = treeImages;\n\n                UnmanagedUtility.SendMessage(tvMain.Handle, UnmanagedUtility.TVM_SETEXTENDEDSTYLE, (IntPtr)UnmanagedUtility.TVS_EX_DOUBLEBUFFER, (IntPtr)UnmanagedUtility.TVS_EX_DOUBLEBUFFER);\n            }\n        }\n\n        private void AddDiagServicesToNode(TreeNode parentNode, ECUVariant variant)\n        {\n\n            string newTag = $\"Exec{nameof(DiagService)}:{variant.Qualifier}\";\n\n            TreeNode diagUnlockingOptions = new TreeNode($\"Security Access\", 19, 19);\n            diagUnlockingOptions.Tag = newTag;\n\n            TreeNode diagStoredData = new TreeNode($\"Diagnostics: Stored Data\", 24, 24);\n            diagStoredData.Tag = newTag;\n\n            TreeNode diagData = new TreeNode($\"Diagnostics: Data\", 24, 24);\n            diagData.Tag = newTag;\n\n            TreeNode diagFunction = new TreeNode($\"Diagnostics: Function\", 24, 24);\n            diagFunction.Tag = newTag;\n\n            TreeNode diagRoutine = new TreeNode($\"Diagnostics: Routine\", 24, 24);\n            diagRoutine.Tag = newTag;\n\n            TreeNode diagIO = new TreeNode($\"Diagnostics: IO\", 24, 24);\n            diagIO.Tag = newTag;\n\n            TreeNode diagDownload = new TreeNode($\"Diagnostics: Download\", 24, 24);\n            diagDownload.Tag = newTag;\n\n\n            for (int i = 0; i < variant.DiagServices.Length; i++)\n            {\n                DiagService currentDiagService = variant.DiagServices[i];\n\n                TreeNode diagNode = new TreeNode(currentDiagService.Qualifier, 9, 9);\n                diagNode.Tag = i.ToString();\n\n                if ((currentDiagService.RequestBytes.Length > 1) && (currentDiagService.RequestBytes[0] == 0x27))\n                {\n                    diagUnlockingOptions.Nodes.Add(diagNode);\n                    continue;\n                }\n\n                if (currentDiagService.DataClass_ServiceType == (int)DiagService.ServiceType.StoredData)\n                {\n                    diagStoredData.Nodes.Add(diagNode);\n                }\n                else if (currentDiagService.DataClass_ServiceType == (int)DiagService.ServiceType.DiagnosticFunction)\n                {\n                    diagFunction.Nodes.Add(diagNode);\n                }\n                else if (currentDiagService.DataClass_ServiceType == (int)DiagService.ServiceType.Data)\n                {\n                    diagData.Nodes.Add(diagNode);\n                }\n                else if (currentDiagService.DataClass_ServiceType == (int)DiagService.ServiceType.Routine)\n                {\n                    diagRoutine.Nodes.Add(diagNode);\n                }\n                else if (currentDiagService.DataClass_ServiceType == (int)DiagService.ServiceType.IoControl)\n                {\n                    diagIO.Nodes.Add(diagNode);\n                }\n                else if (currentDiagService.DataClass_ServiceType == (int)DiagService.ServiceType.Download)\n                {\n                    diagDownload.Nodes.Add(diagNode);\n                }\n            }\n\n            parentNode.Nodes.Add(diagUnlockingOptions);\n            parentNode.Nodes.Add(diagStoredData);\n            parentNode.Nodes.Add(diagData);\n            parentNode.Nodes.Add(diagFunction);\n            parentNode.Nodes.Add(diagRoutine);\n            parentNode.Nodes.Add(diagIO);\n            parentNode.Nodes.Add(diagDownload);\n        }\n\n\n        private void AddEcuMetadataToNode(TreeNode parentNode, CaesarContainer container, ECU ecu)\n        {\n            TreeNode rootMetadata = new TreeNode(\"Metadata\", 26, 26);\n            rootMetadata.Tag = $\"RootMetadata\";\n\n            TreeNode metadataRowNode;\n\n            metadataRowNode = new TreeNode($\"Container File Size: {container.GetFileSize()}\", 9, 9);\n            metadataRowNode.Tag = \"RootMetadataEntry\";\n            rootMetadata.Nodes.Add(metadataRowNode);\n\n            metadataRowNode = new TreeNode($\"Container Checksum: {container.FileChecksum:X8}\", 9, 9);\n            metadataRowNode.Tag = \"RootMetadataEntry\";\n            rootMetadata.Nodes.Add(metadataRowNode);\n\n            metadataRowNode = new TreeNode($\"CBF Version: {container.CaesarCFFHeader.CbfVersionString}\", 9, 9);\n            metadataRowNode.Tag = \"RootMetadataEntry\";\n            rootMetadata.Nodes.Add(metadataRowNode);\n\n            metadataRowNode = new TreeNode($\"GPD Version: {container.CaesarCFFHeader.GpdVersionString}\", 9, 9);\n            metadataRowNode.Tag = \"RootMetadataEntry\";\n            rootMetadata.Nodes.Add(metadataRowNode);\n\n            metadataRowNode = new TreeNode($\"ECU Version: {ecu.EcuXmlVersion}\", 9, 9);\n            metadataRowNode.Tag = \"RootMetadataEntry\";\n            rootMetadata.Nodes.Add(metadataRowNode);\n\n            metadataRowNode = new TreeNode($\"ECU Ignition Required: {ecu.IgnitionRequired}\", 9, 9);\n            metadataRowNode.Tag = \"RootMetadataEntry\";\n            rootMetadata.Nodes.Add(metadataRowNode);\n\n\n            parentNode.Nodes.Add(rootMetadata);\n        }\n\n        private void LoadTree()\n        {\n            InitializeTree();\n            tvMain.Nodes.Clear();\n\n            foreach (CaesarContainer container in Containers)\n            {\n                foreach (ECU ecu in container.CaesarECUs)\n                {\n                    TreeNode ecuNode = new TreeNode(ecu.Qualifier, 1, 1);\n                    ecuNode.Tag = nameof(ECU);\n\n                    TreeNode execDiagAtRoot = new TreeNode(\"Execute Diagnostic Service (Root)\", 21, 21);\n                    execDiagAtRoot.Tag = $\"{nameof(DiagService)}:{nameof(ECU)}:{ecu.Qualifier}\";\n                    ecuNode.Nodes.Add(execDiagAtRoot);\n\n                    AddEcuMetadataToNode(ecuNode, container, ecu);\n\n                    foreach (ECUInterfaceSubtype subtype in ecu.ECUInterfaceSubtypes)\n                    {\n                        if (Connection?.VariantIsAvailable ?? false)\n                        {\n                            // interfaces don't matter anymore when we are connected\n                            break;\n                        }\n                        TreeNode interfaceNode = new TreeNode(subtype.Qualifier, 5, 5);\n                        interfaceNode.Tag = \"\";\n\n                        TreeNode initiateContactNode = new TreeNode(\"Initiate Contact\", 18, 18);\n                        initiateContactNode.Tag = $\"{nameof(ECUInterfaceSubtype)}:{subtype.Qualifier}\";\n                        interfaceNode.Nodes.Add(initiateContactNode);\n\n                        TreeNode comparamParentNode = new TreeNode(\"Communications Parameters\", 6, 6);\n                        comparamParentNode.Tag = $\"ComParamParent\";\n\n                        foreach (ComParameter parameter in subtype.CommunicationParameters)\n                        {\n                            TreeNode comNode = new TreeNode($\"{parameter.ParamName} : {parameter.ComParamValue} (0x{parameter.ComParamValue:X})\", 9, 9);\n                            // Console.WriteLine(comNode.Text);\n                            comNode.Tag = nameof(ComParameter);\n                            comparamParentNode.Nodes.Add(comNode);\n                        }\n                        interfaceNode.Nodes.Add(comparamParentNode);\n\n                        ecuNode.Nodes.Add(interfaceNode);\n                        interfaceNode.Expand();\n                    }\n\n                    // offer the ability to switch sessions at all times, in case user runs functions like FN_Reset\n                    TreeNode sessionContainer = new TreeNode(\"Session\", 23, 23);\n                    sessionContainer.Tag = $\"Session\";\n                    foreach (DiagService ds in ecu.GlobalDiagServices)\n                    {\n                        if (ds.DataClass_ServiceType == (ushort)DiagService.ServiceType.Session)\n                        {\n                            TreeNode dsNode = new TreeNode(ds.Qualifier, 12, 12);\n                            dsNode.Tag = ds.Qualifier;\n                            sessionContainer.Nodes.Add(dsNode);\n                        }\n                    }\n                    ecuNode.Nodes.Add(sessionContainer);\n\n                    foreach (ECUVariant variant in ecu.ECUVariants)\n                    {\n                        TreeNode ecuVariantNode = new TreeNode(variant.Qualifier, 2, 2);\n                        ecuVariantNode.Tag = nameof(ECUVariant);\n\n                        // check if variant should be filtered\n                        if (Connection?.VariantIsAvailable ?? false) \n                        {\n                            bool foundCorrectVariant = false;\n                            foreach (ECUVariantPattern pattern in variant.VariantPatterns) \n                            {\n                                if (pattern.VariantID == Connection.ECUVariantID) \n                                {\n                                    foundCorrectVariant = true;\n                                    break;\n                                }\n                            }\n                            if (!foundCorrectVariant) \n                            {\n                                continue;\n                            }\n                            ecuVariantNode.ImageIndex = 25;\n                            ecuVariantNode.SelectedImageIndex = 25;\n                            ecuVariantNode.Expand();\n                        }\n\n\n                        // exec diag button\n                        TreeNode execDiagAtVariant = new TreeNode(\"Execute Diagnostic Service\", 21, 21);\n                        execDiagAtVariant.Tag = $\"{nameof(DiagService)}:{nameof(ECUVariant)}:{variant.Qualifier}\";\n                        ecuVariantNode.Nodes.Add(execDiagAtVariant);\n\n                        // metadata\n                        TreeNode metadataNode = new TreeNode($\"Metadata\", 6, 6);\n                        metadataNode.Tag = $\"{nameof(ECUVariant)}Metadata\";\n                        foreach (ECUVariantPattern pattern in variant.VariantPatterns)\n                        {\n                            string vendorText = pattern.PatternType == 3 ? $\", Vendor: {pattern.VendorName}\" : \"\";\n                            TreeNode patternNode = new TreeNode($\"Variant ID: {pattern.VariantID} ({pattern.VariantID:X4}){vendorText}\", 9, 9);\n                            patternNode.Tag = nameof(ECUVariantPattern);\n                            metadataNode.Nodes.Add(patternNode);\n                        }\n\n                        AddDiagServicesToNode(ecuVariantNode, variant);\n\n                        ecuVariantNode.Nodes.Add(metadataNode);\n\n                        // vc domains\n                        foreach (VCDomain domain in variant.VCDomains)\n                        {\n                            TreeNode vcDomainNode = new TreeNode(domain.Qualifier, 3, 3);\n                            vcDomainNode.Tag = nameof(VCDomain);\n                            ecuVariantNode.Nodes.Add(vcDomainNode);\n                        }\n\n                        TreeNode backupNode = new TreeNode(\"Backup Variant Strings\", 3, 3);\n                        backupNode.Tag = \"VCBackup\";\n                        ecuVariantNode.Nodes.Add(backupNode);\n\n                        ecuNode.Nodes.Add(ecuVariantNode);\n                    }\n                    tvMain.Nodes.Add(ecuNode);\n                    ecuNode.Expand();\n                }\n            }\n        }\n\n        private void FixCALs(CaesarContainer container)\n        {\n            int newLevel = 1;\n            byte[] newFile = new byte[container.FileBytes.Length];\n            Buffer.BlockCopy(container.FileBytes, 0, newFile, 0, container.FileBytes.Length);\n\n            Console.WriteLine($\"Creating a new CBF with access level requirements set at {newLevel}\");\n            List<DiagService> dsPendingFix = new List<DiagService>();\n\n            using (BinaryReader reader = new BinaryReader(new MemoryStream(container.FileBytes)))\n            {\n                foreach (ECU ecu in container.CaesarECUs)\n                {\n                    foreach (DiagService ds in ecu.GlobalDiagServices)\n                    {\n                        if (ds.ClientAccessLevel > newLevel)\n                        {\n                            dsPendingFix.Add(ds);\n                            Console.WriteLine($\"-> {ds.Qualifier} (Level {ds.ClientAccessLevel})\");\n                            long fileOffset = ds.GetCALInt16Offset(reader);\n                            if (fileOffset != -1)\n                            {\n                                newFile[fileOffset] = (byte)newLevel;\n                                newFile[fileOffset + 1] = (byte)(newLevel >> 8);\n                            }\n                        }\n                    }\n                }\n                uint checksum = CaesarReader.ComputeFileChecksum(newFile);\n                byte[] checksumBytes = BitConverter.GetBytes(checksum);\n                Array.ConstrainedCopy(checksumBytes, 0, newFile, newFile.Length - 4, checksumBytes.Length);\n            }\n\n            SaveFileDialog sfd = new SaveFileDialog();\n            sfd.Title = \"Specify a location to save your new CBF file\";\n            sfd.Filter = \"CBF files (*.cbf)|*.cbf|All files (*.*)|*.*\";\n            if (sfd.ShowDialog() == DialogResult.OK)\n            {\n                File.WriteAllBytes(sfd.FileName, newFile);\n            }\n        }\n\n        private void TreeViewDoubleClickCheckIfSession(TreeNode node)\n        {\n            if (node.Parent != null && node.Parent.Tag.ToString() == \"Session\")\n            {\n                string ecuName = node.Parent.Parent.Text;\n                string serviceName = node.Tag.ToString();\n\n                foreach (CaesarContainer container in Containers)\n                {\n                    ECU ecu = container.CaesarECUs.Find(x => x.Qualifier == ecuName);\n                    if (ecu != null)\n                    {\n                        DiagService ds = ecu.GlobalDiagServices.Find(x => x.Qualifier == serviceName);\n                        if (ds != null)\n                        {\n                            PresentRunDiagDialog(ds);\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n\n        private void TreeViewDoubleClickCheckIfVariantDiag(TreeNode node)\n        {\n            string validNodePrefix = $\"Exec{nameof(DiagService)}:\";\n\n            if (node.Parent is null)\n            {\n                return;\n            }\n            if (node.Parent.Tag.ToString().StartsWith(validNodePrefix))\n            {\n                string variantName = node.Parent.Tag.ToString().Substring(validNodePrefix.Length);\n\n                ECUVariant foundVariant = null;\n                foreach (CaesarContainer container in Containers)\n                {\n                    foreach (ECU ecu in container.CaesarECUs)\n                    {\n                        foreach (ECUVariant variant in ecu.ECUVariants)\n                        {\n                            if (variant.Qualifier == variantName)\n                            {\n                                foundVariant = variant;\n                            }\n                        }\n                    }\n                }\n                // variant found, exec the diag service\n                if (foundVariant != null)\n                {\n                    DiagService ds = foundVariant.DiagServices[int.Parse(node.Tag.ToString())];\n\n                    bool connectionSupportsUnlocking = Connection?.ConnectionProtocol?.SupportsUnlocking() ?? false;\n\n                    // can we help to skip the modal if the ds doesn't require additional user input? common for data, stored data\n                    if ((ds.DataClass_ServiceType == (int)DiagService.ServiceType.StoredData) || (ds.DataClass_ServiceType == (int)DiagService.ServiceType.Data))\n                    {\n                        Connection?.ExecUserDiagJob(ds.RequestBytes, ds);\n                    }\n                    else if (connectionSupportsUnlocking && (ds.RequestBytes.Length == 2) && (ds.RequestBytes[0] == 0x27))\n                    {\n                        // request seed, no need to prompt\n                        Connection?.ExecUserDiagJob(ds.RequestBytes, ds);\n                    }\n                    else\n                    {\n                        PresentRunDiagDialog(ds);\n                    }\n                }\n            }\n        }\n\n        private void PresentRunDiagDialog(DiagService ds)\n        {\n            RunDiagForm runDiagForm = new RunDiagForm(ds);\n            if (runDiagForm.ShowDialog() == DialogResult.OK)\n            {\n                Connection.ExecUserDiagJob(runDiagForm.Result, ds);\n            }\n        }\n\n\n        private void treeViewSelectVariantCoding(TreeNode node) \n        {\n            string domainName = node.Text;\n            string variantName = node.Parent.Text;\n            string ecuName = node.Parent.Parent.Text;\n\n            Console.WriteLine($\"Starting VC Dialog for {ecuName} ({variantName}) with domain as {domainName}\");\n            CaesarContainer container = Containers.Find(x => x.GetECUVariantByName(variantName) != null);\n\n            // prompt the user for vc changes via VCForm\n            VCForm vcForm = new VCForm(container, ecuName, variantName, domainName, Connection);\n            if (vcForm.ShowDialog() == DialogResult.OK)\n            {\n                VariantCoding.DoVariantCoding(Connection, vcForm, allowWriteVariantCodingToolStripMenuItem.Checked);\n            }\n        }\n\n        private void tvMain_DoubleClick(object sender, EventArgs e)\n        {\n            TreeNode node = tvMain.SelectedNode;\n            if (node is null)\n            {\n                return;\n            }\n\n            if (node.Tag.ToString() == nameof(VCDomain))\n            {\n                // variant coding\n                treeViewSelectVariantCoding(node);\n            }\n            else if (node.Tag.ToString() == \"VCBackup\")\n            {\n                // variant coding backup\n                VCReport.treeViewSelectVariantCodingBackup(node, Connection, Containers);\n            }\n            else if (node.Tag.ToString().StartsWith(nameof(ECUInterfaceSubtype)))\n            {\n                // initiate contact\n                string connectionProfileName = node.Tag.ToString().Substring(nameof(ECUInterfaceSubtype).Length + 1);\n                string ecuName = node.Parent.Parent.Text;\n\n                foreach (CaesarContainer container in Containers)\n                {\n                    ECU ecu = container.CaesarECUs.Find(x => x.Qualifier == ecuName);\n                    if (ecu != null)\n                    {\n                        ECUInterfaceSubtype subtype = ecu.ECUInterfaceSubtypes.Find(x => x.Qualifier == connectionProfileName);\n                        if (subtype != null)\n                        {\n                            Console.WriteLine($\"Attempting to open a connection to ({ecuName}) with profile '{connectionProfileName}'\");\n                            ECUConnection.ConnectResponse response = Connection.Connect(subtype, ecu);\n                            if (response == ECUConnection.ConnectResponse.OK)\n                            {\n                                ProtocolPostConnect();\n                            }\n                            else if (response == ECUConnection.ConnectResponse.NoValidInterface)\n                            {\n                                BlinkConnectionMenu();\n                                connectionToolStripMenuItem.ShowDropDown();\n                                j2534InterfacesToolStripMenuItem.ShowDropDown();\n                            }\n                            else \n                            {\n                                // uhoh\n                                Console.WriteLine($\"ECU connection was unsuccessful : {response}\");\n                            }\n                            break;\n                        }\n                    }\n                }\n            }\n            else if (node.Tag.ToString().StartsWith(nameof(DiagService)))\n            {\n                // execute diag service (modal)\n                string diagOrigin = node.Tag.ToString().Substring(nameof(DiagService).Length + 1);\n                string variantName = \"\";\n                string ecuName = \"\";\n\n                if (diagOrigin.StartsWith($\"{nameof(ECUVariant)}:\"))\n                {\n                    variantName = node.Parent.Text;\n                    ecuName = node.Parent.Parent.Text;\n                }\n                else \n                {\n                    ecuName = node.Parent.Text;\n                }\n\n                foreach (CaesarContainer container in Containers)\n                {\n                    ECU ecu = container.CaesarECUs.Find(x => x.Qualifier == ecuName);\n                    if (ecu != null)\n                    {\n                        PickDiagForm picker;\n                        ECUVariant variant = ecu.ECUVariants.Find(x => x.Qualifier == variantName);\n                        if (variant != null)\n                        {\n                            //Console.WriteLine($\"Starting Diagnostic Service picker modal for variant {variantName}\");\n                            picker = new PickDiagForm(variant.DiagServices);\n                        }\n                        else\n                        {\n                            //Console.WriteLine($\"Starting Diagnostic Service picker modal for root {ecuName}\");\n                            picker = new PickDiagForm(ecu.GlobalDiagServices.ToArray());\n                        }\n                        if (picker.ShowDialog() == DialogResult.OK) \n                        {\n                            PresentRunDiagDialog(picker.SelectedDiagService);\n                        }\n                        break;\n                    }\n                }\n            }\n            TreeViewDoubleClickCheckIfSession(node);\n            TreeViewDoubleClickCheckIfVariantDiag(node);\n        }\n\n        private void ProtocolPostConnect()\n        {\n            if (Connection.ConnectionProtocol != null) \n            {\n                Connection.ConnectionProtocol.ConnectionEstablishedHandler(Connection);\n                LoadTree();\n            }\n        }\n\n        private void ShowAbout() \n        {\n            AboutForm about = new AboutForm($\"Diogenes {GetVersion()} (Caesar {CaesarContainer.GetCaesarVersionString()})\");\n            about.ShowDialog();\n        }\n        public static string GetVersion()\n        {\n            System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();\n            System.Diagnostics.FileVersionInfo fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(assembly.Location);\n            return fvi.FileVersion;\n        }\n\n        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            ShowAbout();\n        }\n\n        private void exitToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            Application.Exit();\n        }\n\n        private void unloadExistingFilesToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            Containers.Clear();\n            LoadTree();\n        }\n\n        private void loadCBFFilesToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            OpenFileDialog ofd = new OpenFileDialog();\n            ofd.Title = \"Select a CBF File\";\n            ofd.Filter = \"CBF files (*.cbf)|*.cbf|All files (*.*)|*.*\";\n            ofd.Multiselect = false;\n            if (ofd.ShowDialog() == DialogResult.OK) \n            {\n                TryLoadFile(ofd.FileName);\n            }\n        }\n\n        private void TryLoadFile(string fileName)\n        {\n            byte[] fileBytes = File.ReadAllBytes(fileName);\n            if (CaesarContainer.VerifyChecksum(fileBytes, out uint checksum))\n            {\n                Containers.Add(new CaesarContainer(fileBytes));\n                LoadTree();\n            }\n            else \n            {\n                Console.WriteLine($\"File {Path.GetFileName(fileName)} was not loaded as the checksum is invalid\");\n            }\n        }\n\n        private void setSecurityLevelToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            OpenFileDialog ofd = new OpenFileDialog();\n            ofd.Title = \"Select a Security DLL File\";\n            ofd.Filter = \"DLL files (*.dll)|*.dll|All files (*.*)|*.*\";\n            ofd.Multiselect = false;\n            if (ofd.ShowDialog() == DialogResult.OK)\n            {\n\n                DllContext ctx = new DllContext(ofd.FileName);\n                if (ctx.KeyGenerationCapability)\n                {\n                    SecurityLevelForm slForm = new SecurityLevelForm(ctx);\n                    if (slForm.ShowDialog() == DialogResult.OK)\n                    {\n                        Console.WriteLine($\"Authentication: Selected level {slForm.RequestedSecurityLevel} : {BitUtility.BytesToHex(slForm.KeyResponse)}\");\n                    }\n                }\n                else \n                {\n                    MessageBox.Show(\"The selected DLL is not capable of configuring ECU security levels. Please try another file.\", \"Security Level Configuration\");\n                }\n            }\n        }\n\n        private void debugJ2534ToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n\n        }\n\n        private void j2534InterfacesToolStripMenuItem_DropDownOpening(object sender, EventArgs e)\n        {\n            j2534InterfacesToolStripMenuItem.DropDownItems.Clear();\n            ToolStripItem defaultItem = j2534InterfacesToolStripMenuItem.DropDownItems.Add(\"(No devices found)\");\n            defaultItem.Enabled = false;\n\n            foreach (Tuple<string,string> device in ECUConnection.GetAvailableJ2534NamesAndDrivers()) \n            {\n                defaultItem.Visible = false;\n                ToolStripItem newItem = j2534InterfacesToolStripMenuItem.DropDownItems.Add(device.Item1);\n                newItem.Tag = device.Item2;\n                newItem.Click += J2534InterfaceItem_Click;\n            }\n        }\n\n        private void J2534InterfaceItem_Click(object sender, EventArgs e)\n        {\n            ToolStripItem caller = (ToolStripItem)sender;\n            if (Connection != null) \n            {\n                Connection.TryCleanup();\n            }\n            Connection = new ECUConnection(caller.Tag.ToString(), caller.Text);\n            Connection.ConnectionStateChangeEvent += ConnectionStateChangedHandler;\n            Connection.OpenDevice();\n            // loadtree should not be necessary if the prior state was disconnected\n            // LoadTree();\n        }\n\n        private void disconnectToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            SetDisconnectedState();\n        }\n\n        private void SetDisconnectedState(bool refresh = true) \n        {\n            // disconnected really means \"running in simulation mode\"\n            if (Connection != null)\n            {\n                Connection.TryCleanup();\n            }\n            Connection = new ECUConnection();\n            Connection.ConnectionStateChangeEvent += ConnectionStateChangedHandler;\n            if (refresh) \n            {\n                LoadTree();\n            }\n        }\n\n        private void ConnectionStateChangedHandler(string newStateDescription)\n        {\n            lblConnectionType.Text = newStateDescription;\n            txtJ2534Input.Enabled = Connection.State > ECUConnection.ConnectionState.DeviceSelectedPendingChannelConnection;\n        }\n\n        private void txtJ2534Input_KeyDown(object sender, KeyEventArgs e)\n        {\n            if (e.KeyCode == Keys.Enter) \n            {\n                e.Handled = true;\n                string inText = txtJ2534Input.Text;\n                txtJ2534Input.Text = \"\";\n                if (BitUtility.CheckHexValid(inText))\n                {\n                    byte[] requestData = BitUtility.BytesFromHex(inText.Replace(\" \", \"\").ToUpper());\n                    byte[] response = Connection.SendMessage(requestData);\n                    Console.WriteLine($\"ECU:  {BitUtility.BytesToHex(response, true)}\");\n                }\n                else \n                {\n                    Console.WriteLine($\"Could not understand provided hex input: '{inText}'\");\n                }\n            }\n        }\n\n        private void cFFExportFlashSegmentsToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            OpenFileDialog ofd = new OpenFileDialog();\n            ofd.Title = \"Select a CFF File\";\n            ofd.Filter = \"CFF files (*.cff)|*.cff|All files (*.*)|*.*\";\n            ofd.Multiselect = false;\n            if (ofd.ShowDialog() == DialogResult.OK)\n            {\n                try\n                {\n                    CaesarFlashContainer.ExportCFFMemorySegments(ofd.FileName);\n                }\n                catch (Exception ex) \n                {\n                    Console.WriteLine($\"CFF Export failed: {ex.Message}\");\n                }\n            }\n        }\n\n        private void fixClientAccessPermissionsToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            OpenFileDialog ofd = new OpenFileDialog();\n            ofd.Title = \"Select a CBF File to apply new permissions on\";\n            ofd.Filter = \"CBF files (*.cbf)|*.cbf|All files (*.*)|*.*\";\n            ofd.Multiselect = false;\n            if (ofd.ShowDialog() == DialogResult.OK)\n            {\n                FixCALs(new CaesarContainer(File.ReadAllBytes(ofd.FileName)));\n            }\n        }\n\n        private void cFFFlashSplicerToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            FlashSplicer splicer = new FlashSplicer();\n            splicer.Show();\n        }\n\n        private void allowWriteVariantCodingToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            allowWriteVariantCodingToolStripMenuItem.Checked = !allowWriteVariantCodingToolStripMenuItem.Checked;\n            Preferences.SetValue(Preferences.PreferenceKey.AllowVC, allowWriteVariantCodingToolStripMenuItem.Checked ? \"true\" : \"false\");\n        }\n\n        private void showTraceToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            if (TraceFormSingleInstance is null || TraceFormSingleInstance.IsDisposed)\n            {\n                TraceFormSingleInstance = new TraceForm(this);\n            }\n            TraceFormSingleInstance.Show();\n        }\n\n        private void clearConsoleToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            LogTextbox?.Clear();\n        }\n\n        // originally this was intended to blink the menuitem, but this requires overriding the draw call\n        private void tmrBlinkConnectionMenu_Tick(object sender, EventArgs e)\n        {\n            if (connectionToolStripMenuItem.ForeColor != SystemColors.ControlText)\n            {\n                connectionToolStripMenuItem.ForeColor = SystemColors.ControlText;\n                ConnectionMenuBlinksRemaining--;\n                if (ConnectionMenuBlinksRemaining <= 0)\n                {\n                    ConnectionMenuBlinksRemaining = 0;\n                    tmrBlinkConnectionMenu.Enabled = false;\n                }\n            }\n            else \n            {\n                if (ConnectionMenuBlinksRemaining > 0) \n                {\n                    connectionToolStripMenuItem.ForeColor = SystemColors.Control;\n                }\n            }\n        }\n\n        private int ConnectionMenuBlinksRemaining = 0;\n        private void BlinkConnectionMenu() \n        {\n            ConnectionMenuBlinksRemaining = 8;\n            tmrBlinkConnectionMenu.Enabled = true;\n        }\n\n        private void connectionToolStripMenuItem_DropDownOpening(object sender, EventArgs e)\n        {\n            disconnectToolStripMenuItem.Enabled = Connection?.ConnectionDevice != null;\n            j2534InterfacesToolStripMenuItem.Enabled = Connection?.ConnectionDevice == null;\n        }\n\n        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)\n        {\n            SetDisconnectedState();\n        }\n\n        private void copyConsoleToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            Clipboard.SetText(txtLog.Text);\n        }\n\n        private void uDSHexEditorToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            if (Connection.ConnectionProtocol is null)\n            {\n                MessageBox.Show(\"Please initiate contact with a target first.\");\n                return;\n            }\n            string protocolName = Connection.ConnectionProtocol.GetProtocolName();\n            if (protocolName != \"UDS\")\n            {\n                MessageBox.Show($\"Only UDS targets are officially supported (current protocol: {protocolName}). \\r\\n\\r\\n\" +\n                    $\"The editor will still open, however please ensure that the ECU accepts UDS-like read and write commands\");\n            }\n            UDSHexEditor editor = new UDSHexEditor(Connection); \n            editor.ShowDialog();\n        }\n\n        private void preferencesToolStripMenuItem1_DropDownOpening(object sender, EventArgs e)\n        {\n            RefreshPreferencesDropdown();\n        }\n\n        private void RefreshPreferencesDropdown()\n        {\n            // VC safety switch\n            allowWriteVariantCodingToolStripMenuItem.Checked = Preferences.GetValue(Preferences.PreferenceKey.AllowVC) == \"true\";\n\n            // scn mode\n            bool scnZero = Preferences.GetValue(Preferences.PreferenceKey.EnableSCNZero) == \"true\";\n            writeZerosVediamoToolStripMenuItem.Checked = scnZero;\n            useLastSCNToolStripMenuItem.Checked = !writeZerosVediamoToolStripMenuItem.Checked;\n\n            // fingerprint mode\n            bool fingerprintClone = Preferences.GetValue(Preferences.PreferenceKey.EnableFingerprintClone) == \"true\";\n            useLastFingerprintToolStripMenuItem.Checked = fingerprintClone;\n            customValueToolStripMenuItem.Checked = !fingerprintClone;\n\n            // fingerprint custom value\n            uint customFingerprint = uint.Parse(Preferences.GetValue(Preferences.PreferenceKey.FingerprintValue));\n            customValueToolStripMenuItem.Text = $\"Custom Value: {customFingerprint}\";\n        }\n\n        private void useLastSCNToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            Preferences.SetValue(Preferences.PreferenceKey.EnableSCNZero, \"false\");\n            RefreshPreferencesDropdown();\n        }\n\n        private void writeZerosVediamoToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            Preferences.SetValue(Preferences.PreferenceKey.EnableSCNZero, \"true\");\n            RefreshPreferencesDropdown();\n        }\n\n        private void useLastFingerprintToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            Preferences.SetValue(Preferences.PreferenceKey.EnableFingerprintClone, \"true\");\n            RefreshPreferencesDropdown();\n        }\n\n        private void customValueToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            Preferences.SetValue(Preferences.PreferenceKey.EnableFingerprintClone, \"false\");\n            // prompt for new fingerprint value\n            RefreshPreferencesDropdown();\n        }\n\n        private void tvMain_DragEnter(object sender, DragEventArgs e)\n        {\n            if (e.Data.GetDataPresent(DataFormats.FileDrop))\n            {\n                e.Effect = DragDropEffects.Copy;\n            }\n        }\n\n        private void tvMain_DragDrop(object sender, DragEventArgs e)\n        {\n            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);\n            foreach (string file in files)\n            {\n                TryLoadFile(file);\n            }\n        }\n\n        // maybe this should belong in ECUConnection\n        private ECUVariant GetCurrentVariantInstance()\n        {\n            if (!(Connection?.VariantIsAvailable ?? false))\n            {\n                return null;\n            }\n\n            foreach (CaesarContainer container in Containers)\n            {\n                foreach (ECU ecu in container.CaesarECUs)\n                {\n                    foreach (ECUVariant variant in ecu.ECUVariants)\n                    {\n                        foreach (ECUVariantPattern pattern in variant.VariantPatterns)\n                        {\n                            if (pattern.VariantID == Connection.ECUVariantID)\n                            {\n                                return variant;\n                            }\n                        }\n                    }\n                }\n            }\n            return null;\n        }\n\n        private void diagnosticTroubleCodesDTCToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            if (Connection.ConnectionProtocol is null)\n            {\n                MessageBox.Show(\"Please initiate contact with a target first.\");\n                return;\n            }\n            if (Connection.ConnectionProtocol.GetProtocolName() != \"UDS\")\n            {\n                MessageBox.Show(\"Sorry, only UDS is supported at this time.\");\n                // return was removed from here, to allow for kw2c3pe debugging\n            }\n            if (!(Connection?.VariantIsAvailable ?? false))\n            {\n                MessageBox.Show(\"DTCs require the variant to be identified first\");\n                return;\n            }\n            ECUVariant currentVariant = GetCurrentVariantInstance();\n\n            DTCForm dtcForm = new DTCForm(Connection, currentVariant);\n            dtcForm.ShowDialog();\n        }\n\n        private void viewECUMetadataToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            ECUMetadata.ShowMetadataModal(Connection);\n        }\n\n        private void identifyECUToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            if (ECUIdentification.TryReadChassisNumber(Connection, out string vin))\n            {\n                Console.WriteLine($\"VIN: {vin}\");\n            }\n            else\n            {\n                Console.WriteLine($\"Target could not be identified\");\n            }\n        }\n\n        private void loadCompressedJsonToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            OpenFileDialog ofd = new OpenFileDialog();\n            ofd.Title = \"Select a Compressed Caesar Binary (JSON) File\";\n            ofd.Filter = \"CCB files (*.ccb)|*.ccb|All files (*.*)|*.*\";\n            ofd.Multiselect = false;\n            if (ofd.ShowDialog() == DialogResult.OK)\n            {\n                Containers.Add(CaesarContainer.DeserializeCompressedContainer(File.ReadAllBytes(ofd.FileName)));\n                LoadTree();\n            }\n        }\n\n        private CaesarContainer PickContainer() \n        {\n            if (Containers.Count == 0)\n            {\n                MessageBox.Show(\"No containers have been loaded yet.\");\n                return null;\n            }\n            CaesarContainer targetContainer = Containers[0];\n            if (Containers.Count > 1)\n            {\n                // there isn't an embedded qualifier to identify containers easily; the ecu name is probably an easier name to identify with\n                List<string[]> table = new List<string[]>();\n                foreach (CaesarContainer container in Containers)\n                {\n                    if (container.CaesarECUs.Count > 0)\n                    {\n                        table.Add(new string[] { container.CaesarECUs[0].Qualifier });\n                    }\n                }\n                GenericPicker picker = new GenericPicker(table.ToArray(), new string[] { \"Container\" }, 0);\n                picker.Text = \"Please select a container\";\n                if (picker.ShowDialog() != DialogResult.OK)\n                {\n                    return null;\n                }\n                string selectedEcuQualifier = picker.SelectedResult[0];\n                targetContainer = Containers.Find(x => ((x.CaesarECUs.Count > 0) && (x.CaesarECUs[0].Qualifier == selectedEcuQualifier)));\n            }\n            return targetContainer;\n        }\n\n        private void exportContainerAsCompressedJSONToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            CaesarContainer targetContainer = PickContainer();\n            if (targetContainer is null)\n            {\n                Console.WriteLine(\"Internal error: target container is null\");\n            }\n            else\n            {\n                SaveFileDialog sfd = new SaveFileDialog();\n                sfd.Title = \"Specify a location to save your new Compressed Caesar Binary (JSON) file\";\n                sfd.Filter = \"CCB files (*.ccb)|*.ccb|All files (*.*)|*.*\";\n                sfd.FileName = targetContainer.CaesarECUs[0].Qualifier;\n                if (sfd.ShowDialog() == DialogResult.OK)\n                {\n                    File.WriteAllBytes(sfd.FileName, CaesarContainer.SerializeCompressedContainer(targetContainer));\n                }\n            }\n        }\n\n        private void dSCDebugToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n\n            OpenFileDialog ofd = new OpenFileDialog();\n            ofd.Title = \"Select a PAL File\";\n            ofd.Filter = \"PAL files (*.pal)|*.pal|All files (*.*)|*.*\";\n            ofd.Multiselect = false;\n            if (ofd.ShowDialog() == DialogResult.OK)\n            {\n                DSCContext ctx = new DSCContext(File.ReadAllBytes(ofd.FileName));\n            }\n        }\n\n        private void loadJSONToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            OpenFileDialog ofd = new OpenFileDialog();\n            ofd.Title = \"Select a Caesar JSON File\";\n            ofd.Filter = \"JSON files (*.json)|*.json|All files (*.*)|*.*\";\n            ofd.Multiselect = false;\n            if (ofd.ShowDialog() == DialogResult.OK)\n            {\n                Containers.Add(CaesarContainer.DeserializeContainer(Encoding.UTF8.GetString(File.ReadAllBytes(ofd.FileName))));\n                LoadTree();\n            }\n        }\n\n        private void exportContainerAsJSONToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            CaesarContainer targetContainer = PickContainer();\n            if (targetContainer is null)\n            {\n                Console.WriteLine(\"Internal error: target container is null\");\n            }\n            else\n            {\n                SaveFileDialog sfd = new SaveFileDialog();\n                sfd.Title = \"Specify a location to save your new Caesar JSON file\";\n                sfd.Filter = \"JSON files (*.json)|*.json|All files (*.*)|*.*\";\n                sfd.FileName = targetContainer.CaesarECUs[0].Qualifier;\n                if (sfd.ShowDialog() == DialogResult.OK)\n                {\n                    File.WriteAllBytes(sfd.FileName, Encoding.UTF8.GetBytes(CaesarContainer.SerializeContainer(targetContainer)));\n                }\n            }\n        }\n\n        // this is normally not exposed to the user, the button has to be manually enabled in the Designer\n        private void genericDebugToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            foreach (CaesarContainer container in Containers)\n            {\n                foreach (ECU ecu in container.CaesarECUs)\n                {\n                    foreach (DiagPresentation pres in ecu.GlobalPresentations) \n                    {\n                        Console.WriteLine($\"Pres : {pres.Qualifier} : {pres.GetDataType()}\");\n                        if (pres.InternalDataType == 8) \n                        {\n                            throw new NotImplementedException(\"found a iee754 float!\");\n                        }\n                    }\n                }\n            }\n            return;\n            foreach (CaesarContainer container in Containers) \n            {\n                foreach (ECU ecu in container.CaesarECUs) \n                {\n                    foreach (DiagService ds in ecu.GlobalDiagServices) \n                    {\n                        if (ds.Qualifier != \"DT_Istgang\") \n                        {\n                            //continue;\n                        }\n                        foreach (List<DiagPreparation> dpl in ds.OutputPreparations) \n                        {\n                            foreach (DiagPreparation prep in dpl) \n                            {\n                                DiagPresentation pres = ecu.GlobalPresentations[prep.PresPoolIndex];\n                                if (pres.EnumMaxValue == 0) \n                                {\n                                    continue;\n                                }\n                                foreach (Scale scale in pres.Scales) \n                                {\n                                    if (scale.EnumUpBound >= 0) \n                                    {\n                                        string presOut = pres.InterpretData(BitUtility.BytesFromHex(\"0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B\"), prep);\n                                        Console.WriteLine($\"{ds.Qualifier} : {prep.Qualifier} @ {presOut} = {pres.InternalDataType}, {pres.EnumMaxValue}\");\n                                    }\n                                }\n                                if (pres.Qualifier == \"PRES_ZIELGANG\") \n                                {\n                                    pres.PrintDebug();\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n            Console.WriteLine(\"done\");\n        }\n\n        private void listVariantIDsToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            CaesarContainer targetContainer = PickContainer();\n            if (targetContainer is null)\n            {\n                Console.WriteLine(\"Internal error: target container is null\");\n            }\n            else\n            {\n                foreach (ECU ecu in targetContainer.CaesarECUs) \n                {\n                    foreach (ECUVariant variant in ecu.ECUVariants) \n                    {\n                        foreach (ECUVariantPattern pattern in variant.VariantPatterns) \n                        {\n                            Console.WriteLine($\"{variant.Qualifier}: {pattern.VariantID:X4}\");\n                        }\n                    }\n                }\n            }\n        }\n\n        private void downloadBlocksToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            if (Connection.ConnectionProtocol is null)\n            {\n                //MessageBox.Show(\"Please initiate contact with a target first.\");\n                //return;\n            }\n            BlockDownload blockDownload = new BlockDownload(Connection);\n            blockDownload.ShowDialog();\n        }\n\n        private void fixCBFChecksumToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            // repairs the checksum on a CBF that may have been modified, so that it can be loaded by c32s (e.g. Vediamo) again\n            OpenFileDialog ofd = new OpenFileDialog();\n            ofd.Title = \"Select a CBF File\";\n            ofd.Filter = \"CBF files (*.cbf)|*.cbf|All files (*.*)|*.*\";\n            ofd.Multiselect = false;\n            if (ofd.ShowDialog() == DialogResult.OK)\n            {\n                byte[] file = File.ReadAllBytes(ofd.FileName);\n                Console.WriteLine($\"Current checksum: {BitUtility.BytesToHex(file.Skip(file.Length - 4).Reverse().ToArray())}\");\n                // restore the checksum\n                uint checksum = CaesarReader.ComputeFileChecksumLazy(file);\n                Console.WriteLine($\"New checksum: {checksum:X8}\");\n\n                file[file.Length - 4] = (byte)((checksum >> 0) & 0xFF);\n                file[file.Length - 3] = (byte)((checksum >> 8) & 0xFF);\n                file[file.Length - 2] = (byte)((checksum >> 16) & 0xFF);\n                file[file.Length - 1] = (byte)((checksum >> 24) & 0xFF);\n                File.WriteAllBytes(ofd.FileName, file);\n                Console.WriteLine($\"Fixed CBF file saved at {ofd.FileName}\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/Forms/MainForm.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <metadata name=\"statusStrip1.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>17, 17</value>\n  </metadata>\n  <metadata name=\"menuStrip1.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>133, 17</value>\n  </metadata>\n  <metadata name=\"tmrBlinkConnectionMenu.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>248, 17</value>\n  </metadata>\n  <assembly alias=\"System.Drawing\" name=\"System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\" />\n  <data name=\"$this.Icon\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n    <value>\n        AAABAAEAAAAAAAEAGAAoIAMAFgAAACgAAAAAAQAAAAIAAAEAGAAAAAAAACADAAAAAAAAAAAAAAAAAAAA\n        AADLn2LTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvT\n        nlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvT\n        nlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvT\n        nlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvT\n        nlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvT\n        nlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvT\n        nlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvT\n        nlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvT\n        nlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvT\n        nlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvT\n        nlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvT\n        nlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvT\n        nlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvTnlvLn2LcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTdnVTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTe\n        nlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTe\n        nlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTe\n        nlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTe\n        nlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTe\n        nlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTe\n        nlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTe\n        nlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTe\n        nlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTe\n        nlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTe\n        nlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTenlTe\n        nlTenlTenlTenlTdnlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTXmlPmpFf7sVz3r1v3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3\n        rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3\n        rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3\n        rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3\n        rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3\n        rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3\n        rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3\n        rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3\n        rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3\n        rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3\n        rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv3rlv8slzp\n        plfXmlPcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTv\n        qVmxgUpcSjVsVDltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTlt\n        VTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTlt\n        VTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTlt\n        VTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTlt\n        VTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTlt\n        VTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTlt\n        VTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTlt\n        VTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTlt\n        VTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTlt\n        VTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTlt\n        VTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTltVTlYRzSkeUbxq1ncnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT/tF2LaEAAABgHEyAJ\n        FCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJ\n        FCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJ\n        FCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJ\n        FCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJ\n        FCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJ\n        FCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJ\n        FCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJ\n        FCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJ\n        FCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJ\n        FCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJ\n        FCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAJFCAAABdzWTr/t13cnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgpKCgmJycjJCcpKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgnJygyLiocICUNFiErKikpKSgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCghJCYvLCqleUdUQzMADB0gIyYrKikoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgmJigLFSHCjE7/vmFtVDkJFCEPGCIsKykoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgGEiB5XTz/vmH/t166h0wrKikACx0jJScrKikoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgKFCFgTTb0rFrg\n        n1X/tl7hoFVjTjcFEiARGSIsKykoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgTGyNDOS/lolbkolbYmlPyq1n/t16p\n        fEgjJScADh4mJicqKSgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCghIyYgIya/i03yq1rcnVTam1Pfn1X/uF7cnVRTRDMCDx8X\n        HSQsKykoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgHEyCUbkP/tF3cnVTcnVTcnVTYm1P1rVr9s1yfdUUXHSQBDx8oKCgqKSgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgGEiB4XDz9s1zcnVTcnVTcnVTcnVTZm1PjoVb/uV/MklFJPjABDx4aHyUsKikoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgMFiFYRzTx\n        q1nfn1XcnVTcnVTcnVTcnVTbnFTZm1P6sVv8slyMaUEQGCIIEyApKSgpKSgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgWHCQ8NS3dnlTmpFbcnVTcnVTc\n        nVTcnVTcnVTcnVTZm1Pmo1b/uV7Ejk47NS0ADR4fIiYrKikoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCggIyYiJCfDjU7xq1ncnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTbnFTbnFT9s1zzq1qCYz4JFCAKFSEqKSkpKSgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgmJycRGSKmekf7sVzcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTYm1Pq\n        p1f/uV+zgkozLysCDx8iJCYrKikoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCFZT//tF3cnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTanFTcnVT/tV3wqllv\n        VjoCDx8QGSIrKikpKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgIEyBn\n        UTj4r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTYm1PuqVj/tl2pe0glJigRGSIs\n        KikoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgQGSJKPjHqplfioVXcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTam1Pfn1X/uF7hoFU/Ny4UGyMoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgdISYpKCjKkVDuqVjcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTam1P/vmGHZkACEB8oKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgLFSGddEX9slzcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVT9s1yddEUMFiEnJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgGEiB/YT7+s13cnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVT0rVq6h0wcICUjJCcoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgK\n        FCBfTDb1rVrenlXcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTpplfWmVM0\n        MCsZHiQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgTGyNDOS/joVbko1bc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVThoVXsp1hPQjIPGCIoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgeIiYoKCjJkVDvqVncnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTdnVT7slxuVjoGEiAoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCglJicVHCOtf0n5sFvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVT/tFyNakEIEyAoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgHEyCNakH/tF3cnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVT5sFutf0kUGyMlJicoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgGEiBuVjr7sVzdnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTuqVnK\n        kVAnJygeISYoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgOFyJQQjLuqFng\n        oFXcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVThoFXuqVlSRDIOFyIoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgaHyUxLivUmFLrp1jcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT+s1x3XDwFESAoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgmJygQGSKne0f6sVvcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT+s1yVb0MKFCEoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgGEiCGZUD/tFzcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT3rlqzg0oYHiQjJScoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgIEyBnUTj4sFvdnlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTs\n        p1jQlVIuLCocICUoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgQGSJJPjHo\n        pVfjolbcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTjoVbnpFdIPTARGSMo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgcICUuLCrQlVHsp1jcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTdnlT4sFtnUjgIEyAoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgkJScZHiW0hEv2rlrcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT/s12GZT8HEiAoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgnKCgJFCCVb0P+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVT7sVumekcQGSImJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiB2Wzz9slzcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTxq1nBjE4gIyYgIyYoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgMFiFX\n        RzTxq1nfn1XcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTjolbmpFdHPDAS\n        GSMoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgXHSQ6NC3dnVTopFfcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT9s1xwVzkGESAoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgnKCgnJygoKCgoKCgoKCgkJicWHSSygUr3rlvcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT/tFyOa0EIEyAoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgnJygjJScX\n        HSQIEyADEB8ZHiQtKykoKCgoKCgoKCgGEiCNakH/tF3cnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVT5sFusfkkUGyMlJicoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCglJicfIiYVGyMKFSEGEiALFSEYHiQ3MixjTjeYc0VfTDYT\n        GyMoKCgoKCgoKCgGEiBuVjr7sVzcnlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTuqVjKkVAoKCgeIiYoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgm\n        JygiJCYTGiMGEiAHEyARGSMlJic+Ni1cSjV6Xjybc0S3hUvZm1T4r1v/zGWleUcFEiAnKCgoKCgoKCgO\n        GCJQQzPtqFjhoFXcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTlo1bioVZB\n        OC8UGyMoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgsKikjJCcIEyAFER8OFyIcISVCOS9sVDmK\n        aECoe0jGj0/fn1XzrFr9s1z9slz1rVropFfdnlT1rVq3hUsbHyUjJCcoKCgoKCgZHiQ0MCvWmVPqplfc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTen1X1rVpgTDYKFCAoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCggIyYyLytnUTeCYz6ieEa+iU3ioVX8slz/s1z6sFvvqVnlo1bf\n        n1XcnVTcnVTcnVTcnVTcnVTrp1jTl1IxLiobHyUoKCgoKCgiJCcdISa8iE30rVrcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT+s1x+YD0GEiAoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgPGCJLPzH/tF3/uF77sVzzrFnkolbcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTioVXrp1hNQDEPGCIoKCgoKCgnKCgMFiGddEX9slzcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVT9slyfdUYNFyInJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgc\n        ICUtKyrQlVLtqFjcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTdnlT5sVtq\n        UzkHEyAoKCgoKCgoKCgGEiB+YD7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVT0rVq6h0wbHyUjJScoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgkJicWHCSwgUn3r1vc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT+tF2LaUEHEyAoKCgoKCgo\n        KCgKFCFeSzb0rVrfnlXcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFbe\n        nlU8NS0WHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCCSbUL+s1zcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT6sFupfEgSGiMmJicoKCgoKCgTGyNCOS/lolbl\n        olbcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTdnVT5sFtnUTgIEyAoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiBxWDr8slzdnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTwqlnGj08jJScgIiYoKCgoKCghJCYeISa9iU3zrFrcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT/tF2GZkAGEiAoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgNFyJURTPvqlngoFXcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTioVbppldLPzEQGSIoKCgoKCgpKCgIEyCUb0P/tFzcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVykeUcQGCImJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgZHyQ1MSzYmlPpplfcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT+\n        tF11WjsFER8oKCgoKCgoKCgGEiB2Wzv9s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTxq1nDjU4iJCcgIyYoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCglJicUGyOtf0n4\n        r1vcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT/s1yRbUIIFCAoKCgo\n        KCgoKCgMFiFYRzTxqlngn1XcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTn\n        pFfcnVQ7NC0WHSQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgpKSgFEh+IZ0D/tF3cnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT3r1uxgUoWHCQlJicoKCgoKCgXHSQ6NC3c\n        nVTnpFfcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTgn1XxqllYSDUMFiEo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgHEiBrVDn6sVzdnlTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTtqFjMk1ErKSkdISUoKCgoKCggIyYiJCfDjU7xq1ncnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT9slx3WzwGEiAoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgQGCJMPzHqplfioVXcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTjolblo1dGOzASGiMoKCgoKCgmJygQGSKkeUb7sVzcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT+s1yXcEQKFSEnKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgaHyUyLivTl1LqpljcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTe\n        nlT2rltjTzcJFCAoKCgoKCgoKCgHEiCFZT/+tFzcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVT3rluzgksXHSQkJScoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgjJScaHyW3\n        hUv1rlrcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT/tFyDZD8GEiAo\n        KCgoKCgoKCgIEyBlUDf4r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTqplfUmFIyLisZHyUoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgnKCgLFSGackT9s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7slyieEYOGCInJygoKCgoKCgQGSJK\n        PjHqpljioVbcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTen1X0rVpdSzUL\n        FSEoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiB5XTz9s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTzrFq/ik0dISYiJCYoKCgoKCgeIiYmJyjIkE/vqlncnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnFT/t16HZkAFEh8oKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgLFSFbSTXyrFrfn1XcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTlo1bhoFVBOC4UGyMoKCgoKCgoKCgLFSGcdEX9slzcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTenlTjoVbwqln+s1z+s1z/v2GieEYNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgVHCM9Ni7hoFXmo1bcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVT8slxtVTkGEiAoKCgoKCgoKCgGESB9YD3+s13cnVTcnVTcnVTcnVTcnVTgoFXnpFfyq1n8sVz+\n        s1z2rlrnpFfFjk+YcUN7XjxdSjU9Ni0kJicnKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgiJCcb\n        ICW4hkv0rVrcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT/s1yJaEAH\n        EyAoKCgoKCgoKCgKFCFfTDb1rVrhoFXlo1b0rFr/tF38slzuqVnanFO/ik2ieEaCYj5jTzdGPC8kJicJ\n        FCAFER8IEyAaHyQrKikoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgpKSgGEiCPa0L/tF3cnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT6sVupfEgSGiMmJycoKCgoKCgS\n        GiNAOC/8slz/tF3hoFW6h0yQbEJ0WTtURTM4MywfIiYOFyIGEiAIEyASGSIfIiYoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiBzWTv8slzcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTwqlnGjk8lJigfIiYoKCgoKCgjJSctKyp0WTtlUDc/\n        Ny4cICUGEiAGEiANFiEXHSQhIyYmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgNFyFTRDPuqVngoFXcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTlo1bgoFU/Ny4UHCMoKCgoKCgrKiklJicIEyAJEyAVGyMiJCYoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgYHiQ4Mizam1TopVfcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTfn1XyrFpbSjULFSEoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgi\n        JCYfIia+ik3zrFrcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT+s1x7\n        Xz0GEh8oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgnJygOFyKhd0b8slzc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT9s1yac0QLFSEnKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCBYj7+s1zcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT1rVq4hUwZHiUjJScoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBiTjf2rlvenlXcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTopVfYmlQ2MSwYHSQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgSGiNFOzDnpFfjolbcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTdnlT4r1tjTzcJFCAoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgfIyYjJSfEjU7xqlncnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT/\n        tFyCYz4GEiAoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgIFCCXcET+\n        tFzcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT8slyieEYOFyImJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgFEh96Xj3+s1zcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTyrFq/ik4gIiYhJCYoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgLFSFaSTXyrFrfn1XcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTopVfanFQ4MywXHSQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgVHCQ+Ni7fn1XmpFbcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTgoFXuqVlURTMNFyIoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCggIyYkJSfFjk/wqlncnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVT9slx0WjsGEiAoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgmJicSGiOo\n        fEj6sFvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT+s1yTbkIJFCEo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgu\n        LCobHyUBDx4GEiAGEiAGEiAGEiAGEiAGEiAGEiAGEiAGEiAGEiAGEiAGEiAGEiAGEiAGEiAGEiAGEiAG\n        EiAGEiAGEiAGEiAGEiAGEiAGEiAGEiAGEiAGEiAGEiAGEiAGEiAGEiAGEiAGEiAGEiAGEiAGEiAGEiAG\n        EiAGEiAHEyAIEyAKFCELFSEPGCIWHCMcICUiJCcnJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEyCIZ0D/tF3cnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT3r1qxgkoWHCQkJicoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgZHiRMPzGQbEKDYz6C\n        Yz6CYz6CYz6CYz6CYz6CYz6CYz6CYz6CYz6CYz6CYz6CYz6CYz6CYz6CYz6CYz6CYz6CYz6CYz6CYz6C\n        Yz6CYz6CYz6CYz6CYz6CYz6CYz6CYz6CYz6CYz6CYz6CYz6CYz6CYz6CYz6CYz6CYz6AYT58Xjx0WTpp\n        UjhdSjVNQDE9Ni0sKikbICUNFiEFER8LFSEbICUmJycpKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgHEyBpUzn5sFzdnlTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTsqFjPlVItKykbICUoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgDEB58Xzz/yGX/tFz+s1z+s1z+s1z+s1z+\n        s1z+s1z+s1z+s1z+s1z+s1z+s1z+s1z+s1z+s1z+s1z+s1z+s1z+s1z+s1z+s1z+s1z+s1z+s1z+s1z+\n        s1z+s1z+s1z+s1z+s1z+s1z+s1z+s1z+s1z+s1z+s1z+s1z+s1z9s1z8slz5sFv2rlryq1nppVfdnlTN\n        k1C4hUuddEWCYj5cSjUsKikPGCIEER8NFiEeIiYoKCgpKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgPGCJMPzHrp1jhoVXcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTfn1Xyq1pZSDQMFSEoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTdnlTenlTfn1XioVbmpFbsqFj1rVr8slz/tF30\n        rFrRlVGoe0eAYT1QQjIlJicGEiAJFCEjJScqKSgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgdISUrKinOlFHtqFjcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVT/tFx7Xz0FESAoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTbnVTen1Xsp1j7sVz/tV3v\n        qlnLklCZcUNXRjMSGiIBDx8XHSQpKCgpKSgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgnJygN\n        FiKhdkb8slzcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT9s1yac0UL\n        FiEnJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJ\n        FCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTbnFTgoFXvqVn/tl32rlq4\n        hUt2WzsxLioDEB8RGSIqKSgpKSgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEh+BYz/+tFzcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT1rVq4hkwbHyUjJScoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTanFTfn1X4sFv/tl3dnVSbc0Q7\n        NCwADR4RGSIpKSgpKSgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBiTjf2rlrenlTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTqplfUmFIyLisaHyUoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTbnFTanFTqplj/uV/npFeTbkI4MywBDx8X\n        HSQsKikoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgSGiNFOzDlo1fkolbcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTioVXqplhNQDEPGCIoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTZm1PopVf/uF7ppVeVb0IhJCYADR4iJCcrKiko\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgdISUoKCjfn1X4r1vZm1PcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTdnlT6sVtsVTkHEiAoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTZm1PppVf/ul/UmFJlTzcJFCEOFyIsKikpKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgm\n        JygTGiOCYz7/t170rVrYmlPcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT/tFyL\n        aUEHEyAoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJ\n        FCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTbnVTZm1P0rVr/t16zg0ovLSoADR4lJicqKSkoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgpKSgjJScKFCFLPzHc\n        nVT/ul/goFXZm1PcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT5sFurfUkSGiMlJicoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTanFPenlT/t17npFdbSTQCEB8aHyUsKykoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgqKSgmJycADh8mJyeleUf/tV3yq1nY\n        mlPcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTvqlnHj08lJicfIiYoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTYmlPyq1n/tV2ackQNFiEMFiEsKykoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgsKykRGSMBDx9fTDbkolb/t13enlTanFPcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVThoVbrp1hOQTIPGCIoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTZm1Pj\n        olb/ul+3hUsfIiYKFSEsKikoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgqKikkJicADR4rKim1g0v/t17sp1jYmlPcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT+s1x1WjwFEh8oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTbnFTbnVT/t17fn1Uw\n        LSoADh4rKikpKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgpKCgsKikOFyIIEyBqUzjvqln/tl3cnVTanFTcnVTcnVTcnVTcnVTcnVTcnVT+\n        s1yTbkMJFCEoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJ\n        FCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTZm1P+s13ioVU5MywFEiArKiko\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgrKikgIyYADB48NS2+ik3/t17ppVfYm1PcnVTcnVTcnVTcnVTcnVT3r1uxgUoXHSQkJico\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTXmlP6sVz0rFo7NS0ADR4rKikoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgp\n        KSgrKikJFCEJFSF9Xz34r1v7sVzanFTbnFTcnVTcnVTcnVTsqFjOlFEsKykdICUoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTYmlP6sVzlo1Y1MCsIFCAsKykoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgrKikdISUA\n        DR5EOi/Mk1D/uF7lo1bZm1PcnVTcnVTkolblo1dGOzASGiMoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTXmlP8slznpFcmJygIEyEsKykoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgpKSgpKSgGEiAUGyOHZj/9\n        s1z5sFvZm1PbnFTenlT3r1tlTzgIEyAoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTbnFTcnVTopVfrp1jqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfq\n        plfqplfqplfqplfpplfopVfmo1bioVXfn1XdnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTYm1P/tV3EjU4UGyMVHSQrKikoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgsKikZHiQADR5VRTPVmVP/tl7hoVXZ\n        m1P+s1yDZD8GEiAoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJ\n        FCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTdnVTcnVTUmFLSllLTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LV\n        mFLZm1PenlTppVfzrFr7sVz+s1z3rlvppVfenlTbnFTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTanFP/\n        uV+tfkgGEiAgIycpKSgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgqKSgnKCgDEB8XHSSackT/t17yq1r5r1ujeEcPGCIm\n        JygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTlpFfdnVRHOy8f\n        IyYxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLio0MCs5MyxBOC5NQDFe\n        SzV1WjuSbUKygkrWmVL1rVr/tV3sp1jbnFTbnFTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTbnFTfn1X/uF9uVTkADB0q\n        KikoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgrKikVGyMDEB9fTDbgoFX/xWPBjE4cICUiJCYoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTnpVfdnVQzLioGEiAaHyUaHyUaHyUa\n        HyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUZHiQXHSQUGyMPGCILFSEGEiAIEyAWHCQy\n        LypZSDSOakHVmFL/tl74r1ven1XanFPcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTanFPsqFj0rVpCOC4IFCErKikoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgrKikkJScADh8kJSepfkn/vWBURTMOFyIoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgkJicZHiQIEyACDx8rKihy\n        WDq6h0v7sVv5sFvanFTbnFTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTYmlP/tF3Hj08SGiMdISYpKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgrKikQGCIFEB+TbkNyWDoQGCIoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgpKCgqKSgZHiQBDx4RGSJWRjPAik3/\n        uV7sp1jYm1PcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTbnFT/uV95XDwACx0rKikoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgr\n        KikiJCYNFiEnKCgqKikoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJ\n        FCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgqKSkiJCcBDx8SGSN+YD3rplj6sVzZm1Pb\n        nFTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTbnFTuqFnkolYzLyoSGiMqKSgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgpKCgmJyclJicp\n        KSgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0V\n        HCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgsKikdISUADB4vLCrHj0//ul/en1XanFPcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTYmlP/\n        uF+oe0cFESAnJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgpKSgqKSkHEyAVGyOoe0f/tV3ioVbanFTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTkolbyq1lHPDAMFiIp\n        KSgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgtKykTGyMADR6VbkL/uV/hoFXanFPcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTam1P/tl6hd0YDEB8oKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgrKikZHyUEER+XcEP/tl3enlXbnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTkolbvqVlIPDAOFyIpKSgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJ\n        FCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgsKikZ\n        HiQADh6uf0j/ul/Zm1PcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTZm1P/t16jeEYGEiAoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0V\n        HCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgrKikRGSMZHyXNk1D5\n        sFvZm1PcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTppVffn1Q1MCsWHSQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgtKykFEiA1MSvvqVnqpljbnFTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTbnFT/tl12\n        WzoCEB8pKSgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgqKSgADR6EZD//uV/anFTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTbnFT6sVyxgUkPGCImJigoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgpKSgcICUUGyPEjU74sFvanFPcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTioVbtqFhKPjAPGCIoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJ\n        FCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgsKikBDx9XRjT8slzen1XcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTanFP/t16IZz8DEB8pKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0V\n        HCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgj\n        JScPGCK4hUv6sFzbnFTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT3r1u3hUsWHSQkJicoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgqKSkCDx9tVDj/tl7b\n        nFTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTo\n        pVfbnVQ4MiwXHiQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgdISYhIybKklDxqlncnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTenlT1rVpeSzUJFCEo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgrKikADR+AYT3/tl3bnFTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT+tFyBYj4GEiAoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJ\n        FCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgNFyJMPzHtqFjhoFXcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT8slyjeEYPGCInJycoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0V\n        HCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgeIiUmJyjJkVDvqlncnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVT0rFq9iE0dISUiJCYoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgnJygOFyKi\n        d0b8slzcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVToplfYmlM2MSsYHiQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEh+AYj7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTfn1Xxq1lZRzQM\n        FiIoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBjTjf2rlrenlXcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTdnlT5sFtvVjkIEyAoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJ\n        FCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgPGCJOQDHqpljioVXcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT9s1x9Xz0GEiAoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0V\n        HCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgWHCQ+Ny3dnVTmpFbcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVT9s1yLaEAJEyAoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgaHyUx\n        LyrTl1LqpljcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVT7sVyUbkIMFiEnJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgeIiYnJyjGj07vqVncnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyZckQO\n        FyImJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgfIyYiIya+iUzyq1ncnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT6sVufdUUQGCImJycoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJ\n        FCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCggIyYgIyW9iUvyrFrcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT6sFugdkUQGCImJycoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0V\n        HCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgfIiYlJifCjE3wqlncnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVT6sVufdUUQGCImJycoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgcICUu\n        KynOlFHsqFjcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVT7sVyZckQOFyImJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgXHiQ5NCzanFTnpVfcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyUbkIM\n        FiEnJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgSGiJIPTDlo1bjolbcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT+s1yKZ0AIEyAoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJ\n        FCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgLFSFbSTTyq1nfn1XcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT9s1x8Xz0GEiAoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0V\n        HCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgpKCgFEiB2Wzv9slzdnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTdnVT5sFtuVjkIFCAoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCGW\n        b0P+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTgn1XwqllYRzQNFiIoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgiJSccICW8iE30rFrcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTpplfWmVMzLysZ\n        HiUoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgUHCM8NS3goFXlo1bcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT0rVq8iEwdISYiJCYoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJ\n        FCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgqKSkBDx9rUzj/tF3cnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT8slyhdkYOFyInJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0V\n        HCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCglJygPFyKsfkj7sVzbnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVT+tF2AYT4GEiAoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgpKSgKFSFNQDH0rVrg\n        oFXcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTf\n        n1X0rVpaSTQLFSEoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgpKSgDEB+Vb0P/tl7anFTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVToplfanFQ2MSwYHiQo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgqKSgRGSMxLirkolbppVfcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT5sFuygkoUGyMlJicoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJ\n        FCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgpKCgADh6MaUD/tl7anFPcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTanFP/t16GZT8DEB8pKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0V\n        HCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgrKikGEiBH\n        PC/3rlrlo1bbnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTlo1bnpFdCOS4SGiMoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgpKSgeIiYLFSG8iEz+tF3Zm1PcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTbnFT8slyt\n        fkgMFiEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgpKCgoKCgACh19Xzz/t17cnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTbnVT/tF1uVTkDEB8pKSgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgrKikBDx9RQzL5sFvopVfanFPcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTrp1janFQwLSoYHiQoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJ\n        FCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgsKikA\n        Dx4xLiruqFj0rVrYm1PcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTZm1P/uV+YcUQDDx8pKSgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0V\n        HCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgrKikFESAtKynbnFT6sVzYmlPc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTnpFfqplc/Ny4QGCIpKSgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgqKSgmJygACx02MSvnpFf9s1zYmlPcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTZm1P/uF6TbkIADR4q\n        KSkoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgsKykYHiQADB5YRzTppVf5sFvYmlPcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTnpFftqFg9Ni0PGCIpKSgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgqKSkkJScBDx4W\n        HCSSbUL+s13zrFrXmlPcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTYm1P/ul+WcEMBDx4pKSkoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJ\n        FCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgqKSgmJycIEyAKFCFRQjLIkE//uV7kolbZm1Pc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTanFPyrFrbnFQnJygVHCMpKSgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0V\n        HCQoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgpKSgnJygZHiQDEB8JEyBPQTKzg0r7sVz3r1vam1PbnFTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTenlT/t15k\n        TzYADR4sKykoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTmpFfdnVQ/Ni0VHCQoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgmJygiJCYSGiMD\n        EB8LFSEuLCpkTzerfUj0rVr/tFzgn1Xam1PcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTYmlP/tl63hUsLFSEhJCcoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTopVfdnVQmJicACBwMFiEMFiEMFiEMFiEMFiEMFiEMFiEM\n        FiEMFiEMFiEMFiEMFiEMFiEMFiEMFiEMFiELFSEJFCEGEiAIEyAPGCIbICVBOS53WzuieEbWmVL8slz8\n        slzhoFXZm1PcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTZm1P0rVrioFYpKCgQGSIrKikoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTjolbdnVRqUjhMPzFaSDRaSDRaSDRaSDRaSDRaSDRaSDRaSDRaSDRaSDRaSDRa\n        SDRaSDRaSDRZSDRaSTRgTDZpUjh3WzuLaECid0a9iUzjolX/tF39slzqplfcnVTbnFTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTbnFTlo1b/tV1aSDQADR4sKykoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJ\n        FCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTbnFTcnVTuqVjzrFnwqlnwqlnwqlnwqlnwqlnwqlnwqlnwqlnwqlnwqlnwqlnwqlnwqlnwqlnwqlnx\n        qlnzrFn2rlr7sVz+s1z6sVvzrFrkolbbnFTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTbnFTdnlT/\n        u2CNaUEADh4mJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTfn1Xg\n        n1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1XenlTdnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTanFT/t16vf0kKFCEbICUqKSgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTZm1P/uF7LklARGSISGiMsKikoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTZm1P/tF3Tl1IjJCcMFiEsKykoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTbnFTZm1P/\n        t17Ym1MfISYIEyAtKykoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJ\n        FCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTbnFTcnVT/tl7Nk1AlJicJFCEsKyko\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTam1PhoFX/u1+7h0wUGyMJFCEsKykoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTYmlPtqFj/uF6bckQQGCIQGCIsKykoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTbnFTbnFT+s1zy\n        q1lqUzgDEB8XHSQsKykoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTZm1PnpFf/t17Nk1BAOC4ADB4iJScrKiko\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJ\n        FCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTanFPdnlT/tF35r1uCYj4TGiMJFCEqKSkpKSgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTb\n        nFTanFT3r1v/tl23hUtJPTAADh4aHyUrKikoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTbnFTcnVT1rVr/ul/IkE9eSzUN\n        FiEIEyApKCgqKSgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTanFTen1X7sVz/tF3HkE95XDwbICUADh4jJCcrKikoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgJFCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTbnFTenlTtqFj/tV36sFuzgkphTTYbICUADh4cISUsKikoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJ\n        FCBvVjn3r1venlTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTbnVTdnlTuqFj/tV33r1vTl1GX\n        cUNXRjQRGSIBDx8fIiYqKSkoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgJFCBvVjn3r1venlTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTenlXjolbuqVj6sFv/tF33r1vPlFGTbUJdSjUqKSgGEiAIFCAjJScrKiko\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgIFCBwVzn7slzhoFXfn1Xfn1Xfn1Xfn1Xf\n        n1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xf\n        n1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1Xfn1XgoFXhoFXjolblo1bopVfxq1n6sVv9\n        s1z9s1z0rFrkolbLkVCrfUiEYz5cSjUqKSgEEB8IEyAcICUoKCgpKSgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEh93Wzv/vmHyq1nwqlnwqlnwqlnwqlnwqlnwqlnwqlnwqlnw\n        qlnwqlnwqlnwqlnwqlnwqlnwqlnwqlnwqlnwqlnwqlnwqlnwqlnwqlnwqlnwqlnwqlnwqlnwqlnwqlnw\n        qlnwqlnwqlnwqlnwqlnwqlnwqlnwqlnwqlnvqVjsp1jmo1bgn1XZm1PAi02leUaRbEJ7XjxgTDZFOy8p\n        KCgSGSIFER8JFCEcICUpKSgpKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCggIyY7NCxfTDVYRzRYRzRYRzRYRzRYRzRYRzRYRzRYRzRYRzRYRzRYRzRYRzRYRzRY\n        RzRYRzRYRzRYRzRYRzRYRzRYRzRYRzRYRzRYRzRYRzRYRzRYRzRYRzRYRzRYRzRYRzRYRzRYRzRYRzRY\n        RzRYRzRYRzRYRzRYRzRWRjNSQzJLPzBCOS44MiwiJCYQGCIJFCAGEiAKFSESGiMdISUlJicoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgt\n        KykdISUIEyAMFiEMFiEMFiEMFiEMFiEMFiEMFiEMFiEMFiEMFiEMFiEMFiEMFiEMFiEMFiEMFiEMFiEM\n        FiEMFiEMFiEMFiEMFiEMFiEMFiEMFiEMFiEMFiEMFiEMFiEMFiEMFiEMFiEMFiEMFiEMFiEMFiEMFiEM\n        FiENFiEOFyIRGSIUGyMYHSQgIyYmJycnJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCC\n        Yz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7\n        sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT7sVyXcEMNFyEmJygoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo\n        KCgoKCgoKCgoKCgoKCgoKCgoKCgGEiCCYz7+s1zcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVT9s12SbUIADR0YHiUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUa\n        HyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUa\n        HyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUa\n        HyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUa\n        HyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUa\n        HyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUa\n        HyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUa\n        HyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUa\n        HyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUa\n        HyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUa\n        HyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUaHyUa\n        HyUaHyUaHyUABxx7Xjz/tV3cnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVT5sFybckQYHiQvLSoxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLiox\n        LioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLiox\n        LioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLiox\n        LioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLiox\n        LioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLiox\n        LioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLiox\n        LioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLiox\n        LioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLiox\n        LioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLiox\n        LioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLiox\n        LioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioxLioRGSOH\n        Zj/8slzcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTe\n        nlTYm1PRllHTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LT\n        l1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LT\n        l1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LT\n        l1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LT\n        l1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LT\n        l1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LT\n        l1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LT\n        l1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LT\n        l1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LT\n        l1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LT\n        l1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LTl1LRllHXmlPenlTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTam1PhoFXsp1jqplfq\n        plfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfq\n        plfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfq\n        plfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfq\n        plfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfq\n        plfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfq\n        plfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfq\n        plfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfq\n        plfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfq\n        plfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfq\n        plfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplfq\n        plfqplfqplfqplfqplfqplfqplfqplfqplfqplfqplftqFjjolbZm1PcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTT\n        nlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTTnlvTnlvcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTcnVTc\n        nVTcnVTcnVTcnVTTnlv/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/\n        mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/\n        mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/\n        mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/\n        mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/\n        mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/\n        mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/\n        mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/\n        mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/\n        mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/\n        mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/\n        mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/\n        mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/mzr/\n        mzp1paB4pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14\n        pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14\n        pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14\n        pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14\n        pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14\n        pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14\n        pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14\n        pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14\n        pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14\n        pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14\n        pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14\n        pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14\n        pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ14pJ11paAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\n</value>\n  </data>\n</root>"
  },
  {
    "path": "Caesar/Diogenes/Forms/PickDiagForm.Designer.cs",
    "content": "﻿namespace Diogenes\n{\n    partial class PickDiagForm\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PickDiagForm));\n            this.dgvMain = new System.Windows.Forms.DataGridView();\n            this.txtFilter = new System.Windows.Forms.TextBox();\n            ((System.ComponentModel.ISupportInitialize)(this.dgvMain)).BeginInit();\n            this.SuspendLayout();\n            // \n            // dgvMain\n            // \n            this.dgvMain.AllowUserToAddRows = false;\n            this.dgvMain.AllowUserToDeleteRows = false;\n            this.dgvMain.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.dgvMain.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;\n            this.dgvMain.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;\n            this.dgvMain.Location = new System.Drawing.Point(0, 21);\n            this.dgvMain.Name = \"dgvMain\";\n            this.dgvMain.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;\n            this.dgvMain.Size = new System.Drawing.Size(800, 429);\n            this.dgvMain.TabIndex = 1;\n            this.dgvMain.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dgvMain_CellDoubleClick);\n            // \n            // txtFilter\n            // \n            this.txtFilter.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.txtFilter.Location = new System.Drawing.Point(0, 1);\n            this.txtFilter.Name = \"txtFilter\";\n            this.txtFilter.Size = new System.Drawing.Size(800, 20);\n            this.txtFilter.TabIndex = 2;\n            this.txtFilter.TextChanged += new System.EventHandler(this.txtFilter_TextChanged);\n            // \n            // PickDiagForm\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(800, 450);\n            this.Controls.Add(this.txtFilter);\n            this.Controls.Add(this.dgvMain);\n            this.Icon = ((System.Drawing.Icon)(resources.GetObject(\"$this.Icon\")));\n            this.Name = \"PickDiagForm\";\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\n            this.Text = \"Select Diagnostic Service\";\n            this.Load += new System.EventHandler(this.PickDiagForm_Load);\n            ((System.ComponentModel.ISupportInitialize)(this.dgvMain)).EndInit();\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.DataGridView dgvMain;\n        private System.Windows.Forms.TextBox txtFilter;\n    }\n}"
  },
  {
    "path": "Caesar/Diogenes/Forms/PickDiagForm.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nusing System.Linq;\nusing System.Reflection;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\nusing Caesar;\n\nnamespace Diogenes\n{\n    public partial class PickDiagForm : Form\n    {\n        public DiagService[] DiagServices = new DiagService[] { };\n        public DiagService SelectedDiagService = null;\n        public PickDiagForm(DiagService[] diagServices)\n        {\n            DiagServices = diagServices;\n            InitializeComponent();\n        }\n\n        private void PickDiagForm_Load(object sender, EventArgs e)\n        {\n            UnmanagedUtility.SendMessage(txtFilter.Handle, UnmanagedUtility.EM_SETCUEBANNER, 0, \"Search for a diagnostic service..\");\n            EnableDoubleBuffer(dgvMain, true);\n            PresentDiagServices();\n        }\n\n        public static void EnableDoubleBuffer(DataGridView dgv, bool setting)\n        {\n            Type dgvType = dgv.GetType();\n            PropertyInfo pi = dgvType.GetProperty(\"DoubleBuffered\", BindingFlags.Instance | BindingFlags.NonPublic);\n            pi.SetValue(dgv, setting, null);\n        }\n\n        private void PresentDiagServices()\n        {\n            DataTable dt = new DataTable();\n            dt.Columns.Add(\"Index\", typeof(String));\n            dt.Columns.Add(\"Name\", typeof(String));\n            dt.Columns.Add(\"Function Type\", typeof(String));\n            dt.Columns.Add(\"Access Level\", typeof(String));\n            dt.Columns.Add(\"Security Access Level\", typeof(String));\n            dt.Columns.Add(\"Input Parameters\", typeof(String));\n            dt.Columns.Add(\"Output Parameters\", typeof(String));\n            dt.Columns.Add(\"Command\", typeof(String));\n\n            string namePartialMatch = txtFilter.Text.ToLower();\n\n            for (int i = 0; i < DiagServices.Length; i++) \n            {\n                DiagService diag = DiagServices[i];\n\n                if (diag.Qualifier.ToLower().Contains(namePartialMatch))\n                {\n                    dt.Rows.Add(new string[]\n                    {\n                        i.ToString(),\n                        diag.Qualifier,\n                        diag.IsExecutable == 1 ? \"User\" : \"System\" ,\n                        diag.ClientAccessLevel.ToString(),\n                        diag.SecurityAccessLevel.ToString(),\n                        diag.InputPreparations.Count.ToString(),\n                        diag.OutputPreparations.Count.ToString(),\n                        BitUtility.BytesToHex(diag.RequestBytes, true),\n                    });\n                }\n            }\n\n            dgvMain.DataSource = dt;\n\n            // apparently resize+sort is really expensive\n            if (dgvMain.Columns[dgvMain.Columns.Count - 1].AutoSizeMode != DataGridViewAutoSizeColumnMode.Fill) \n            {\n                dgvMain.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;\n                dgvMain.Columns[dgvMain.Columns.Count - 1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;\n                dgvMain.Columns[0].Visible = false;\n            }\n\n            /*\n            int colIndex = 0;\n            dgvMain.Columns[colIndex++].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;\n            dgvMain.Columns[colIndex++].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;\n            dgvMain.Columns[colIndex++].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;\n            dgvMain.Columns[colIndex++].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;\n            dgvMain.Columns[colIndex++].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;\n            dgvMain.Columns[colIndex++].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;\n            dgvMain.Columns[colIndex++].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;\n            dgvMain.Columns[colIndex++].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;\n            */\n            // dgvMain.Sort(dgvMain.Columns[0], ListSortDirection.Ascending);\n        }\n\n        private void txtFilter_TextChanged(object sender, EventArgs e)\n        {\n            PresentDiagServices();\n        }\n\n        private void dgvMain_CellDoubleClick(object sender, DataGridViewCellEventArgs e)\n        {\n            if (dgvMain.SelectedRows.Count == 1)\n            {\n                int selectedDiagIndex = int.Parse(dgvMain.SelectedRows[0].Cells[0].Value.ToString());\n                SelectedDiagService = DiagServices[selectedDiagIndex];\n                this.DialogResult = DialogResult.OK;\n                this.Close();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/Forms/PickDiagForm.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <assembly alias=\"System.Drawing\" name=\"System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\" />\n  <data name=\"$this.Icon\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n    <value>\n        AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAw5Ftm8OOaP/Ai2b/vohk/7uFYf+5g1//toBe/7R+XP+yfFr/sXtY/655V/+tdlb/q3VU/6lz\n        U/+pcVH/o3BRm8iSbP9SUlL/U1NT/1RUVP9VVVX/VlZW/1dXV/9XV1f/WFhY/1lZWf9aWlr/W1tb/1xc\n        XP9cXFz/XV1d/6lyUf/KlG7/Tk5O/z09Pf89PT3/Pj4+/z8/P/9BQUH/QkJC/0NDQ/9ERET/RUVF/0ZG\n        Rv9GRkb/SEhI/1paWv+qc1P/zJdv/0tLS/84ODj/OTk5/zo6Ov88PDz/PT09/z8/P/8/Pz//QUFB/0JC\n        Qv9CQkL/RERE/0VFRf9XV1f/rHVU/8+acv9HR0f/MzMz/zQ0NP82Njb/Nzc3/zk5Of86Ojr/Ozs7/zw8\n        PP8+Pj7/Pz8//0BAQP9BQUH/VVVV/614Vv/RnHP/QkJC/y8vL/8wMDD/MTEx/zMzM/80NDT/NjY2/zY2\n        Nv84ODj/Ojo6/zs7O/89PT3/PT09/1JSUv+welj/1J51/z09Pf8pKSn/0dHR/62trf8uLi7/Ly8v/zEx\n        Mf8yMjL/NDQ0/zY2Nv83Nzf/ODg4/zo6Ov9OTk7/snxa/9Wgdv85OTn/JSUl/yYmJv/e3t7/dHR0/yoq\n        Kv8sLCz/LS0t/y8vL/8xMTH/MjIy/zQ0NP81NTX/S0tL/7V+XP/Yonn/NDQ0/yAgIP/Pz8//qKio/yQk\n        JP8lJSX/JiYm/ygoKP8qKir/LCws/y0tLf8vLy//MTEx/0ZGRv+3gV7/2aN5/zQ0NP8gICD/ISEh/yIi\n        Iv8kJCT/JSUl/yYmJv8oKCj/Kioq/ywsLP8tLS3/Ly8v/zExMf9GRkb/uoVg/9ukev8xMTH/MjIy/zMz\n        M/80NDT/NTU1/zY2Nv83Nzf/OTk5/zs7O/88PDz/PT09/z8/P/9BQUH/Q0ND/72HY//cp3v/26R6/9qj\n        ef/Yonn/16F4/9Wfdv/TnnT/0Zxz/8+acv/Nl3D/y5Vu/8mUbP/HkWv/xI9p/8ONZ//Ai2b/3ayF/fHc\n        zv/qwaD/6LmS/+i5kv/ouZL/6LmS/+i5kv/ouZL/zcjF/+i5kv/NyMX/6LmS/0Rk///oxKf/wZBv/d2s\n        hsLdsY303Kd7/9ymev/apHr/2KJ5/9ihef/VoHb/1J51/9Kdc//PmnL/zplw/8uWb//JlGz/xJp69MOT\n        ccIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAA//8AAA==\n</value>\n  </data>\n</root>"
  },
  {
    "path": "Caesar/Diogenes/Forms/RunDiagForm.Designer.cs",
    "content": "﻿namespace Diogenes\n{\n    partial class RunDiagForm\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(RunDiagForm));\n            this.groupBox2 = new System.Windows.Forms.GroupBox();\n            this.dgvMain = new System.Windows.Forms.DataGridView();\n            this.groupBox1 = new System.Windows.Forms.GroupBox();\n            this.btnApply = new System.Windows.Forms.Button();\n            this.btnReinterpret = new System.Windows.Forms.Button();\n            this.btnCopy = new System.Windows.Forms.Button();\n            this.txtDiagCommand = new System.Windows.Forms.TextBox();\n            this.groupBox2.SuspendLayout();\n            ((System.ComponentModel.ISupportInitialize)(this.dgvMain)).BeginInit();\n            this.groupBox1.SuspendLayout();\n            this.SuspendLayout();\n            // \n            // groupBox2\n            // \n            this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.groupBox2.Controls.Add(this.dgvMain);\n            this.groupBox2.Location = new System.Drawing.Point(12, 99);\n            this.groupBox2.Name = \"groupBox2\";\n            this.groupBox2.Size = new System.Drawing.Size(1225, 507);\n            this.groupBox2.TabIndex = 3;\n            this.groupBox2.TabStop = false;\n            this.groupBox2.Text = \"Diagnostics Parameters\";\n            // \n            // dgvMain\n            // \n            this.dgvMain.AllowUserToAddRows = false;\n            this.dgvMain.AllowUserToDeleteRows = false;\n            this.dgvMain.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.dgvMain.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;\n            this.dgvMain.Location = new System.Drawing.Point(6, 19);\n            this.dgvMain.Name = \"dgvMain\";\n            this.dgvMain.ReadOnly = true;\n            this.dgvMain.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;\n            this.dgvMain.ShowEditingIcon = false;\n            this.dgvMain.Size = new System.Drawing.Size(1213, 482);\n            this.dgvMain.TabIndex = 0;\n            // \n            // groupBox1\n            // \n            this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.groupBox1.Controls.Add(this.btnApply);\n            this.groupBox1.Controls.Add(this.btnReinterpret);\n            this.groupBox1.Controls.Add(this.btnCopy);\n            this.groupBox1.Controls.Add(this.txtDiagCommand);\n            this.groupBox1.Location = new System.Drawing.Point(12, 12);\n            this.groupBox1.Name = \"groupBox1\";\n            this.groupBox1.Size = new System.Drawing.Size(1225, 81);\n            this.groupBox1.TabIndex = 2;\n            this.groupBox1.TabStop = false;\n            this.groupBox1.Text = \"Computed Command\";\n            // \n            // btnApply\n            // \n            this.btnApply.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));\n            this.btnApply.Location = new System.Drawing.Point(1144, 51);\n            this.btnApply.Name = \"btnApply\";\n            this.btnApply.Size = new System.Drawing.Size(75, 23);\n            this.btnApply.TabIndex = 5;\n            this.btnApply.Text = \"Write\";\n            this.btnApply.UseVisualStyleBackColor = true;\n            this.btnApply.Click += new System.EventHandler(this.btnApply_Click);\n            // \n            // btnReinterpret\n            // \n            this.btnReinterpret.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));\n            this.btnReinterpret.Location = new System.Drawing.Point(1063, 51);\n            this.btnReinterpret.Name = \"btnReinterpret\";\n            this.btnReinterpret.Size = new System.Drawing.Size(75, 23);\n            this.btnReinterpret.TabIndex = 4;\n            this.btnReinterpret.Text = \"Reinterpret\";\n            this.btnReinterpret.UseVisualStyleBackColor = true;\n            // \n            // btnCopy\n            // \n            this.btnCopy.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));\n            this.btnCopy.Location = new System.Drawing.Point(982, 51);\n            this.btnCopy.Name = \"btnCopy\";\n            this.btnCopy.Size = new System.Drawing.Size(75, 23);\n            this.btnCopy.TabIndex = 3;\n            this.btnCopy.Text = \"Copy\";\n            this.btnCopy.UseVisualStyleBackColor = true;\n            // \n            // txtDiagCommand\n            // \n            this.txtDiagCommand.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.txtDiagCommand.Font = new System.Drawing.Font(\"Consolas\", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.txtDiagCommand.Location = new System.Drawing.Point(6, 19);\n            this.txtDiagCommand.Name = \"txtDiagCommand\";\n            this.txtDiagCommand.Size = new System.Drawing.Size(1213, 26);\n            this.txtDiagCommand.TabIndex = 0;\n            // \n            // RunDiagForm\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(1249, 618);\n            this.Controls.Add(this.groupBox2);\n            this.Controls.Add(this.groupBox1);\n            this.Icon = ((System.Drawing.Icon)(resources.GetObject(\"$this.Icon\")));\n            this.Name = \"RunDiagForm\";\n            this.Text = \"Execute Diagnostic Service\";\n            this.Load += new System.EventHandler(this.RunDiagForm_Load);\n            this.groupBox2.ResumeLayout(false);\n            ((System.ComponentModel.ISupportInitialize)(this.dgvMain)).EndInit();\n            this.groupBox1.ResumeLayout(false);\n            this.groupBox1.PerformLayout();\n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.GroupBox groupBox2;\n        private System.Windows.Forms.DataGridView dgvMain;\n        private System.Windows.Forms.GroupBox groupBox1;\n        private System.Windows.Forms.Button btnApply;\n        private System.Windows.Forms.Button btnReinterpret;\n        private System.Windows.Forms.Button btnCopy;\n        private System.Windows.Forms.TextBox txtDiagCommand;\n    }\n}"
  },
  {
    "path": "Caesar/Diogenes/Forms/RunDiagForm.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\nusing Caesar;\n\nnamespace Diogenes\n{\n    public partial class RunDiagForm : Form\n    {\n        public DiagService CurrentDiagService;\n        public byte[] Result = Array.Empty<byte>();\n\n        public RunDiagForm(DiagService diagService)\n        {\n            CurrentDiagService = diagService;\n            Result = CurrentDiagService.RequestBytes;\n            InitializeComponent();\n        }\n\n        private void RunDiagForm_Load(object sender, EventArgs e)\n        {\n            this.Text = $\"Run Diagnostics Service: {CurrentDiagService.Qualifier}\";\n            TrimIntegerDumps();\n            txtDiagCommand.Text = BitUtility.BytesToHex(Result, true);\n\n            if (!CheckBitAlignment()) \n            {\n                MessageBox.Show(\"One or more parameters are placed between byte boundaries. This isn't supported yet.\", \"Parameter misalignment\");\n                this.Close();\n                return;\n            }\n\n            PresentDiagService();\n        }\n\n        private void TrimIntegerDumps() \n        {\n            // integer dumps are always saved as LE int32, even if they are not int32\n            foreach (DiagPreparation prep in CurrentDiagService.InputPreparations)\n            {\n                if (prep.FieldType == DiagPreparation.InferredDataType.IntegerType)\n                {\n                    int byteSize = prep.SizeInBits / 8;\n                    if (prep.Dump.Length > byteSize) \n                    {\n                        prep.Dump = prep.Dump.Take(byteSize).ToArray();\n                    }\n                }\n            }\n        }\n\n        private bool CheckBitAlignment() \n        {\n            // example service that fails this check:\n            /*\n                MED40:\n             \tIOC_Getriebeanwaermung_Absperrventil_Getriebeanwaermung_Absperrventil\tUser\t1\t0\t5\t1\t2F D1 05 03 00\n             */\n            foreach (DiagPreparation prep in CurrentDiagService.InputPreparations)\n            {\n                if (prep.BitPosition % 8 != 0)\n                {\n                    return false;\n                }\n                if (prep.SizeInBits % 8 != 0)\n                {\n                    return false;\n                }\n            }\n            return true;\n        }\n\n        private void PresentDiagService() \n        {\n            DataTable dt = new DataTable();\n            dt.Columns.Add(\"Index\", typeof(int));\n            dt.Columns.Add(\"Name\", typeof(String));\n            dt.Columns.Add(\"Byte Position\", typeof(int));\n            dt.Columns.Add(\"Data Size\", typeof(int));\n            dt.Columns.Add(\"Data Type\", typeof(String));\n            dt.Columns.Add(\"Inferred Type\", typeof(String));\n            dt.Columns.Add(\"Direction\", typeof(String));\n            dt.Columns.Add(\"Raw Data\", typeof(String));\n\n            int listUniqueIndex = 0;\n            for (int i = 0; i < CurrentDiagService.InputPreparations.Count; i++)\n            {\n                DiagPreparation prep = CurrentDiagService.InputPreparations[i];\n\n                dt.Rows.Add(new object[]\n                {\n                        listUniqueIndex,\n                        prep.Qualifier,\n                        prep.BitPosition / 8,\n                        prep.SizeInBits / 8,\n                        prep.ModeConfig.ToString(\"X\"),\n                        prep.FieldType.ToString(),\n                        \"Input\",\n                        BitUtility.BytesToHex(prep.Dump, true),\n                });\n                listUniqueIndex++;\n            }\n            for (int i = 0; i < CurrentDiagService.OutputPreparations.Count; i++)\n            {\n                List<DiagPreparation> currentDiagList = CurrentDiagService.OutputPreparations[i];\n                for (int j = 0; j < currentDiagList.Count; j++) \n                {\n                    DiagPreparation prep = CurrentDiagService.OutputPreparations[i][j];\n\n                    dt.Rows.Add(new object[]\n                    {\n                        listUniqueIndex,\n                        prep.Qualifier,\n                        prep.BitPosition / 8,\n                        prep.SizeInBits / 8,\n                        prep.ModeConfig.ToString(\"X\"),\n                        prep.FieldType.ToString(),\n                        $\"Output ({i})\",\n                        BitUtility.BytesToHex(prep.Dump, true),\n                    });\n                    listUniqueIndex++;\n                }\n            }\n\n            dgvMain.DataSource = dt;\n\n            int colIndex = 0;\n            dgvMain.Columns[colIndex++].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;\n            dgvMain.Columns[colIndex++].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;\n            dgvMain.Columns[colIndex++].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;\n            dgvMain.Columns[colIndex++].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;\n            dgvMain.Columns[colIndex++].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;\n            dgvMain.Columns[colIndex++].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;\n            dgvMain.Columns[colIndex++].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;\n            dgvMain.Columns[colIndex++].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;\n\n            dgvMain.Columns[0].Visible = false;\n            dgvMain.Columns[4].Visible = false;\n            // dgvMain.Columns[6].Visible = false;\n            dgvMain.Sort(dgvMain.Columns[0], ListSortDirection.Ascending);\n        }\n\n        private void btnApply_Click(object sender, EventArgs e)\n        {\n            string commandAsString = txtDiagCommand.Text;\n            if (!BitUtility.CheckHexValid(commandAsString))\n            {\n                MessageBox.Show(\"Hex data could not be parsed. Please check if there are any invalid values\", \"Write Variant Coding\");\n                return;\n            }\n            Result = BitUtility.BytesFromHex(commandAsString);\n            this.DialogResult = DialogResult.OK;\n            this.Close();\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/Forms/RunDiagForm.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <assembly alias=\"System.Drawing\" name=\"System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\" />\n  <data name=\"$this.Icon\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n    <value>\n        AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAw5Ftm8OOaP/Ai2b/vohk/7uFYf+5g1//toBe/7R+XP+yfFr/sXtY/655V/+tdlb/q3VU/6lz\n        U/+pcVH/o3BRm8iSbP9SUlL/U1NT/1RUVP9VVVX/VlZW/1dXV/9XV1f/WFhY/1lZWf9aWlr/W1tb/1xc\n        XP9cXFz/XV1d/6lyUf/KlG7/Tk5O/z09Pf89PT3/Pj4+/z8/P/9BQUH/QkJC/0NDQ/9ERET/RUVF/0ZG\n        Rv9GRkb/SEhI/1paWv+qc1P/zJdv/0tLS/84ODj/OTk5/zo6Ov88PDz/PT09/z8/P/8/Pz//QUFB/0JC\n        Qv9CQkL/RERE/0VFRf9XV1f/rHVU/8+acv9HR0f/MzMz/zQ0NP82Njb/Nzc3/zk5Of86Ojr/Ozs7/zw8\n        PP8+Pj7/Pz8//0BAQP9BQUH/VVVV/614Vv/RnHP/QkJC/y8vL/8wMDD/MTEx/zMzM/80NDT/NjY2/zY2\n        Nv84ODj/Ojo6/zs7O/89PT3/PT09/1JSUv+welj/1J51/z09Pf8pKSn/0dHR/62trf8uLi7/Ly8v/zEx\n        Mf8yMjL/NDQ0/zY2Nv83Nzf/ODg4/zo6Ov9OTk7/snxa/9Wgdv85OTn/JSUl/yYmJv/e3t7/dHR0/yoq\n        Kv8sLCz/LS0t/y8vL/8xMTH/MjIy/zQ0NP81NTX/S0tL/7V+XP/Yonn/NDQ0/yAgIP/Pz8//qKio/yQk\n        JP8lJSX/JiYm/ygoKP8qKir/LCws/y0tLf8vLy//MTEx/0ZGRv+3gV7/2aN5/zQ0NP8gICD/ISEh/yIi\n        Iv8kJCT/JSUl/yYmJv8oKCj/Kioq/ywsLP8tLS3/Ly8v/zExMf9GRkb/uoVg/9ukev8xMTH/MjIy/zMz\n        M/80NDT/NTU1/zY2Nv83Nzf/OTk5/zs7O/88PDz/PT09/z8/P/9BQUH/Q0ND/72HY//cp3v/26R6/9qj\n        ef/Yonn/16F4/9Wfdv/TnnT/0Zxz/8+acv/Nl3D/y5Vu/8mUbP/HkWv/xI9p/8ONZ//Ai2b/3ayF/fHc\n        zv/qwaD/6LmS/+i5kv/ouZL/6LmS/+i5kv/ouZL/zcjF/+i5kv/NyMX/6LmS/0Rk///oxKf/wZBv/d2s\n        hsLdsY303Kd7/9ymev/apHr/2KJ5/9ihef/VoHb/1J51/9Kdc//PmnL/zplw/8uWb//JlGz/xJp69MOT\n        ccIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAA//8AAA==\n</value>\n  </data>\n</root>"
  },
  {
    "path": "Caesar/Diogenes/Forms/SecurityLevelForm.Designer.cs",
    "content": "﻿namespace Diogenes\n{\n    partial class SecurityLevelForm\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SecurityLevelForm));\n            this.txtChallenge = new System.Windows.Forms.TextBox();\n            this.groupBox1 = new System.Windows.Forms.GroupBox();\n            this.groupBox2 = new System.Windows.Forms.GroupBox();\n            this.dgvMain = new System.Windows.Forms.DataGridView();\n            this.groupBox1.SuspendLayout();\n            this.groupBox2.SuspendLayout();\n            ((System.ComponentModel.ISupportInitialize)(this.dgvMain)).BeginInit();\n            this.SuspendLayout();\n            // \n            // txtChallenge\n            // \n            this.txtChallenge.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.txtChallenge.Font = new System.Drawing.Font(\"Consolas\", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.txtChallenge.Location = new System.Drawing.Point(6, 19);\n            this.txtChallenge.Name = \"txtChallenge\";\n            this.txtChallenge.Size = new System.Drawing.Size(764, 26);\n            this.txtChallenge.TabIndex = 1;\n            this.txtChallenge.TextChanged += new System.EventHandler(this.txtCodingString_TextChanged);\n            // \n            // groupBox1\n            // \n            this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.groupBox1.Controls.Add(this.txtChallenge);\n            this.groupBox1.Location = new System.Drawing.Point(12, 12);\n            this.groupBox1.Name = \"groupBox1\";\n            this.groupBox1.Size = new System.Drawing.Size(776, 54);\n            this.groupBox1.TabIndex = 2;\n            this.groupBox1.TabStop = false;\n            this.groupBox1.Text = \"Input Seed\";\n            // \n            // groupBox2\n            // \n            this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.groupBox2.Controls.Add(this.dgvMain);\n            this.groupBox2.Location = new System.Drawing.Point(12, 72);\n            this.groupBox2.Name = \"groupBox2\";\n            this.groupBox2.Size = new System.Drawing.Size(776, 366);\n            this.groupBox2.TabIndex = 3;\n            this.groupBox2.TabStop = false;\n            this.groupBox2.Text = \"Available Key Responses\";\n            // \n            // dgvMain\n            // \n            this.dgvMain.AllowUserToAddRows = false;\n            this.dgvMain.AllowUserToDeleteRows = false;\n            this.dgvMain.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.dgvMain.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;\n            this.dgvMain.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;\n            this.dgvMain.Location = new System.Drawing.Point(6, 19);\n            this.dgvMain.Name = \"dgvMain\";\n            this.dgvMain.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;\n            this.dgvMain.Size = new System.Drawing.Size(764, 341);\n            this.dgvMain.TabIndex = 0;\n            this.dgvMain.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dgvMain_CellDoubleClick);\n            // \n            // SecurityLevelForm\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(800, 450);\n            this.Controls.Add(this.groupBox2);\n            this.Controls.Add(this.groupBox1);\n            this.Icon = ((System.Drawing.Icon)(resources.GetObject(\"$this.Icon\")));\n            this.Name = \"SecurityLevelForm\";\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\n            this.Text = \"Configure Security Level\";\n            this.Load += new System.EventHandler(this.SecurityLevelForm_Load);\n            this.groupBox1.ResumeLayout(false);\n            this.groupBox1.PerformLayout();\n            this.groupBox2.ResumeLayout(false);\n            ((System.ComponentModel.ISupportInitialize)(this.dgvMain)).EndInit();\n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.TextBox txtChallenge;\n        private System.Windows.Forms.GroupBox groupBox1;\n        private System.Windows.Forms.GroupBox groupBox2;\n        private System.Windows.Forms.DataGridView dgvMain;\n    }\n}"
  },
  {
    "path": "Caesar/Diogenes/Forms/SecurityLevelForm.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\nusing Caesar;\nusing Diogenes.SecurityAccess;\n\nnamespace Diogenes\n{\n    public partial class SecurityLevelForm : Form\n    {\n        public int RequestedSecurityLevel = -1;\n        public byte[] InputChallenge = new byte[] { };\n        public byte[] KeyResponse = new byte[] { };\n        DllContext Context;\n\n        private const string invalidSeedPrompt = \"(double-click to request for seed)\";\n        public SecurityLevelForm(DllContext context)\n        {\n            InitializeComponent();\n            Context = context;\n        }\n\n        private void PresentKeys(byte[] seed) \n        {\n            DataTable dt = new DataTable();\n            dt.Columns.Add(\"Access Level\", typeof(String));\n            dt.Columns.Add(\"Key\", typeof(String));\n\n            for (int i = 0; i < Context.AccessLevels.Count; i++)\n            {\n                if (Context.AccessLevels[i].Item3 == seed.Length)\n                {\n                    DataRow row = dt.Rows.Add(new string[] { Context.AccessLevels[i].Item1.ToString(), Context.GenerateKeyAuto(Context.AccessLevels[i].Item1, seed) });\n                }\n                else\n                {\n                    dt.Rows.Add(new string[] { Context.AccessLevels[i].Item1.ToString(), invalidSeedPrompt });\n                }\n            }\n\n            dgvMain.DataSource = dt;\n            dgvMain.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;\n            dgvMain.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;\n            dgvMain.Sort(dgvMain.Columns[0], ListSortDirection.Ascending);\n        }\n\n        private void SecurityLevelForm_Load(object sender, EventArgs e)\n        {\n            // dj_zugriffsberechtigung\n            this.Text = $\"Configure Security Level - {Context.ECUName}\";\n            txtChallenge.Text = BitUtility.BytesToHex(InputChallenge, true);\n            PresentKeys(new byte[] { });\n        }\n\n        private void txtCodingString_TextChanged(object sender, EventArgs e)\n        {\n            TryRefreshKey();\n        }\n        public void TryRefreshKey()\n        {\n            bool validHex = true;\n            string cleanedText = txtChallenge.Text.Replace(\" \", \"\").Replace(\"\\r\", \"\").Replace(\"\\n\", \"\").Replace(\"\\t\", \"\").Replace(\"-\", \"\").ToUpper();\n            if (cleanedText.Length % 2 != 0)\n            {\n                validHex = false;\n            }\n            if (!System.Text.RegularExpressions.Regex.IsMatch(cleanedText, @\"\\A\\b[0-9a-fA-F]+\\b\\Z\"))\n            {\n                validHex = false;\n            }\n\n            if (validHex)\n            {\n                byte[] seed = BitUtility.BytesFromHex(cleanedText);\n                txtChallenge.BackColor = System.Drawing.SystemColors.Window;\n                PresentKeys(seed);\n            }\n            else\n            {\n                if (cleanedText.Length == 0)\n                {\n                    PresentKeys(new byte[] { });\n                }\n                txtChallenge.BackColor = System.Drawing.Color.LavenderBlush;\n            }\n        }\n\n        private void dgvMain_CellDoubleClick(object sender, DataGridViewCellEventArgs e)\n        {\n            if (dgvMain.SelectedRows.Count == 1)\n            {\n                int selectedLevel = int.Parse(dgvMain.SelectedRows[0].Cells[0].Value.ToString());\n                string selectedValue = dgvMain.SelectedRows[0].Cells[1].Value.ToString();\n                if (selectedValue == invalidSeedPrompt)\n                {\n                    Console.WriteLine($\"Security Access: Requesting seed for level {selectedLevel}\");\n                    RequestSeed(selectedLevel);\n                }\n                else \n                {\n                    KeyResponse = BitUtility.BytesFromHex(selectedValue);\n                    RequestedSecurityLevel = selectedLevel;\n                    DialogResult = DialogResult.OK;\n                    this.Close();\n                }\n            }\n        }\n\n        private void RequestSeed(int accessLevel) \n        {\n            // since we have no connection at the moment, feed in a dummy value\n            int seedSize = Context.AccessLevels.Find(x => x.Item1 == accessLevel).Item3;\n            txtChallenge.Text = BitUtility.BytesToHex(new byte[seedSize]);\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/Forms/SecurityLevelForm.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <assembly alias=\"System.Drawing\" name=\"System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\" />\n  <data name=\"$this.Icon\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n    <value>\n        AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAA\n        AAA2ndn/MZnY/yyU1/8okNb/I4zV/x6I1P8ahNP/FYDS/xF80f8OedH/CnbQ/wdzz/8EcM//AW7O/wAA\n        AAAAAAAAPaPa/7zr+v+86/z/v+7+/8b0///O+P//0/r//9D4///H8v//uun8/7Pk+f+w4vj/sOL4/wVx\n        z/8AAAAAAAAAAEOo2/+/7Pv/Wc/1/0Gw7P8TQVr/KWGJ/0mJvv9Imsj/SK7n/zel5v8qmuH/OLju/7Hj\n        +P8JddD/AAAAAAAAAABJrdz/we77/1/T9/9s2/z/LGeF/5TH+f+Ryfn/QYXJ/yFqrv9Tvez/Rr7v/zy6\n        7v+z4/n/DnnR/wAAAAAAAAAATrLd/8Pv+/9l1vj/TLbs/0OJqv/g8v//VJrY/xp6vv9JmMX/NYbF/zOb\n        3v9Cvu//tOX5/xN+0v8AAAAAAAAAAFO33v/G8Pz/atn4/3zi/f9jt9n/erbV/5C30f9VyeT/W9/1/3jQ\n        7f9CmNz/RLrt/7bn+f8Yg9P/AAAAAAAAAABYu9//x/H8/2/c+f9Wu+3/Yb3v/3HG5/9yuNb/wvb9/2Pf\n        9/9d4vj/edPw/0OX3P+o3PX/HojU/wAAAAAAAAAAXL/g/8jz/P913/n/ieb9/5Xn//+a5f//ecrn/3fL\n        5//H9/3/Xtz1/1rh9/971PH/SJne/yiN1v8AAAAAAAAAAGDC4f/J8/z/y/P9/9T2/v/X9v//2PT//+D4\n        //+p4/X/edPu/8f3/f9f3PX/W+L3/3rW8v8+mN7/RI3NMAAAAABhw+H/iKCo/5GRkf+Ojo7/Wrnc/1W4\n        3/9Rtd7/TbHd/z+w3v981O7/xPb9/2zd9v9tyu3/Y6PX/12b0uxRksomAAAAAJmZmcPGxsb/lJSU/wAA\n        AAgAAAAAAAAAAAAAAAAAAAAAJ7LdWn7T6/+y4/n/i8Dn/67T9v/E4Pz/Zp/T9wAAAACdnZ2uxMTE/6Gh\n        of+Tk5MpAAAAAAAAAAAAAAAAAAAAAIKCgilkman/d77n/7TS8P/l8///rNLv/0iMx+gAAAAAoaGhdbq6\n        uv+/v7//mJiY3ZSUlB8AAAAFAAAABYqKih+Hh4flqKio/3uks/9Ypdj/hbHb/0ad0P8rldFeAAAAAKSk\n        pAyhoaHbxMTE/76+vv+hoaH/lpaW/5OTk/+Xl5f/rq6u/66urv+EhITbAAAACQAAAAAAAAAAAAAAAAAA\n        AAAAAAAApKSkMKKiot68vLz/ysrK/8zMzP/Kysr/wsLC/62trf+MjIzeiYmJMAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAClpaUMo6OjgaCgoLqdnZ3MmpqazJeXl7qUlJSBkJCQDAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAQAAAAAAAI+AAACHgAAAgwAAAIAP\n        AADADwAA4B8AAA==\n</value>\n  </data>\n</root>"
  },
  {
    "path": "Caesar/Diogenes/Forms/TraceForm.Designer.cs",
    "content": "﻿\nnamespace Diogenes\n{\n    partial class TraceForm\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TraceForm));\n            this.menuStrip1 = new System.Windows.Forms.MenuStrip();\n            this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.copyAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.saveToFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.txtTrace = new System.Windows.Forms.TextBox();\n            this.menuStrip1.SuspendLayout();\n            this.SuspendLayout();\n            // \n            // menuStrip1\n            // \n            this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.fileToolStripMenuItem});\n            this.menuStrip1.Location = new System.Drawing.Point(0, 0);\n            this.menuStrip1.Name = \"menuStrip1\";\n            this.menuStrip1.RenderMode = System.Windows.Forms.ToolStripRenderMode.System;\n            this.menuStrip1.Size = new System.Drawing.Size(800, 24);\n            this.menuStrip1.TabIndex = 0;\n            this.menuStrip1.Text = \"menuStrip1\";\n            // \n            // fileToolStripMenuItem\n            // \n            this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.copyAllToolStripMenuItem,\n            this.saveToFileToolStripMenuItem});\n            this.fileToolStripMenuItem.Name = \"fileToolStripMenuItem\";\n            this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);\n            this.fileToolStripMenuItem.Text = \"File\";\n            // \n            // copyAllToolStripMenuItem\n            // \n            this.copyAllToolStripMenuItem.Name = \"copyAllToolStripMenuItem\";\n            this.copyAllToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift) \n            | System.Windows.Forms.Keys.C)));\n            this.copyAllToolStripMenuItem.Size = new System.Drawing.Size(193, 22);\n            this.copyAllToolStripMenuItem.Text = \"Copy All\";\n            this.copyAllToolStripMenuItem.Click += new System.EventHandler(this.copyAllToolStripMenuItem_Click);\n            // \n            // saveToFileToolStripMenuItem\n            // \n            this.saveToFileToolStripMenuItem.Name = \"saveToFileToolStripMenuItem\";\n            this.saveToFileToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S)));\n            this.saveToFileToolStripMenuItem.Size = new System.Drawing.Size(193, 22);\n            this.saveToFileToolStripMenuItem.Text = \"Save to file\";\n            this.saveToFileToolStripMenuItem.Click += new System.EventHandler(this.saveToFileToolStripMenuItem_Click);\n            // \n            // txtTrace\n            // \n            this.txtTrace.Dock = System.Windows.Forms.DockStyle.Fill;\n            this.txtTrace.Font = new System.Drawing.Font(\"Consolas\", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.txtTrace.Location = new System.Drawing.Point(0, 24);\n            this.txtTrace.Multiline = true;\n            this.txtTrace.Name = \"txtTrace\";\n            this.txtTrace.ReadOnly = true;\n            this.txtTrace.ScrollBars = System.Windows.Forms.ScrollBars.Both;\n            this.txtTrace.Size = new System.Drawing.Size(800, 426);\n            this.txtTrace.TabIndex = 1;\n            // \n            // TraceForm\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(800, 450);\n            this.Controls.Add(this.txtTrace);\n            this.Controls.Add(this.menuStrip1);\n            this.Icon = ((System.Drawing.Icon)(resources.GetObject(\"$this.Icon\")));\n            this.MainMenuStrip = this.menuStrip1;\n            this.Name = \"TraceForm\";\n            this.Text = \"Trace\";\n            this.Load += new System.EventHandler(this.TraceForm_Load);\n            this.menuStrip1.ResumeLayout(false);\n            this.menuStrip1.PerformLayout();\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.MenuStrip menuStrip1;\n        private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem copyAllToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem saveToFileToolStripMenuItem;\n        private System.Windows.Forms.TextBox txtTrace;\n    }\n}"
  },
  {
    "path": "Caesar/Diogenes/Forms/TraceForm.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\n\nnamespace Diogenes\n{\n    // trace is generally quite hacky since I did not plan for this early\n    public partial class TraceForm : Form\n    {\n        MainForm ParentMainForm = new MainForm();\n        Timer RefreshTimer = new Timer();\n        public TraceForm(MainForm parentMainForm)\n        {\n            ParentMainForm = parentMainForm;\n            InitializeComponent();\n        }\n\n        private void TraceForm_Load(object sender, EventArgs e)\n        {\n            RefreshTimer.Interval = 50;\n            RefreshTimer.Tick += RefreshTimer_Tick;\n            RefreshTimer.Start();\n        }\n\n        private void RefreshTimer_Tick(object sender, EventArgs e)\n        {\n            if ((ParentMainForm is null) || (ParentMainForm.Connection is null)) \n            {\n                return;\n            }\n            if (txtTrace.Text.Length != ParentMainForm.Connection.CommunicationsLogHighLevel.Length) \n            {\n                lock (ParentMainForm.Connection.WriteLock) \n                {\n                    txtTrace.Text = ParentMainForm.Connection.CommunicationsLogHighLevel.ToString();\n                }\n                txtTrace.SelectionStart = txtTrace.TextLength;\n                txtTrace.ScrollToCaret();\n            }\n            \n        }\n\n        private void copyAllToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            Clipboard.SetText(txtTrace.Text);\n        }\n\n        private void saveToFileToolStripMenuItem_Click(object sender, EventArgs e)\n        {\n            SaveFileDialog sfd = new SaveFileDialog();\n            sfd.Title = \"Specify a location to save your trace\";\n            sfd.Filter = \"txt file (*.txt)|*.txt|All files (*.*)|*.*\";\n            sfd.FileName = $\"Trace_{DateTime.Now.ToString(\"yyyyMMdd_HHmm\")}.txt\";\n            if (sfd.ShowDialog() == DialogResult.OK)\n            {\n                File.WriteAllText(sfd.FileName, txtTrace.Text);\n            }\n\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/Forms/TraceForm.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <metadata name=\"menuStrip1.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>17, 17</value>\n  </metadata>\n  <assembly alias=\"System.Drawing\" name=\"System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\" />\n  <data name=\"$this.Icon\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n    <value>\n        AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAuIdYHLiHWK64h1gsAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALiHWAy4h1jxuIdY97iHWDIAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAuIdY2eLOuv+4h1j4uIdYMQAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAuIdYVbiHWPH59vH/4s25/7iH\n        WP64h1jcuIdY07iHWJG4h1gPAAAAAAAAAAC4h1gVuIdYgbiHWCEAAAAAuIdYh8+ujv/r3tH//fz6//38\n        +v/9+/j/9Ovj//Hn3f/YvqP/uIdY9riHWHIAAAAAAAAACbiHWLO4h1i3uIdYJbiHWOj48ez//fv4//jw\n        5//37+b/9+7k//jw6P/48er//fv5//Lp4P+4h1jYAAAAAAAAAAC4h1ih4s66vbiHWLi4h1jz+vfy//rz\n        7P/48en/+PDn//fv5v/37uT/9uzi//fv5//07OX/uIdY3wAAAAC4h1g8uIdYqvbw6b3izbm9uIdY+/r2\n        8f/69O7/+fLq//jx6f/48Oj/9+/m//fu5P/48en/8+ri/7iHWNq4h1hkzqyMverczr39/Pq9/fz6vbqL\n        Xfv69vL/+vXv//r07v/68+3/+fPr//ny6//48en/+vXv//Pq4v+4h1jauIdYrPjx7L39+/m9+PDnvffv\n        5r3FnHXw5NG+//r28v/69vH/+vbx//r18f/69fH/+vXw//bw6f/cxK3/uIdYrbiHWLP69/K9+vPsvfjx\n        6b348Oe95tPAy8Sbc+67jF77u4xf+7uMXvu4h1j5uIdY77iHWO+4h1jkuIdYhriHWCi4h1iy+vbxvfr0\n        7r358uq9+PHpvfjw6L337+a99+7kvfjx6b3z6uK9uIdYogAAAAAAAAAAAAAAAAAAAAAAAAAAuIdYsvr2\n        8r369e+9+vTuvfrz7b358+u9+fLrvfjx6b369e+98+rivbiHWKIAAAAAAAAAAAAAAAAAAAAAAAAAALiH\n        WJHk0b69+vbyvfr28b369vG9+vXxvfr18b369fC99vDpvdzErb24h1iAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAC4h1gouIdYjriHWLG4h1ixuIdYsbiHWLG4h1ixuIdYsbiHWKm4h1hjuIdYHgAAAAAAAAAAAAAAAAAA\n        AAAAAAAA//8AAPx/AAD8PwAA/h8AAPwBAACIAAAAwAAAAMAAAACAAAAAAAAAAAAAAAAAAAAAAB8AAAAf\n        AAAAHwAAAB8AAA==\n</value>\n  </data>\n</root>"
  },
  {
    "path": "Caesar/Diogenes/Forms/UDSHexEditor.Designer.cs",
    "content": "﻿\nnamespace Diogenes\n{\n    partial class UDSHexEditor\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(UDSHexEditor));\n            this.splitContainer1 = new System.Windows.Forms.SplitContainer();\n            this.gbInputOutput = new System.Windows.Forms.GroupBox();\n            this.chkSendAlfid = new System.Windows.Forms.CheckBox();\n            this.lblDescCmdWrite = new System.Windows.Forms.Label();\n            this.nudWriteCmd = new System.Windows.Forms.NumericUpDown();\n            this.lblDescCmdRead = new System.Windows.Forms.Label();\n            this.nudReadCmd = new System.Windows.Forms.NumericUpDown();\n            this.lblDescIOWidth = new System.Windows.Forms.Label();\n            this.nudIOWidth = new System.Windows.Forms.NumericUpDown();\n            this.lblDescWidth = new System.Windows.Forms.Label();\n            this.nudAddressWidth = new System.Windows.Forms.NumericUpDown();\n            this.gbOperation = new System.Windows.Forms.GroupBox();\n            this.btnSaveToFile = new System.Windows.Forms.Button();\n            this.btnWrite = new System.Windows.Forms.Button();\n            this.btnRead = new System.Windows.Forms.Button();\n            this.gbDestination = new System.Windows.Forms.GroupBox();\n            this.txtDestination = new System.Windows.Forms.TextBox();\n            this.rbSize = new System.Windows.Forms.RadioButton();\n            this.rbAddress = new System.Windows.Forms.RadioButton();\n            this.gbSource = new System.Windows.Forms.GroupBox();\n            this.txtSource = new System.Windows.Forms.TextBox();\n            ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();\n            this.splitContainer1.Panel1.SuspendLayout();\n            this.splitContainer1.SuspendLayout();\n            this.gbInputOutput.SuspendLayout();\n            ((System.ComponentModel.ISupportInitialize)(this.nudWriteCmd)).BeginInit();\n            ((System.ComponentModel.ISupportInitialize)(this.nudReadCmd)).BeginInit();\n            ((System.ComponentModel.ISupportInitialize)(this.nudIOWidth)).BeginInit();\n            ((System.ComponentModel.ISupportInitialize)(this.nudAddressWidth)).BeginInit();\n            this.gbOperation.SuspendLayout();\n            this.gbDestination.SuspendLayout();\n            this.gbSource.SuspendLayout();\n            this.SuspendLayout();\n            // \n            // splitContainer1\n            // \n            this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;\n            this.splitContainer1.Location = new System.Drawing.Point(0, 0);\n            this.splitContainer1.Name = \"splitContainer1\";\n            // \n            // splitContainer1.Panel1\n            // \n            this.splitContainer1.Panel1.Controls.Add(this.gbInputOutput);\n            this.splitContainer1.Panel1.Controls.Add(this.gbOperation);\n            this.splitContainer1.Panel1.Controls.Add(this.gbDestination);\n            this.splitContainer1.Panel1.Controls.Add(this.gbSource);\n            this.splitContainer1.Size = new System.Drawing.Size(929, 595);\n            this.splitContainer1.SplitterDistance = 285;\n            this.splitContainer1.TabIndex = 0;\n            // \n            // gbInputOutput\n            // \n            this.gbInputOutput.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.gbInputOutput.Controls.Add(this.chkSendAlfid);\n            this.gbInputOutput.Controls.Add(this.lblDescCmdWrite);\n            this.gbInputOutput.Controls.Add(this.nudWriteCmd);\n            this.gbInputOutput.Controls.Add(this.lblDescCmdRead);\n            this.gbInputOutput.Controls.Add(this.nudReadCmd);\n            this.gbInputOutput.Controls.Add(this.lblDescIOWidth);\n            this.gbInputOutput.Controls.Add(this.nudIOWidth);\n            this.gbInputOutput.Controls.Add(this.lblDescWidth);\n            this.gbInputOutput.Controls.Add(this.nudAddressWidth);\n            this.gbInputOutput.Location = new System.Drawing.Point(12, 289);\n            this.gbInputOutput.Name = \"gbInputOutput\";\n            this.gbInputOutput.Size = new System.Drawing.Size(264, 295);\n            this.gbInputOutput.TabIndex = 7;\n            this.gbInputOutput.TabStop = false;\n            this.gbInputOutput.Text = \"I/O\";\n            // \n            // chkSendAlfid\n            // \n            this.chkSendAlfid.AutoSize = true;\n            this.chkSendAlfid.Checked = true;\n            this.chkSendAlfid.CheckState = System.Windows.Forms.CheckState.Checked;\n            this.chkSendAlfid.Location = new System.Drawing.Point(9, 270);\n            this.chkSendAlfid.Name = \"chkSendAlfid\";\n            this.chkSendAlfid.Size = new System.Drawing.Size(227, 17);\n            this.chkSendAlfid.TabIndex = 10;\n            this.chkSendAlfid.Text = \"AddressAndLengthFormatID (KW: Disable)\";\n            this.chkSendAlfid.UseVisualStyleBackColor = true;\n            // \n            // lblDescCmdWrite\n            // \n            this.lblDescCmdWrite.AutoSize = true;\n            this.lblDescCmdWrite.Location = new System.Drawing.Point(5, 213);\n            this.lblDescCmdWrite.Name = \"lblDescCmdWrite\";\n            this.lblDescCmdWrite.Size = new System.Drawing.Size(147, 13);\n            this.lblDescCmdWrite.TabIndex = 9;\n            this.lblDescCmdWrite.Text = \"WriteMemoryByAddress (Hex)\";\n            // \n            // nudWriteCmd\n            // \n            this.nudWriteCmd.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.nudWriteCmd.Font = new System.Drawing.Font(\"Consolas\", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.nudWriteCmd.Hexadecimal = true;\n            this.nudWriteCmd.Location = new System.Drawing.Point(6, 232);\n            this.nudWriteCmd.Maximum = new decimal(new int[] {\n            255,\n            0,\n            0,\n            0});\n            this.nudWriteCmd.Name = \"nudWriteCmd\";\n            this.nudWriteCmd.Size = new System.Drawing.Size(250, 32);\n            this.nudWriteCmd.TabIndex = 8;\n            this.nudWriteCmd.Value = new decimal(new int[] {\n            61,\n            0,\n            0,\n            0});\n            // \n            // lblDescCmdRead\n            // \n            this.lblDescCmdRead.AutoSize = true;\n            this.lblDescCmdRead.Location = new System.Drawing.Point(5, 149);\n            this.lblDescCmdRead.Name = \"lblDescCmdRead\";\n            this.lblDescCmdRead.Size = new System.Drawing.Size(148, 13);\n            this.lblDescCmdRead.TabIndex = 7;\n            this.lblDescCmdRead.Text = \"ReadMemoryByAddress (Hex)\";\n            // \n            // nudReadCmd\n            // \n            this.nudReadCmd.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.nudReadCmd.Font = new System.Drawing.Font(\"Consolas\", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.nudReadCmd.Hexadecimal = true;\n            this.nudReadCmd.Location = new System.Drawing.Point(6, 168);\n            this.nudReadCmd.Maximum = new decimal(new int[] {\n            255,\n            0,\n            0,\n            0});\n            this.nudReadCmd.Name = \"nudReadCmd\";\n            this.nudReadCmd.Size = new System.Drawing.Size(250, 32);\n            this.nudReadCmd.TabIndex = 6;\n            this.nudReadCmd.Value = new decimal(new int[] {\n            35,\n            0,\n            0,\n            0});\n            // \n            // lblDescIOWidth\n            // \n            this.lblDescIOWidth.AutoSize = true;\n            this.lblDescIOWidth.Location = new System.Drawing.Point(5, 85);\n            this.lblDescIOWidth.Name = \"lblDescIOWidth\";\n            this.lblDescIOWidth.Size = new System.Drawing.Size(82, 13);\n            this.lblDescIOWidth.TabIndex = 5;\n            this.lblDescIOWidth.Text = \"I/O Width (Hex)\";\n            // \n            // nudIOWidth\n            // \n            this.nudIOWidth.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.nudIOWidth.Font = new System.Drawing.Font(\"Consolas\", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.nudIOWidth.Hexadecimal = true;\n            this.nudIOWidth.Location = new System.Drawing.Point(6, 104);\n            this.nudIOWidth.Maximum = new decimal(new int[] {\n            255,\n            0,\n            0,\n            0});\n            this.nudIOWidth.Minimum = new decimal(new int[] {\n            1,\n            0,\n            0,\n            0});\n            this.nudIOWidth.Name = \"nudIOWidth\";\n            this.nudIOWidth.Size = new System.Drawing.Size(250, 32);\n            this.nudIOWidth.TabIndex = 4;\n            this.nudIOWidth.Value = new decimal(new int[] {\n            16,\n            0,\n            0,\n            0});\n            // \n            // lblDescWidth\n            // \n            this.lblDescWidth.AutoSize = true;\n            this.lblDescWidth.Location = new System.Drawing.Point(6, 21);\n            this.lblDescWidth.Name = \"lblDescWidth\";\n            this.lblDescWidth.Size = new System.Drawing.Size(76, 13);\n            this.lblDescWidth.TabIndex = 3;\n            this.lblDescWidth.Text = \"Address Width\";\n            // \n            // nudAddressWidth\n            // \n            this.nudAddressWidth.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.nudAddressWidth.Font = new System.Drawing.Font(\"Consolas\", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.nudAddressWidth.Hexadecimal = true;\n            this.nudAddressWidth.Location = new System.Drawing.Point(8, 40);\n            this.nudAddressWidth.Maximum = new decimal(new int[] {\n            5,\n            0,\n            0,\n            0});\n            this.nudAddressWidth.Minimum = new decimal(new int[] {\n            1,\n            0,\n            0,\n            0});\n            this.nudAddressWidth.Name = \"nudAddressWidth\";\n            this.nudAddressWidth.Size = new System.Drawing.Size(250, 32);\n            this.nudAddressWidth.TabIndex = 2;\n            this.nudAddressWidth.Value = new decimal(new int[] {\n            4,\n            0,\n            0,\n            0});\n            // \n            // gbOperation\n            // \n            this.gbOperation.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.gbOperation.Controls.Add(this.btnSaveToFile);\n            this.gbOperation.Controls.Add(this.btnWrite);\n            this.gbOperation.Controls.Add(this.btnRead);\n            this.gbOperation.Location = new System.Drawing.Point(12, 171);\n            this.gbOperation.Name = \"gbOperation\";\n            this.gbOperation.Size = new System.Drawing.Size(264, 112);\n            this.gbOperation.TabIndex = 6;\n            this.gbOperation.TabStop = false;\n            this.gbOperation.Text = \"Operation\";\n            // \n            // btnSaveToFile\n            // \n            this.btnSaveToFile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.btnSaveToFile.Location = new System.Drawing.Point(8, 77);\n            this.btnSaveToFile.Name = \"btnSaveToFile\";\n            this.btnSaveToFile.Size = new System.Drawing.Size(250, 23);\n            this.btnSaveToFile.TabIndex = 2;\n            this.btnSaveToFile.Text = \"Save Displayed Data\";\n            this.btnSaveToFile.UseVisualStyleBackColor = true;\n            this.btnSaveToFile.Click += new System.EventHandler(this.btnSaveToFile_Click);\n            // \n            // btnWrite\n            // \n            this.btnWrite.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.btnWrite.Location = new System.Drawing.Point(8, 48);\n            this.btnWrite.Name = \"btnWrite\";\n            this.btnWrite.Size = new System.Drawing.Size(250, 23);\n            this.btnWrite.TabIndex = 1;\n            this.btnWrite.Text = \"Write\";\n            this.btnWrite.UseVisualStyleBackColor = true;\n            this.btnWrite.Click += new System.EventHandler(this.btnWrite_Click);\n            // \n            // btnRead\n            // \n            this.btnRead.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.btnRead.Location = new System.Drawing.Point(8, 19);\n            this.btnRead.Name = \"btnRead\";\n            this.btnRead.Size = new System.Drawing.Size(250, 23);\n            this.btnRead.TabIndex = 0;\n            this.btnRead.Text = \"Read\";\n            this.btnRead.UseVisualStyleBackColor = true;\n            this.btnRead.Click += new System.EventHandler(this.btnRead_Click);\n            // \n            // gbDestination\n            // \n            this.gbDestination.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.gbDestination.Controls.Add(this.txtDestination);\n            this.gbDestination.Controls.Add(this.rbSize);\n            this.gbDestination.Controls.Add(this.rbAddress);\n            this.gbDestination.Location = new System.Drawing.Point(12, 78);\n            this.gbDestination.Name = \"gbDestination\";\n            this.gbDestination.Size = new System.Drawing.Size(264, 87);\n            this.gbDestination.TabIndex = 3;\n            this.gbDestination.TabStop = false;\n            this.gbDestination.Text = \"Destination (Hex)\";\n            // \n            // txtDestination\n            // \n            this.txtDestination.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.txtDestination.Font = new System.Drawing.Font(\"Consolas\", 16F);\n            this.txtDestination.Location = new System.Drawing.Point(8, 19);\n            this.txtDestination.Name = \"txtDestination\";\n            this.txtDestination.Size = new System.Drawing.Size(250, 32);\n            this.txtDestination.TabIndex = 3;\n            this.txtDestination.Text = \"0\";\n            // \n            // rbSize\n            // \n            this.rbSize.AutoSize = true;\n            this.rbSize.Location = new System.Drawing.Point(77, 57);\n            this.rbSize.Name = \"rbSize\";\n            this.rbSize.Size = new System.Drawing.Size(45, 17);\n            this.rbSize.TabIndex = 5;\n            this.rbSize.Text = \"Size\";\n            this.rbSize.UseVisualStyleBackColor = true;\n            // \n            // rbAddress\n            // \n            this.rbAddress.AutoSize = true;\n            this.rbAddress.Checked = true;\n            this.rbAddress.Location = new System.Drawing.Point(8, 57);\n            this.rbAddress.Name = \"rbAddress\";\n            this.rbAddress.Size = new System.Drawing.Size(63, 17);\n            this.rbAddress.TabIndex = 4;\n            this.rbAddress.TabStop = true;\n            this.rbAddress.Text = \"Address\";\n            this.rbAddress.UseVisualStyleBackColor = true;\n            // \n            // gbSource\n            // \n            this.gbSource.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.gbSource.Controls.Add(this.txtSource);\n            this.gbSource.Location = new System.Drawing.Point(12, 12);\n            this.gbSource.Name = \"gbSource\";\n            this.gbSource.Size = new System.Drawing.Size(264, 60);\n            this.gbSource.TabIndex = 2;\n            this.gbSource.TabStop = false;\n            this.gbSource.Text = \"Source Address (Hex)\";\n            // \n            // txtSource\n            // \n            this.txtSource.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.txtSource.Font = new System.Drawing.Font(\"Consolas\", 16F);\n            this.txtSource.Location = new System.Drawing.Point(8, 19);\n            this.txtSource.Name = \"txtSource\";\n            this.txtSource.Size = new System.Drawing.Size(250, 32);\n            this.txtSource.TabIndex = 2;\n            this.txtSource.Text = \"0\";\n            // \n            // UDSHexEditor\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(929, 595);\n            this.Controls.Add(this.splitContainer1);\n            this.Icon = ((System.Drawing.Icon)(resources.GetObject(\"$this.Icon\")));\n            this.Name = \"UDSHexEditor\";\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\n            this.Text = \"UDS Hex Editor\";\n            this.Load += new System.EventHandler(this.UDSHexEditor_Load);\n            this.splitContainer1.Panel1.ResumeLayout(false);\n            ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();\n            this.splitContainer1.ResumeLayout(false);\n            this.gbInputOutput.ResumeLayout(false);\n            this.gbInputOutput.PerformLayout();\n            ((System.ComponentModel.ISupportInitialize)(this.nudWriteCmd)).EndInit();\n            ((System.ComponentModel.ISupportInitialize)(this.nudReadCmd)).EndInit();\n            ((System.ComponentModel.ISupportInitialize)(this.nudIOWidth)).EndInit();\n            ((System.ComponentModel.ISupportInitialize)(this.nudAddressWidth)).EndInit();\n            this.gbOperation.ResumeLayout(false);\n            this.gbDestination.ResumeLayout(false);\n            this.gbDestination.PerformLayout();\n            this.gbSource.ResumeLayout(false);\n            this.gbSource.PerformLayout();\n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.SplitContainer splitContainer1;\n        private System.Windows.Forms.GroupBox gbOperation;\n        private System.Windows.Forms.Button btnWrite;\n        private System.Windows.Forms.Button btnRead;\n        private System.Windows.Forms.GroupBox gbDestination;\n        private System.Windows.Forms.RadioButton rbSize;\n        private System.Windows.Forms.RadioButton rbAddress;\n        private System.Windows.Forms.GroupBox gbSource;\n        private System.Windows.Forms.GroupBox gbInputOutput;\n        private System.Windows.Forms.Label lblDescWidth;\n        private System.Windows.Forms.NumericUpDown nudAddressWidth;\n        private System.Windows.Forms.Label lblDescCmdWrite;\n        private System.Windows.Forms.NumericUpDown nudWriteCmd;\n        private System.Windows.Forms.Label lblDescCmdRead;\n        private System.Windows.Forms.NumericUpDown nudReadCmd;\n        private System.Windows.Forms.Label lblDescIOWidth;\n        private System.Windows.Forms.NumericUpDown nudIOWidth;\n        private System.Windows.Forms.TextBox txtDestination;\n        private System.Windows.Forms.TextBox txtSource;\n        private System.Windows.Forms.Button btnSaveToFile;\n        private System.Windows.Forms.CheckBox chkSendAlfid;\n    }\n}"
  },
  {
    "path": "Caesar/Diogenes/Forms/UDSHexEditor.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\nusing System.IO;\nusing Be.Windows.Forms;\nusing Caesar;\nusing System.Globalization;\n\nnamespace Diogenes\n{\n    public partial class UDSHexEditor : Form\n    {\n        ECUConnection Connection;\n        HexBox Hexbox;\n        byte[] OriginalBuffer = new byte[] { };\n        public UDSHexEditor(ECUConnection connection)\n        {\n            InitializeComponent();\n            Connection = connection;\n\n            // missing docs for HexBox : https://stackoverflow.com/questions/53410380/how-to-create-hex-editor-inside-of-winforms-app\n            Hexbox = new HexBox() \n            {\n                /*\n                UseFixedBytesPerLine = true,\n                BytesPerLine = 16,\n                */\n                ColumnInfoVisible = true,\n                LineInfoVisible = true,\n                StringViewVisible = true,\n                VScrollBarVisible = true\n            };\n            Hexbox.Dock = DockStyle.Fill;\n            splitContainer1.Panel2.Controls.Add(Hexbox);\n\n            Hexbox.LineInfoOffset = 0;\n            Hexbox.ByteProvider = new DynamicByteProvider(new byte[] { });\n        }\n\n        private void UDSHexEditor_Load(object sender, EventArgs e)\n        {\n\n        }\n\n        private static void GatewayWait() \n        {\n            System.Threading.Thread.Sleep(150);\n            Application.DoEvents();\n        }\n\n        private void btnRead_Click(object sender, EventArgs e)\n        {\n            if (!FetchAndValidateInput(out uint sourceAddress, out uint destinationAddress, out uint bufferSize))\n            {\n                return;\n            }\n\n            int strideWidth = decimal.ToInt32(nudIOWidth.Value);\n            int addressWidth = decimal.ToInt32(nudAddressWidth.Value);\n            int ioDigitCount = GetMemoryDigitCount(strideWidth);\n            byte readCmd = decimal.ToByte(nudReadCmd.Value);\n            byte positiveResponse = (byte)(readCmd + 0x40);\n\n            byte alfid = GetAddressAndLengthFormatIdentifier(\n                        addressWidth,\n                        ioDigitCount\n                    );\n\n            GenericLoader loader = new GenericLoader();\n            loader.Text = \"Reading from ECU\";\n            loader.SetProgressMax((int)(destinationAddress - sourceAddress));\n            loader.SetProgressValue(0);\n            loader.TopMost = true;\n            loader.Show();\n            Application.DoEvents();\n\n            byte[] memoryBuffer = new byte[bufferSize];\n            uint readCursor = sourceAddress;\n            int bufferCursor = 0;\n            bool hasBadReads = false;\n\n            while (readCursor < destinationAddress)\n            {\n                loader.Text = $\"Reading from ECU : 0x{readCursor:X8}\";\n                loader.SetProgressValue((int)(readCursor - sourceAddress));\n                Application.DoEvents();\n\n                uint remainder = destinationAddress - readCursor;\n                int readSize = strideWidth;\n                if (readSize > remainder) \n                {\n                    readSize = (int)remainder;\n                }\n                List<byte> readCommand = CreateReadCommand(readCmd, alfid, readCursor, addressWidth, readSize, chkSendAlfid.Checked);\n\n                byte[] response = Connection.SendMessage(readCommand);\n                if (response[0] == positiveResponse)\n                {\n                    Array.ConstrainedCopy(response, 1, memoryBuffer, bufferCursor, readSize);\n                }\n                else \n                {\n                    hasBadReads = true;\n                }\n\n                readCursor += (uint)readSize;\n                bufferCursor += readSize;\n\n                // waiting for a moment here; if there is a gateway (e.g. 500k<->83.3k), let it take a breather\n                GatewayWait();\n            }\n\n            loader.Close();\n            Application.DoEvents();\n\n            OriginalBuffer = memoryBuffer;\n\n            Hexbox.LineInfoOffset = sourceAddress;\n            Hexbox.ByteProvider = new DynamicByteProvider(OriginalBuffer);\n\n            if (hasBadReads) \n            {\n                MessageBox.Show(\"One or more read requests were rejected by the ECU, and the empty blocks were substituted with zeros. \\r\\n\\r\\n\" +\n                    \"Please check if the memory address is valid to the ECU, and if the ECU has been unlocked if required.\\r\\n\\r\\n\" +\n                    \"If the memory region has protected bytes, consider loading a smaller, more specific range with a I/O width of 1 to skip past the protected bytes.\", \n                    \"Warning: Invalid reads\");\n            }\n        }\n\n        private List<byte> CreateReadCommand(byte readCmd, byte alfid, long sourceAddress, int addressWidth, int ioWidth, bool includeAlfid)\n        {\n            List<byte> readCommand = new List<byte>();\n            readCommand.Add(readCmd); // command\n            if (includeAlfid)\n            {\n                readCommand.Add(alfid);   // addressing and memory mode\n            }\n            readCommand.AddRange(ValueToBEByteArrayConstrained(sourceAddress, addressWidth)); // address, constrained to earlier specified width\n            readCommand.AddRange(ValueToBEByteArray(ioWidth)); // should actually be constrained too, based on alfid\n            return readCommand;\n        }\n        private List<byte> CreateWriteCommand(byte writeCmd, long destAddress, int addressWidth, byte[] payload, bool includeAlfid)\n        {\n            int ioDigitCount = GetMemoryDigitCount(payload.Length);\n            byte alfid = GetAddressAndLengthFormatIdentifier(\n                        addressWidth,\n                        ioDigitCount\n                    );\n            List<byte> writeCommand = new List<byte>();\n            writeCommand.Add(writeCmd); // command\n            if (includeAlfid)\n            {\n                writeCommand.Add(alfid);   // addressing and memory mode\n            }\n            writeCommand.AddRange(ValueToBEByteArrayConstrained(destAddress, addressWidth)); // address, constrained to earlier specified width\n            writeCommand.AddRange(ValueToBEByteArray(payload.Length)); // should actually be constrained too, based on alfid\n            writeCommand.AddRange(payload);\n            return writeCommand;\n        }\n\n\n        private List<byte> ValueToBEByteArrayConstrained(long inValue, int size)\n        {\n            List<byte> result = new List<byte>();\n            for (int i = 0; i < size; i++) \n            {\n                byte row = (byte)(inValue & 0xFF);\n                result.Insert(0, row);\n                inValue >>= 8;\n            }\n            return result;\n        }\n\n        // unconstrained size\n        private List<byte> ValueToBEByteArray(long inValue) \n        {\n            List<byte> result = new List<byte>();\n            while (inValue > 0) \n            {\n                byte row = (byte)(inValue & 0xFF);\n                result.Insert(0, row);\n                inValue >>= 8;\n            }\n            return result;\n        }\n\n        private static int GetMemoryDigitCount(int value) \n        {\n            int count = 0;\n            while (value > 0) \n            {\n                count++;\n                value >>= 8;\n            }\n            return count;\n        }\n\n        private static byte GetAddressAndLengthFormatIdentifier(int addressSizeInBytes, int memorySizeInBytes) \n        {\n            /*\n            address map in bits:\n            8 bits  : 1\n            16 bits : 2\n            24 bits : 3\n            32 bits : 4\n            40 bits : 5\n\n            memory size map in bits:\n            8 bits  : 1\n            16 bits : 2\n            24 bits : 3\n            32 bits : 4\n             */\n            if ((addressSizeInBytes < 1) || (addressSizeInBytes > 5))\n            {\n                throw new ArgumentOutOfRangeException(\"Invalid address size for ALFID\");\n            }\n            if ((memorySizeInBytes < 1) || (memorySizeInBytes > 5))\n            {\n                throw new ArgumentOutOfRangeException(\"Invalid memory size for ALFID\");\n            }\n            return (byte)((memorySizeInBytes << 4) | addressSizeInBytes);\n        }\n\n        private bool FetchAndValidateInput(out uint sourceAddress_, out uint destinationAddress_, out uint bufferSize) \n        {\n            sourceAddress_ = 0;\n            destinationAddress_ = 0;\n            bufferSize = 0;\n            if (!uint.TryParse(txtSource.Text, System.Globalization.NumberStyles.HexNumber, CultureInfo.InvariantCulture, out uint sourceAddress))\n            {\n                MessageBox.Show($\"Please check the source address : could not parse '{txtSource.Text}'\");\n                return false;\n            }\n            if (!uint.TryParse(txtDestination.Text, System.Globalization.NumberStyles.HexNumber, CultureInfo.InvariantCulture, out uint destinationAddress))\n            {\n                MessageBox.Show($\"Please check the destination address : could not parse '{txtDestination.Text}'\");\n                return false;\n            }\n\n            if (rbSize.Checked)\n            {\n                destinationAddress += sourceAddress;\n            }\n            if (destinationAddress < sourceAddress)\n            {\n                MessageBox.Show($\"Destination position cannot be lower than the source address.\");\n                return false;\n            }\n\n            sourceAddress_ = sourceAddress;\n            destinationAddress_ = destinationAddress;\n            bufferSize = destinationAddress - sourceAddress;\n            const uint sizeLimitMB = 50;\n            if (bufferSize > (sizeLimitMB * 1024 * 1024))\n            {\n                MessageBox.Show($\"Buffer size is above {sizeLimitMB}MB. Please read in smaller chunks.\");\n                return false;\n            }\n            return true;\n        }\n\n        private bool BytearrayEqual(byte[] a, byte[] b) \n        {\n            if (a.Length != b.Length) \n            {\n                return false;\n            }\n            for (int i = 0; i < a.Length; i++) \n            {\n                if (a[i] != b[i]) \n                {\n                    return false;\n                } \n            }\n            return true;\n        }\n\n        private void btnWrite_Click(object sender, EventArgs e)\n        {\n            if (!FetchAndValidateInput(out uint sourceAddress, out uint destinationAddress, out uint bufferSize))\n            {\n                return;\n            }\n\n            byte[] memoryBuffer = ((DynamicByteProvider)Hexbox.ByteProvider).Bytes.ToArray();\n\n            if (memoryBuffer.Length != OriginalBuffer.Length) \n            {\n                MessageBox.Show(\"Please read the memory region first, before attempting to write.\");\n            }\n\n            int strideWidth = decimal.ToInt32(nudIOWidth.Value);\n            int addressWidth = decimal.ToInt32(nudAddressWidth.Value);\n            byte writeCmd = decimal.ToByte(nudWriteCmd.Value);\n            byte positiveResponse = (byte)(writeCmd + 0x40);\n\n            uint writeCursor = sourceAddress;\n            int bufferCursor = 0;\n            bool hasBadWrites = false;\n\n            while (writeCursor < destinationAddress)\n            {\n                uint remainder = destinationAddress - writeCursor;\n                int writeSizeChunk = strideWidth;\n                if (writeSizeChunk > remainder)\n                {\n                    writeSizeChunk = (int)remainder;\n                }\n\n                byte[] dataToWrite = new byte[writeSizeChunk];\n                byte[] originalData = new byte[writeSizeChunk];\n                Array.ConstrainedCopy(memoryBuffer, bufferCursor, dataToWrite, 0, writeSizeChunk);\n                // consider checking in-place\n                Array.ConstrainedCopy(OriginalBuffer, bufferCursor, originalData, 0, writeSizeChunk);\n\n                // skip writes to unmodified chunks\n                if (!BytearrayEqual(dataToWrite, originalData))\n                {\n                    List<byte> writeCommand = CreateWriteCommand(writeCmd, writeCursor, addressWidth, dataToWrite, chkSendAlfid.Checked);\n\n                    byte[] response = Connection.SendMessage(writeCommand);\n                    if (response[0] != positiveResponse)\n                    {\n                        hasBadWrites = true;\n                    }\n                }\n                writeCursor += (uint)writeSizeChunk;\n                bufferCursor += writeSizeChunk;\n\n                GatewayWait();\n            }\n\n            if (hasBadWrites)\n            {\n                MessageBox.Show(\"One or more write requests were rejected by the ECU\\r\\n\\r\\n\" +\n                    \"Please check if the memory address is valid to the ECU, and if the ECU has been unlocked if required.\\r\\n\\r\\n\",\n                    \"Warning: Write command rejected\");\n            }\n            else\n            {\n                MessageBox.Show(\"Write complete\");\n            }\n        }\n\n        private void btnSaveToFile_Click(object sender, EventArgs e)\n        {\n            byte[] memoryBuffer = ((DynamicByteProvider)Hexbox.ByteProvider).Bytes.ToArray();\n            SaveFileDialog sfd = new SaveFileDialog();\n            sfd.Title = \"Specify a location to save your binary data\";\n            sfd.Filter = \"BIN files (*.bin)|*.bin|All files (*.*)|*.*\";\n            if (sfd.ShowDialog() == DialogResult.OK)\n            {\n                File.WriteAllBytes(sfd.FileName, memoryBuffer);\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/Forms/UDSHexEditor.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <assembly alias=\"System.Drawing\" name=\"System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\" />\n  <data name=\"$this.Icon\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n    <value>\n        AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAANaecsTTmW700ZZo/86SY//Ljl7/yYpb/8eHVv/DhFL/w4RS/8OEUv/DhFL/w4RS/8OE\n        Uv+7d0KwAAAAAAAAAADXoXX/+PLt//fw6v/27eb/9Ori//Pn3v/x5Nv/8OLY//Di2P/w4tj/8OLY//Di\n        2P/w4tj/xYpd/QAAAAAAAAAA2aR6//nz7v/r0r7//////+vTv//////////////////qx63/////////\n        ////////8OLY/8aMX/8AAAAAAAAAAN2ofv/58+//69C6/+vQu//r0Lv/69C7/+vQu//r0b3/6s21/+rN\n        tf/qzbX/6s21//Di2P/Gilz/AAAAAAAAAADfqoL/+fPv/+rOt///////69C7/////////////////+rP\n        uv/79vL////////////w4tj/yI1f/wAAAAAAAAAA4a6H//r08P/qy7L/6syz/+rMs//qzLP/6syz/+rO\n        t//ox6z/6Mes/+jIsP/oyK7/8OLY/8SGVP8AAAAAAAAAAOOxjP/69vH/6smu///////qybD/////////\n        ////////6Mes//////////////////Hl2//GhlX/AAAAAAAAAADltI//+vby/+nGqv/pxqz/6ses/+nH\n        rf/pya7/6cmw/+jHrP/pybD/6Miw/+jMtf/y597/yIpZ/wAAAAAAAAAA57eU//v39P/pw6b//////+jE\n        qf/////////////////ox6z/////////////////9/Hr/8uPX/8AAAAAAAAAAOm6mP/79/T/6cOm/+nD\n        pv/pw6b/6cOm/+nDpv/pw6b/6cOm/+nDpv/pw6b/6cOm//v39P/Ok2T/AAAAAAAAAADrvZv/+/f0////\n        ///////////////////////////////////////////////////79/T/0Zdq/wAAAAAAAAAA7L+e//v3\n        9P+c1aX/mNOh/5TQnf+Qzpj/i8uT/4fJjv+Cxon/fsOE/3rBgP92vnz/+/f0/9Sbb/8AAAAAAAAAAO7B\n        oev79/T/+/f0//v39P/79/T/+/f0//v39P/79/T/+/f0//v39P/79/T/+/f0//v39P/XoHT4AAAAAAAA\n        AADvwqN+78Gi4+3An//rvp3/67ya/+m6lv/nt5P/5rWQ/+SyjP/ir4j/4KyE/92pgP/cpX3/2qN6ygAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAA//8AAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIAB\n        AACAAQAA//8AAA==\n</value>\n  </data>\n</root>"
  },
  {
    "path": "Caesar/Diogenes/Forms/VCForm.Designer.cs",
    "content": "﻿namespace Diogenes\n{\n    partial class VCForm\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.components = new System.ComponentModel.Container();\n            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(VCForm));\n            this.groupBox1 = new System.Windows.Forms.GroupBox();\n            this.btnApply = new System.Windows.Forms.Button();\n            this.btnReinterpret = new System.Windows.Forms.Button();\n            this.btnCopy = new System.Windows.Forms.Button();\n            this.radioButton1 = new System.Windows.Forms.RadioButton();\n            this.rbHex = new System.Windows.Forms.RadioButton();\n            this.txtCodingString = new System.Windows.Forms.TextBox();\n            this.groupBox2 = new System.Windows.Forms.GroupBox();\n            this.dgvMain = new System.Windows.Forms.DataGridView();\n            this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);\n            this.groupBox1.SuspendLayout();\n            this.groupBox2.SuspendLayout();\n            ((System.ComponentModel.ISupportInitialize)(this.dgvMain)).BeginInit();\n            this.SuspendLayout();\n            // \n            // groupBox1\n            // \n            this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.groupBox1.Controls.Add(this.btnApply);\n            this.groupBox1.Controls.Add(this.btnReinterpret);\n            this.groupBox1.Controls.Add(this.btnCopy);\n            this.groupBox1.Controls.Add(this.radioButton1);\n            this.groupBox1.Controls.Add(this.rbHex);\n            this.groupBox1.Controls.Add(this.txtCodingString);\n            this.groupBox1.Location = new System.Drawing.Point(12, 12);\n            this.groupBox1.Name = \"groupBox1\";\n            this.groupBox1.Size = new System.Drawing.Size(1225, 81);\n            this.groupBox1.TabIndex = 0;\n            this.groupBox1.TabStop = false;\n            this.groupBox1.Text = \"Computed Values\";\n            // \n            // btnApply\n            // \n            this.btnApply.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));\n            this.btnApply.Location = new System.Drawing.Point(1144, 51);\n            this.btnApply.Name = \"btnApply\";\n            this.btnApply.Size = new System.Drawing.Size(75, 23);\n            this.btnApply.TabIndex = 5;\n            this.btnApply.Text = \"Write\";\n            this.btnApply.UseVisualStyleBackColor = true;\n            this.btnApply.Click += new System.EventHandler(this.btnApply_Click);\n            // \n            // btnReinterpret\n            // \n            this.btnReinterpret.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));\n            this.btnReinterpret.Location = new System.Drawing.Point(1063, 51);\n            this.btnReinterpret.Name = \"btnReinterpret\";\n            this.btnReinterpret.Size = new System.Drawing.Size(75, 23);\n            this.btnReinterpret.TabIndex = 4;\n            this.btnReinterpret.Text = \"Reinterpret\";\n            this.btnReinterpret.UseVisualStyleBackColor = true;\n            this.btnReinterpret.Click += new System.EventHandler(this.btnReinterpret_Click);\n            // \n            // btnCopy\n            // \n            this.btnCopy.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));\n            this.btnCopy.Location = new System.Drawing.Point(982, 51);\n            this.btnCopy.Name = \"btnCopy\";\n            this.btnCopy.Size = new System.Drawing.Size(75, 23);\n            this.btnCopy.TabIndex = 3;\n            this.btnCopy.Text = \"Copy\";\n            this.btnCopy.UseVisualStyleBackColor = true;\n            this.btnCopy.Click += new System.EventHandler(this.btnCopy_Click);\n            // \n            // radioButton1\n            // \n            this.radioButton1.AutoSize = true;\n            this.radioButton1.Location = new System.Drawing.Point(56, 54);\n            this.radioButton1.Name = \"radioButton1\";\n            this.radioButton1.Size = new System.Drawing.Size(45, 17);\n            this.radioButton1.TabIndex = 2;\n            this.radioButton1.Text = \"Dec\";\n            this.radioButton1.UseVisualStyleBackColor = true;\n            this.radioButton1.CheckedChanged += new System.EventHandler(this.radioButton1_CheckedChanged);\n            // \n            // rbHex\n            // \n            this.rbHex.AutoSize = true;\n            this.rbHex.Checked = true;\n            this.rbHex.Location = new System.Drawing.Point(6, 54);\n            this.rbHex.Name = \"rbHex\";\n            this.rbHex.Size = new System.Drawing.Size(44, 17);\n            this.rbHex.TabIndex = 1;\n            this.rbHex.TabStop = true;\n            this.rbHex.Text = \"Hex\";\n            this.rbHex.UseVisualStyleBackColor = true;\n            this.rbHex.CheckedChanged += new System.EventHandler(this.rbHex_CheckedChanged);\n            // \n            // txtCodingString\n            // \n            this.txtCodingString.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.txtCodingString.Font = new System.Drawing.Font(\"Consolas\", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.txtCodingString.Location = new System.Drawing.Point(6, 19);\n            this.txtCodingString.Name = \"txtCodingString\";\n            this.txtCodingString.Size = new System.Drawing.Size(1213, 26);\n            this.txtCodingString.TabIndex = 0;\n            // \n            // groupBox2\n            // \n            this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.groupBox2.Controls.Add(this.dgvMain);\n            this.groupBox2.Location = new System.Drawing.Point(12, 99);\n            this.groupBox2.Name = \"groupBox2\";\n            this.groupBox2.Size = new System.Drawing.Size(1225, 507);\n            this.groupBox2.TabIndex = 1;\n            this.groupBox2.TabStop = false;\n            this.groupBox2.Text = \"Variant Configuration\";\n            // \n            // dgvMain\n            // \n            this.dgvMain.AllowUserToAddRows = false;\n            this.dgvMain.AllowUserToDeleteRows = false;\n            this.dgvMain.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) \n            | System.Windows.Forms.AnchorStyles.Left) \n            | System.Windows.Forms.AnchorStyles.Right)));\n            this.dgvMain.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;\n            this.dgvMain.ContextMenuStrip = this.contextMenuStrip1;\n            this.dgvMain.Location = new System.Drawing.Point(6, 19);\n            this.dgvMain.Name = \"dgvMain\";\n            this.dgvMain.ReadOnly = true;\n            this.dgvMain.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;\n            this.dgvMain.ShowEditingIcon = false;\n            this.dgvMain.Size = new System.Drawing.Size(1213, 482);\n            this.dgvMain.TabIndex = 0;\n            // \n            // contextMenuStrip1\n            // \n            this.contextMenuStrip1.Name = \"contextMenuStrip1\";\n            this.contextMenuStrip1.RenderMode = System.Windows.Forms.ToolStripRenderMode.System;\n            this.contextMenuStrip1.Size = new System.Drawing.Size(61, 4);\n            this.contextMenuStrip1.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuStrip1_Opening);\n            // \n            // VCForm\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(1249, 618);\n            this.Controls.Add(this.groupBox2);\n            this.Controls.Add(this.groupBox1);\n            this.Icon = ((System.Drawing.Icon)(resources.GetObject(\"$this.Icon\")));\n            this.Name = \"VCForm\";\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\n            this.Text = \"Variant Coding\";\n            this.Load += new System.EventHandler(this.VCForm_Load);\n            this.groupBox1.ResumeLayout(false);\n            this.groupBox1.PerformLayout();\n            this.groupBox2.ResumeLayout(false);\n            ((System.ComponentModel.ISupportInitialize)(this.dgvMain)).EndInit();\n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.GroupBox groupBox1;\n        private System.Windows.Forms.Button btnReinterpret;\n        private System.Windows.Forms.Button btnCopy;\n        private System.Windows.Forms.RadioButton radioButton1;\n        private System.Windows.Forms.RadioButton rbHex;\n        private System.Windows.Forms.TextBox txtCodingString;\n        private System.Windows.Forms.Button btnApply;\n        private System.Windows.Forms.GroupBox groupBox2;\n        private System.Windows.Forms.DataGridView dgvMain;\n        private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;\n    }\n}"
  },
  {
    "path": "Caesar/Diogenes/Forms/VCForm.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Data;\nusing System.Drawing;\nusing System.Linq;\nusing System.Reflection;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\nusing Caesar;\n\nnamespace Diogenes\n{\n    public partial class VCForm : Form\n    {\n        ECU SelectedECU;\n        ECUVariant ECUVariant;\n        VCDomain VariantCodingDomain;\n        string ECUName;\n        string VariantName;\n        string VCDomainName;\n        public byte[] VCValue;\n        public byte[] UnfilteredReadValue;\n\n        public DiagService ReadService;\n        public DiagService WriteService;\n\n        public VCForm(CaesarContainer container, string ecuName, string variantName, string vcDomain, ECUConnection connection)\n        {\n            InitializeComponent();\n\n            ECUName = ecuName;\n            VariantName = variantName;\n            VCDomainName = vcDomain;\n\n            SelectedECU = container.GetECUByName(ecuName);\n            ECUVariant = container.GetECUVariantByName(variantName);\n            VariantCodingDomain = ECUVariant.GetVCDomainByName(VCDomainName);\n\n            ReadService = ECUVariant.GetDiagServiceByName(VariantCodingDomain.ReadServiceName);\n            WriteService = ECUVariant.GetDiagServiceByName(VariantCodingDomain.WriteServiceName);\n            if ((ReadService is null) || (WriteService is null))\n            {\n                Console.WriteLine(\"VC Dialog: Unable to proceed - could not find referenced diagnostic services\");\n                this.Close();\n            }\n\n            //Console.WriteLine(ReadService.Qualifier);\n            //Console.WriteLine(WriteService.Qualifier);\n\n            VCValue = new byte[VariantCodingDomain.DumpSize];\n            UnfilteredReadValue = new byte[] { };\n\n            foreach (Tuple<string, byte[]> row in VariantCodingDomain.DefaultData)\n            {\n                if (row.Item1.ToLower() == \"default\" && (row.Item2.Length == VariantCodingDomain.DumpSize))\n                {\n                    VCValue = row.Item2;\n                    Console.WriteLine(\"Default CBF variant coding data is available\");\n                    break;\n                }\n            }\n\n            if (connection.State >= ECUConnection.ConnectionState.ChannelConnectedPendingEcuContact)\n            {\n                // Console.WriteLine($\"Requesting variant coding read: {ReadService.Qualifier} : ({BitUtility.BytesToHex(ReadService.RequestBytes)})\");\n                byte[] response = connection.SendDiagRequest(ReadService);\n\n                DiagPreparation largestPrep = GetLargestPreparation(ReadService.OutputPreparations);\n                if (largestPrep.PresPoolIndex > -1)\n                {\n                    // DiagPresentation pres = SelectedECU.GlobalPresentations[largestPrep.PresPoolIndex];\n                    // pres.PrintDebug();\n                }\n                // Console.WriteLine($\"Variant coding received: {BitUtility.BytesToHex(response)}\");\n\n                VCValue = response.Skip(largestPrep.BitPosition / 8).Take(largestPrep.SizeInBits / 8).ToArray();\n                // store the received VC: when writing back, we might need the previous author's fingerprints\n                UnfilteredReadValue = response;\n            }\n            else\n            {\n                Console.WriteLine(\"Please check for connectivity to the target ECU (could not read variant coding data)\");\n                MessageBox.Show(\"Variant Coding dialog will operate as a simulation using default values.\", \"Unable to read ECU variant coding data\", MessageBoxButtons.OK);\n                btnApply.Enabled = false;\n            }\n\n            // VCSanityCheck();\n            IntepretVC();\n            PresentVC();\n        }\n\n        // extremely unscientific way of figuring out the actual vc data\n        public static DiagPreparation GetLargestPreparation(List<List<DiagPreparation>> presSet)\n        {\n            int largestField = 0;\n            foreach (List<DiagPreparation> wtf in presSet)\n            {\n                foreach (DiagPreparation prep in wtf)\n                {\n                    if (prep.SizeInBits > largestField)\n                    {\n                        largestField = prep.SizeInBits;\n                    }\n                }\n            }\n\n            foreach (List<DiagPreparation> wtf in presSet)\n            {\n                foreach (DiagPreparation prep in wtf)\n                {\n                    if (prep.SizeInBits == largestField)\n                    {\n                        return prep;\n                    }\n                }\n            }\n            return null;\n        }\n        \n        public static DiagPreparation GetLargestPreparation(List<DiagPreparation> presSet)\n        {\n            int largestField = 0;\n            foreach (DiagPreparation prep in presSet)\n            {\n                if (prep.SizeInBits > largestField)\n                {\n                    largestField = prep.SizeInBits;\n                }\n            }\n\n            foreach (DiagPreparation prep in presSet)\n            {\n                if (prep.SizeInBits == largestField)\n                {\n                    return prep;\n                }\n            }\n            return null;\n        }\n\n        private void VCSanityCheck() \n        {\n            VariantCodingDomain.VCFragments.ForEach(x => Console.WriteLine($\"Fragment: {x.Qualifier}, R:{x.ReadAccessLevel} W:{x.WriteAccessLevel}\"));\n            Console.WriteLine($\"ReadSvc level {ReadService.ClientAccessLevel}/{ReadService.SecurityAccessLevel}, WriteSvc level {WriteService.ClientAccessLevel}/{WriteService.SecurityAccessLevel}\");\n\n            Console.WriteLine($\"ReadService: {ReadService.Qualifier} : {BitUtility.BytesToHex(ReadService.RequestBytes)} ({ReadService.RequestBytes.Length * 8})\");\n            ReadService.InputPreparations.ForEach(x => Console.WriteLine($\"{x.Qualifier} @ {x.BitPosition}, size: {x.SizeInBits}\"));\n\n            Console.WriteLine($\"WriteService: {WriteService.Qualifier} : {BitUtility.BytesToHex(WriteService.RequestBytes)} ({WriteService.RequestBytes.Length * 8})\");\n            WriteService.InputPreparations.ForEach(x => Console.WriteLine($\"{x.Qualifier} @ {x.BitPosition}, size: {x.SizeInBits}\"));\n        }\n\n        private void PresentVC() \n        {\n            txtCodingString.Text = rbHex.Checked ? BitUtility.BytesToHex(VCValue, true) : BitUtility.BytesToDecimalString(VCValue);\n            txtCodingString.Select(0, 0);\n        }\n\n        private void ReinterpretVC() \n        {\n            VCValue = rbHex.Checked ? BitUtility.BytesFromHex(txtCodingString.Text) : BitUtility.BytesFromDecimalString(txtCodingString.Text);\n            IntepretVC();\n        }\n\n        private void IntepretVC()\n        {\n            // save view state\n            int saveRow = 0;\n            if (dgvMain.Rows.Count > 0 && dgvMain.FirstDisplayedCell != null)\n            {\n                saveRow = dgvMain.FirstDisplayedCell.RowIndex;\n            }\n            List<int> saveSelectedIndices = new List<int>();\n            foreach (DataGridViewRow row in dgvMain.SelectedRows)\n            {\n                saveSelectedIndices.Add(row.Index);\n            }\n\n            // actually interpret vc\n            DataTable dt = new DataTable();\n            dt.Columns.Add(\"Fragment\", typeof(String));\n            dt.Columns.Add(\"Value\", typeof(String));\n            dt.Columns.Add(\"Bit Position\", typeof(String));\n            dt.Columns.Add(\"Bit Length\", typeof(String));\n\n            for (int i = 0; i < VariantCodingDomain.VCFragments.Count; i++)\n            {\n                VCFragment currentFragment = VariantCodingDomain.VCFragments[i];\n                VCSubfragment subfragment = currentFragment.GetSubfragmentConfiguration(VCValue);\n\n                dt.Rows.Add(new string[] { \n                    currentFragment.Qualifier, \n                    subfragment is null ? \"(warning: no matching subfragment)\" : subfragment.NameResolved,\n                    currentFragment.ByteBitPos.ToString(),\n                    currentFragment.BitLength.ToString(),\n                });\n            }\n\n            dgvMain.DataSource = dt;\n            dgvMain.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;\n            dgvMain.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;\n            dgvMain.Sort(dgvMain.Columns[0], ListSortDirection.Ascending);\n\n            // restore view state\n            if (saveRow != 0 && saveRow < dgvMain.Rows.Count)\n            {\n                dgvMain.FirstDisplayedScrollingRowIndex = saveRow;\n            }\n            foreach (int rowIndex in saveSelectedIndices)\n            {\n                foreach (DataGridViewRow row in dgvMain.Rows)\n                {\n                    row.Selected = row.Index == rowIndex;\n                }\n            }\n\n        }\n\n        private void VCForm_Load(object sender, EventArgs e)\n        {\n            SetDoubleBuffer(dgvMain, true);\n        }\n\n        static void SetDoubleBuffer(Control ctl, bool DoubleBuffered)\n        {\n            typeof(Control).InvokeMember(\"DoubleBuffered\",\n                BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty,\n                null, ctl, new object[] { DoubleBuffered });\n        }\n\n        private void btnApply_Click(object sender, EventArgs e)\n        {\n            if (!BitUtility.CheckHexValid(txtCodingString.Text)) \n            {\n                MessageBox.Show(\"Hex data could not be parsed. Please check if there are any invalid values\", \"Write Variant Coding\");\n                return;\n            }\n\n            VCValue = BitUtility.BytesFromHex(txtCodingString.Text);\n            ReinterpretVC();\n            PresentVC();\n\n            if (MessageBox.Show(\"The SCN (Software Calibration Number) will be reset for some ECUs when the variant coding is modified. Continue?\", \"SCN Warning\", MessageBoxButtons.YesNo) == DialogResult.Yes) \n            {\n                this.DialogResult = DialogResult.OK;\n                this.Close();\n            }\n        }\n\n        private void btnReinterpret_Click(object sender, EventArgs e)\n        {\n            if (!BitUtility.CheckHexValid(txtCodingString.Text))\n            {\n                MessageBox.Show(\"Hex data could not be parsed. Please check if there are any invalid values\", \"Reinterpret Variant Coding\");\n                return;\n            }\n\n            ReinterpretVC();\n        }\n\n        private void rbHex_CheckedChanged(object sender, EventArgs e)\n        {\n            PresentVC();\n        }\n\n        private void radioButton1_CheckedChanged(object sender, EventArgs e)\n        {\n            PresentVC();\n        }\n\n        private void btnCopy_Click(object sender, EventArgs e)\n        {\n            Clipboard.SetText(txtCodingString.Text);\n        }\n\n        private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)\n        {\n            if (dgvMain.SelectedRows.Count > 0)\n            {\n                string fragmentName = dgvMain.SelectedRows[0].Cells[0].Value.ToString();\n                string fragmentValue = dgvMain.SelectedRows[0].Cells[1].Value.ToString();\n                VCFragment fragment = VariantCodingDomain.VCFragments.Find(x => x.Qualifier == fragmentName);\n                if (fragment is null)\n                {\n                    return;\n                }\n\n                int contextMenuLimit = 30;\n\n                contextMenuStrip1.Items.Clear();\n                ToolStripMenuItem tsHeader = new ToolStripMenuItem();\n                tsHeader.Text = fragmentName;\n                if (fragment.Subfragments.Count > contextMenuLimit)\n                {\n                    tsHeader.Text += \" (Warning: too many entries to show)\";\n\n                    // build table for picker\n                    ShowPickerDialog(fragmentName, fragment);\n\n                    e.Cancel = true;\n                    return;\n\n                }\n                tsHeader.Enabled = false;\n                contextMenuStrip1.Items.Add(tsHeader);\n                contextMenuStrip1.Items.Add(new ToolStripSeparator());\n\n                foreach (VCSubfragment subfragment in fragment.Subfragments) \n                {\n                    ToolStripMenuItem tsItem = new ToolStripMenuItem();\n                    tsItem.Text = subfragment.NameResolved;\n                    tsItem.Tag = fragmentName;\n                    tsItem.Click += VCContextMenu_Click;\n                    if (fragmentValue == tsItem.Text) \n                    {\n                        tsItem.Checked = true;\n                    }\n                    contextMenuStrip1.Items.Add(tsItem);\n                    if (--contextMenuLimit == 0) \n                    {\n                        break;\n                    }\n                }\n            }\n            // we *want* to show the context menu, this makes it happen\n            e.Cancel = false;\n        }\n\n        private void ShowPickerDialog(string fragmentName, VCFragment fragment)\n        {\n            string[][] table = new string[fragment.Subfragments.Count][];\n\n            for (int i = 0; i < fragment.Subfragments.Count; i++)\n            {\n                table[i] = new string[] { fragment.Subfragments[i].NameResolved };\n            }\n            GenericPicker picker = new GenericPicker(table, new string[] { \"Name\" });\n            picker.Text = $\"Select an option for {fragmentName}\";\n\n            if (picker.ShowDialog() == DialogResult.OK) \n            {\n                SelectVC(fragmentName, picker.SelectedResult[0]);\n            }\n        }\n\n        private void VCContextMenu_Click(object sender, EventArgs e)\n        {\n            ToolStripMenuItem senderItem = (ToolStripMenuItem)sender;\n            string fragmentName = senderItem.Tag.ToString();\n            string fragmentValue = senderItem.Text;\n            SelectVC(fragmentName, fragmentValue);\n        }\n\n        private void SelectVC(string fragmentName, string fragmentValue) \n        {\n            VCFragment fragment = VariantCodingDomain.VCFragments.Find(x => x.Qualifier == fragmentName);\n            if (fragment is null)\n            {\n                Console.WriteLine(\"Coding context menu: couldn't find a matching fragment\");\n                return;\n            }\n            VCSubfragment subfragment = fragment.Subfragments.Find(x => x.NameResolved == fragmentValue);\n            if (subfragment is null)\n            {\n                Console.WriteLine(\"Coding context menu: couldn't find a matching subfragment\");\n                return;\n            }\n            VCValue = fragment.SetSubfragmentConfiguration(VCValue, subfragment);\n            IntepretVC();\n            PresentVC();\n        }\n\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/Forms/VCForm.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <metadata name=\"contextMenuStrip1.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>17, 17</value>\n  </metadata>\n  <assembly alias=\"System.Drawing\" name=\"System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\" />\n  <data name=\"$this.Icon\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n    <value>\n        AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABtbW1jWFhYv1FRUb9SUlJjAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAb29vKWpqag4AAAACgYGB6r29vf+ysrL/W1tb6gAAAAJcXFwOTk5OKQAA\n        AAAAAAAAAAAAAAAAAAAAAAAAgYGBm29vb/1kZGTndnZ2GYODg+fLy8v/x8fH/2JiYudaWloZWFhY505O\n        Tv1JSUmbAAAAAAAAAAAAAAAApKSke7y8vP/e3t7/pqam/4ODg/SFhYX+xMTE/8LCwv9tbW3+bm5u9Kam\n        pv/S0tL/gICA/1JSUnsAAAAAAAAAAKurq32mpqb+1dXV/8XFxf/Ly8v/0dHR/8nJyf/Hx8f/zMzM/8XF\n        xf+9vb3/y8vL/25ubv5nZ2d9AAAAAAAAAAAAAAAArKyshcXFxf/BwcH/xcXF/8fHx/+qqqr/p6en/8HB\n        wf++vr7/tbW1/6qqqv9paWmFAAAAAAAAAACjo6PNj4+P46CgoO7Pz8//xsbG/8zMzP+enp7GmZmZRJSU\n        lESPj4/GwcHB/7y8vP+5ubn/ZGRk7lhYWONTU1PNv7+//eLi4v/S0tL/xsbG/83Nzf+xsbH/k5OTRAAA\n        AAAAAAAAlZWVRKioqP/CwsL/t7e3/8DAwP/S0tL/YWFh/cTExP3p6en/1tbW/8nJyf/Ozs7/paWl/4SE\n        hEQAAAAAAAAAAJqamkSsrKz/xMTE/7q6uv/Gxsb/3d3d/2tra/3IyMjNxMTE48DAwO7Y2Nj/zc3N/7y8\n        vP+CgoLGd3d3RH5+fkSPj4/Gw8PD/8LCwv/Nzc3/jIyM7oeHh+ODg4PNAAAAAAAAAADFxcWF1NTU/8zM\n        zP/Jycn/urq6/5ycnP+hoaH/wsLC/8bGxv/BwcH/t7e3/4mJiYUAAAAAAAAAAAAAAADKysp9xMTE/tzc\n        3P/U1NT/2dnZ/9vb2//W1tb/1NTU/9nZ2f/S0tL/y8vL/8jIyP95eXn+cXFxfQAAAAAAAAAA0NDQe9zc\n        3P/t7e3/29vb/8LCwvS+vr7+1tbW/9TU1P+wsLD+rKys9MvLy//n5+f/t7e3/4uLi3sAAAAAAAAAAAAA\n        AADR0dGbzs7O/crKyufGxsYZwsLC597e3v/d3d3/srKy57GxsRmsrKznp6en/aOjo5sAAAAAAAAAAAAA\n        AAAAAAAAAAAAANHR0SnOzs4OAAAAAsfHx+rl5eX/5OTk/6ysrOoAAAACsrKyDq2trSkAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADLy8tjx8fHv8TExL+/v79jAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAA/D8AAOQnAADAAwAAgAEAAIABAADAAwAAAAAAAAGAAAABgAAAAAAAAMADAACAAQAAgAEAAMAD\n        AADkJwAA/D8AAA==\n</value>\n  </data>\n</root>"
  },
  {
    "path": "Caesar/Diogenes/Preferences.cs",
    "content": "﻿using Caesar;\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Diogenes\n{\n    public class Preferences\n    {\n        public enum PreferenceKey \n        {\n            AllowVC,\n            EnableSCNZero,\n            EnableFingerprintClone,\n            FingerprintValue,\n        }\n\n        private static Dictionary<int, string> UserPreferences = null;\n\n        public static void InitializePreferences()\n        {\n            // default values for first run / no config file\n            UserPreferences = new Dictionary<int, string>();\n            UserPreferences.Add((int)PreferenceKey.AllowVC, \"false\");\n            UserPreferences.Add((int)PreferenceKey.EnableSCNZero, \"true\");\n            UserPreferences.Add((int)PreferenceKey.FingerprintValue, \"1\");\n            UserPreferences.Add((int)PreferenceKey.EnableFingerprintClone, \"true\");\n            LoadAndDeserializePreferences();\n        }\n\n        public static string GetValue(PreferenceKey key)\n        {\n            int keyIndex = (int)key;\n            if (UserPreferences is null)\n            {\n                InitializePreferences();\n            }\n\n            if (UserPreferences.ContainsKey(keyIndex))\n            {\n                return UserPreferences[keyIndex];\n            }\n            else\n            {\n                return \"\";\n            }\n        }\n        public static void SetValue(PreferenceKey key, string newValue, bool save = true)\n        {\n            int keyIndex = (int)key;\n            if (UserPreferences is null)\n            {\n                InitializePreferences();\n            }\n\n            if (UserPreferences.ContainsKey(keyIndex))\n            {\n                UserPreferences[keyIndex] = newValue;\n            }\n            else\n            {\n                UserPreferences.Add(keyIndex, newValue);\n            }\n            if (save)\n            {\n                SerializeAndSavePreferences();\n            }\n        }\n\n        private static string GetPreferencesFilePath()\n        {\n            return Path.Combine(GetPreferencesDirectory(), \"Preferences.ini\");\n        }\n        private static string GetPreferencesDirectory()\n        {\n            return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), \"Diogenes\");\n        }\n\n        public static void SerializeAndSavePreferences() \n        {\n            string prefsDirectory = GetPreferencesDirectory();\n            if (!Directory.Exists(prefsDirectory)) \n            {\n                Directory.CreateDirectory(prefsDirectory);\n            }\n            StringBuilder sb = new StringBuilder();\n            foreach (KeyValuePair<int, string> row in UserPreferences) \n            {\n                // assume that windows clients will mess up the line endings, so use \\r\\n first\n                sb.Append($\"{row.Key}={BitUtility.BytesToHex(Encoding.UTF8.GetBytes(row.Value))}\\r\\n\");\n            }\n            File.WriteAllText(GetPreferencesFilePath(), sb.ToString());\n        }\n\n        public static bool LoadAndDeserializePreferences() \n        {\n            string prefsPath = GetPreferencesFilePath();\n            if (!File.Exists(prefsPath))\n            {\n                return false;\n            }\n            string[] iniRows = File.ReadAllText(prefsPath).Replace(\"\\r\", \"\").Split(new string[] {\"\\n\" }, StringSplitOptions.RemoveEmptyEntries);\n            foreach (string iniRow in iniRows) \n            {\n                string[] keyValue = iniRow.Split(new string[] { \"=\" }, StringSplitOptions.RemoveEmptyEntries);\n                PreferenceKey key = (PreferenceKey)int.Parse(keyValue[0]);\n                string value = Encoding.UTF8.GetString(BitUtility.BytesFromHex(keyValue[1]));\n                SetValue(key, value, false);\n            }\n            return true;\n        }\n\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/Program.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\n\nnamespace Diogenes\n{\n    static class Program\n    {\n        /// <summary>\n        /// The main entry point for the application.\n        /// </summary>\n        [STAThread]\n        static void Main()\n        {\n            Application.EnableVisualStyles();\n            Application.SetCompatibleTextRenderingDefault(false);\n            Application.Run(new MainForm());\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following\n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"Diogenes\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"Diogenes\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2020\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible\n// to COM components.  If you need to access a type in this assembly from\n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"2216db99-eaac-46a8-b99a-28d659907de7\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version\n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers\n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.5.2.1\")]\n[assembly: AssemblyFileVersion(\"1.5.2.1\")]\n"
  },
  {
    "path": "Caesar/Diogenes/Properties/Resources.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//     Runtime Version:4.0.30319.42000\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace Diogenes.Properties {\n    using System;\n    \n    \n    /// <summary>\n    ///   A strongly-typed resource class, for looking up localized strings, etc.\n    /// </summary>\n    // This class was auto-generated by the StronglyTypedResourceBuilder\n    // class via a tool like ResGen or Visual Studio.\n    // To add or remove a member, edit your .ResX file then rerun ResGen\n    // with the /str option, or rebuild your VS project.\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"16.0.0.0\")]\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    internal class Resources {\n        \n        private static global::System.Resources.ResourceManager resourceMan;\n        \n        private static global::System.Globalization.CultureInfo resourceCulture;\n        \n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\n        internal Resources() {\n        }\n        \n        /// <summary>\n        ///   Returns the cached ResourceManager instance used by this class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Resources.ResourceManager ResourceManager {\n            get {\n                if (object.ReferenceEquals(resourceMan, null)) {\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"Diogenes.Properties.Resources\", typeof(Resources).Assembly);\n                    resourceMan = temp;\n                }\n                return resourceMan;\n            }\n        }\n        \n        /// <summary>\n        ///   Overrides the current thread's CurrentUICulture property for all\n        ///   resource lookups using this strongly typed resource class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Globalization.CultureInfo Culture {\n            get {\n                return resourceCulture;\n            }\n            set {\n                resourceCulture = value;\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap accept {\n            get {\n                object obj = ResourceManager.GetObject(\"accept\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap application_xp_terminal {\n            get {\n                object obj = ResourceManager.GetObject(\"application_xp_terminal\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap asterisk_orange {\n            get {\n                object obj = ResourceManager.GetObject(\"asterisk_orange\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap blank {\n            get {\n                object obj = ResourceManager.GetObject(\"blank\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap box {\n            get {\n                object obj = ResourceManager.GetObject(\"box\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap brick {\n            get {\n                object obj = ResourceManager.GetObject(\"brick\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap bullet_black {\n            get {\n                object obj = ResourceManager.GetObject(\"bullet_black\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap bullet_blue {\n            get {\n                object obj = ResourceManager.GetObject(\"bullet_blue\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap bullet_go {\n            get {\n                object obj = ResourceManager.GetObject(\"bullet_go\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap bullet_green {\n            get {\n                object obj = ResourceManager.GetObject(\"bullet_green\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap bullet_orange {\n            get {\n                object obj = ResourceManager.GetObject(\"bullet_orange\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap bullet_pink {\n            get {\n                object obj = ResourceManager.GetObject(\"bullet_pink\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap bullet_purple {\n            get {\n                object obj = ResourceManager.GetObject(\"bullet_purple\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap bullet_red {\n            get {\n                object obj = ResourceManager.GetObject(\"bullet_red\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap bullet_star {\n            get {\n                object obj = ResourceManager.GetObject(\"bullet_star\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap bullet_white {\n            get {\n                object obj = ResourceManager.GetObject(\"bullet_white\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap bullet_yellow {\n            get {\n                object obj = ResourceManager.GetObject(\"bullet_yellow\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap cog {\n            get {\n                object obj = ResourceManager.GetObject(\"cog\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap computer_go {\n            get {\n                object obj = ResourceManager.GetObject(\"computer_go\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap connect {\n            get {\n                object obj = ResourceManager.GetObject(\"connect\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap diogenes {\n            get {\n                object obj = ResourceManager.GetObject(\"diogenes\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap folder {\n            get {\n                object obj = ResourceManager.GetObject(\"folder\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap house {\n            get {\n                object obj = ResourceManager.GetObject(\"house\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap information {\n            get {\n                object obj = ResourceManager.GetObject(\"information\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap key {\n            get {\n                object obj = ResourceManager.GetObject(\"key\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap lock_edit {\n            get {\n                object obj = ResourceManager.GetObject(\"lock_edit\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap page_white_edit {\n            get {\n                object obj = ResourceManager.GetObject(\"page_white_edit\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized resource of type System.Drawing.Bitmap.\n        /// </summary>\n        internal static System.Drawing.Bitmap report {\n            get {\n                object obj = ResourceManager.GetObject(\"report\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <assembly alias=\"System.Windows.Forms\" name=\"System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\" />\n  <data name=\"asterisk_orange\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\asterisk_orange.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"brick\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\brick.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"bullet_white\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\bullet_white.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"blank\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\blank.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"folder\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\folder.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"computer_go\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\computer_go.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"bullet_pink\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\bullet_pink.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"report\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\report.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"lock_edit\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\lock_edit.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"bullet_red\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\bullet_red.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"bullet_yellow\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\bullet_yellow.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"key\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\key.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"bullet_blue\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\bullet_blue.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"connect\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\connect.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"accept\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\accept.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"bullet_green\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\bullet_green.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"bullet_star\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\bullet_star.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"application_xp_terminal\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\application_xp_terminal.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"bullet_orange\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\bullet_orange.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"bullet_go\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\bullet_go.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"box\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\box.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"bullet_purple\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\bullet_purple.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"page_white_edit\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\page_white_edit.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"bullet_black\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\bullet_black.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"cog\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\cog.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"house\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\house.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"information\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\information.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"diogenes\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>..\\Resources\\diogenes.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n</root>"
  },
  {
    "path": "Caesar/Diogenes/Properties/Settings.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//     Runtime Version:4.0.30319.42000\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace Diogenes.Properties\n{\n\n\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator\", \"11.0.0.0\")]\n    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase\n    {\n\n        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));\n\n        public static Settings Default\n        {\n            get\n            {\n                return defaultInstance;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/Properties/Settings.settings",
    "content": "﻿<?xml version='1.0' encoding='utf-8'?>\n<SettingsFile xmlns=\"http://schemas.microsoft.com/VisualStudio/2004/01/settings\" CurrentProfile=\"(Default)\">\n  <Profiles>\n    <Profile Name=\"(Default)\" />\n  </Profiles>\n  <Settings />\n</SettingsFile>\n"
  },
  {
    "path": "Caesar/Diogenes/Reports/DTCReport.cs",
    "content": "﻿using Caesar;\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\n\nnamespace Diogenes\n{\n    public class DTCReport\n    {\n\n        public static void CreateDTCReport(List<DTCContext> dtcContexts, ECUConnection connection, ECUVariant variant)\n        {\n            Cursor.Current = Cursors.WaitCursor;\n\n            string reportDate = $\"{DateTime.Now.ToShortDateString()} {DateTime.Now.ToLongTimeString()}\";\n\n            string containerChecksum = variant.ParentECU.ParentContainer.FileChecksum.ToString(\"X8\");\n            string dVersion = MainForm.GetVersion();\n            string cVersion = CaesarContainer.GetCaesarVersionString();\n            string connectionData = connection is null ? \"(Unavailable)\" : connection.FriendlyProfileName;\n            string ecuCbfVersion = variant.ParentECU.EcuXmlVersion;\n\n            StringBuilder tableBuilder = new StringBuilder();\n\n            // back up every domain since some have overlaps\n            foreach (DTCContext dtcCtx in dtcContexts)\n            {\n                StringBuilder tableRowBuilder = new StringBuilder();\n\n                // env, description\n                for (int i = 0; i < dtcCtx.EnvironmentContext.Count; i++)\n                {\n                    string tableRowBlock = $@\"\n        <tr>\n            <td>{dtcCtx.EnvironmentContext[i][0]}</td>\n            <td>{dtcCtx.EnvironmentContext[i][1]}</td>\n        </tr>\n\";\n                    tableRowBuilder.Append(tableRowBlock);\n                }\n\n                string tableBlock = $@\"\n    <hr>\n\n    <h2>{dtcCtx.DTC.Qualifier}</h2>\n\n    <p>{dtcCtx.DTC.Description}</p>\n\n    <table>\n        <tr>\n            <th>Environment</th>\n            <th>Description</th>\n        </tr>\n        {tableRowBuilder}\n    </table>\n\";\n                tableBuilder.Append(tableBlock);\n            }\n\n\n            string document = $@\"\n<!DOCTYPE html>\n<html lang=\"\"en\"\">\n<head>\n    <meta charset=\"\"UTF-8\"\">\n    <title>{variant.ParentECU.Qualifier} : DTC Report</title>\n    <style>\n        body\n        {{\n            padding: 10px 20% 15px 15%;\n            font-family: sans-serif;\n        }}\n        .pull-right\n        {{\n            float: right;\n        }}\n        hr\n        {{\n            border-bottom: 0;\n            opacity: 0.2;\n        }}\n        table\n        {{\n            width: 100%;\n            margin: 20px 0;\n        }}\n        #eof\n        {{\n            text-transform: uppercase;\n            font-weight: bold;\n            opacity: 0.15;\n            letter-spacing: 0.4em;\n        }}\n        .coding-data\n        {{\n            opacity: 0.8;\n        }}\n        .monospace\n        {{\n            font-family: monospace;\n        }}\n        .fifth\n        {{\n            width: 20%;\n        }}\n        th\n        {{\n            text-align: left;\n        }}\n    </style>\n</head>\n<body>\n    <h1 class=\"\"pull-right\"\">Diogenes</h1>\n    <h1>{variant.ParentECU.Qualifier}</h1>\n    <hr>\n    <table>\n        <tr>\n            <td>CBF Checksum</td>\n            <td>{containerChecksum}</td>\n        </tr>\n        <tr>\n            <td>Date</td>\n            <td>{reportDate}</td>\n        </tr>\n        <tr>\n            <td>Client Version</td>\n            <td>Diogenes: {dVersion}, Caesar: {cVersion}</td>\n        </tr>\n        <tr>\n            <td>ECU CBF Version</td>\n            <td>{ecuCbfVersion}</td>\n        </tr>\n        <tr>\n            <td>ECU Variant</td>\n            <td>{variant.Qualifier}</td>\n        </tr>\n        <tr>\n            <td>Connection Info</td>\n            <td>{connectionData}</td>\n        </tr>\n    </table>\n\n    {connection.ConnectionProtocol.QueryECUMetadata(connection).GetHtmlTable(connection)}\n    {tableBuilder}\n\n    <hr>\n\n    <span id=\"\"eof\"\">End of report</span>\n</body>\n</html>\";\n\n\n            Cursor.Current = Cursors.Default;\n\n            SaveFileDialog sfd = new SaveFileDialog();\n            sfd.Title = \"Specify a location to save your new DTC report\";\n            sfd.Filter = \"HTML file (*.html)|*.html|All files (*.*)|*.*\";\n            sfd.FileName = $\"DTC_{variant.Qualifier}_{DateTime.Now.ToString(\"yyyyMMdd_HHmm\")}.html\";\n            if (sfd.ShowDialog() == DialogResult.OK)\n            {\n                File.WriteAllText(sfd.FileName, document.ToString());\n                MessageBox.Show($\"Report successfully saved to {sfd.FileName}\", \"Export complete\");\n            }\n\n        }\n\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/Reports/VCReport.cs",
    "content": "﻿using Caesar;\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\n\nnamespace Diogenes\n{\n    public class VCReport\n    {\n\n        public static void treeViewSelectVariantCodingBackup(TreeNode node, ECUConnection connection, List<CaesarContainer> containers)\n        {\n\n            if (connection is null)\n            {\n                return;\n            }\n\n            Cursor.Current = Cursors.WaitCursor;\n\n            string variantName = node.Parent.Text;\n            string ecuName = node.Parent.Parent.Text;\n            string reportDate = $\"{DateTime.Now.ToShortDateString()} {DateTime.Now.ToLongTimeString()}\";\n\n            StringBuilder report = new StringBuilder();\n\n            CaesarContainer container = containers.Find(x => x.GetECUVariantByName(variantName) != null);\n            ECU ecu = container.GetECUByName(ecuName);\n            ECUVariant variant = container.GetECUVariantByName(variantName);\n\n            string containerChecksum = container.FileChecksum.ToString(\"X8\");\n            string dVersion = MainForm.GetVersion();\n            string cVersion = CaesarContainer.GetCaesarVersionString();\n            string connectionData = connection is null ? \"(Unavailable)\" : connection.FriendlyProfileName;\n            string ecuCbfVersion = ecu.EcuXmlVersion;\n\n            report.Append($\"ECU Variant: {variant.Qualifier}\\r\\n\");\n\n            StringBuilder tableBuilder = new StringBuilder();\n\n            // back up every domain since some have overlaps\n            foreach (VCDomain domain in variant.VCDomains)\n            {\n                report.Append($\"\\r\\nCoding Service: {domain.Qualifier}\\r\\n\");\n                // find the read service, then execute it as-is\n                DiagService readService = variant.GetDiagServiceByName(domain.ReadServiceName);\n                byte[] response = connection.SendDiagRequest(readService);\n\n                // isolate the traditional vc string\n                DiagPreparation largestPrep = VCForm.GetLargestPreparation(readService.OutputPreparations);\n                byte[] vcValue = response.Skip(largestPrep.BitPosition / 8).Take(largestPrep.SizeInBits / 8).ToArray();\n\n                StringBuilder tableRowBuilder = new StringBuilder();\n\n                // explain the vc string's settings\n                for (int i = 0; i < domain.VCFragments.Count; i++)\n                {\n                    VCFragment currentFragment = domain.VCFragments[i];\n                    VCSubfragment subfragment = currentFragment.GetSubfragmentConfiguration(vcValue);\n\n                    string fragmentValue = subfragment is null ? \"(?)\" : subfragment.NameResolved;\n                    string fragmentSupplementKey = subfragment is null ? \"(?)\" : subfragment.SupplementKey;\n\n                    string tableRowBlock = $@\"\n        <tr>\n            <td>{currentFragment.Qualifier}</td>\n            <td>{fragmentValue}</td>\n            <td>{fragmentSupplementKey}</td>\n        </tr>\n\";\n                    tableRowBuilder.Append(tableRowBlock);\n                }\n\n                string tableBlock = $@\"\n    <hr>\n\n    <h2>{domain.Qualifier}</h2>\n\n    <table class=\"\"coding-data\"\">\n        <tr>\n            <td class=\"\"fifth\"\">Coding String (Hex)</td>\n            <td class=\"\"monospace\"\">{BitUtility.BytesToHex(vcValue, true)}</td>\n        </tr>\n        <tr>\n            <td class=\"\"fifth\"\">Raw Coding String (Hex)</td>\n            <td class=\"\"monospace\"\">{BitUtility.BytesToHex(response, true)}</td>\n        </tr>\n    </table>\n\n    <table>\n        <tr>\n            <th>Fragment</th>\n            <th>Value</th>\n            <th>Supplement Key</th>\n        </tr>\n        {tableRowBuilder}\n    </table>\n\";\n                tableBuilder.Append(tableBlock);\n            }\n\n\n            string document = $@\"\n<!DOCTYPE html>\n<html lang=\"\"en\"\">\n<head>\n    <meta charset=\"\"UTF-8\"\">\n    <title>{ecuName} : Backup</title>\n    <style>\n        body\n        {{\n            padding: 10px 20% 15px 15%;\n            font-family: sans-serif;\n        }}\n        .pull-right\n        {{\n            float: right;\n        }}\n        hr\n        {{\n            border-bottom: 0;\n            opacity: 0.2;\n        }}\n        table\n        {{\n            width: 100%;\n            margin: 20px 0;\n        }}\n        #eof\n        {{\n            text-transform: uppercase;\n            font-weight: bold;\n            opacity: 0.15;\n            letter-spacing: 0.4em;\n        }}\n        .coding-data\n        {{\n            opacity: 0.8;\n        }}\n        .monospace\n        {{\n            font-family: monospace;\n        }}\n        .fifth\n        {{\n            width: 20%;\n        }}\n        th\n        {{\n            text-align: left;\n        }}\n    </style>\n</head>\n<body>\n    <h1 class=\"\"pull-right\"\">Diogenes</h1>\n    <h1>{ecuName}</h1>\n\n    <hr>\n    <table>\n        <tr>\n            <td>CBF Checksum</td>\n            <td>{containerChecksum}</td>\n        </tr>\n        <tr>\n            <td>Date</td>\n            <td>{reportDate}</td>\n        </tr>\n        <tr>\n            <td>Client Version</td>\n            <td>Diogenes: {dVersion}, Caesar: {cVersion}</td>\n        </tr>\n        <tr>\n            <td>ECU CBF Version</td>\n            <td>{ecuCbfVersion}</td>\n        </tr>\n        <tr>\n            <td>ECU Variant</td>\n            <td>{variantName}</td>\n        </tr>\n        <tr>\n            <td>Connection Info</td>\n            <td>{connectionData}</td>\n        </tr>\n    </table>\n\n    {connection.ConnectionProtocol.QueryECUMetadata(connection).GetHtmlTable(connection)}\n    {tableBuilder}\n\n    <hr>\n\n    <span id=\"\"eof\"\">End of report</span>\n</body>\n</html>\";\n\n\n            Cursor.Current = Cursors.Default;\n\n            SaveFileDialog sfd = new SaveFileDialog();\n            sfd.Title = \"Specify a location to save your new VC backup\";\n            sfd.Filter = \"HTML file (*.html)|*.html|All files (*.*)|*.*\";\n            sfd.FileName = $\"VC_{variantName}_{DateTime.Now.ToString(\"yyyyMMdd_HHmm\")}.html\";\n            if (sfd.ShowDialog() == DialogResult.OK)\n            {\n                File.WriteAllText(sfd.FileName, document.ToString());\n                MessageBox.Show($\"Backup successfully saved to {sfd.FileName}\", \"Export complete\");\n            }\n\n        }\n\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/SecurityAccess/DllContext.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Runtime.InteropServices;\nusing System.Security.Cryptography;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Caesar;\n\nnamespace Diogenes.SecurityAccess\n{\n    public class DllContext\n    {\n        private IntPtr dllHandle = IntPtr.Zero;\n        public List<string> DllExports = new List<string>();\n        private Dictionary<string, IntPtr> dllAddressMappings = new Dictionary<string, IntPtr>();\n\n        public string SHA1Hash = \"\";\n        public string FileDescription = \"\";\n        public string FileName = \"\";\n        public string DLLPath = \"\";\n        public string ECUName = \"\";\n        public string Comment = \"\";\n        public bool KeyGenerationCapability = false;\n        public bool ModeSpecified = false;\n        public List<Tuple<uint, int, int>> AccessLevels = new List<Tuple<uint, int, int>>();\n\n        public DllContext(string filePath, bool runHash = true)\n        {\n            DLLPath = filePath;\n            if (!File.Exists(DLLPath))\n            {\n                Console.WriteLine($\"{DLLPath}: File does not exist\");\n                return;\n            }\n            FileName = Path.GetFileName(filePath);\n\n            // Compute and store the file hash\n            if (runHash)\n            {\n                using (var cryptoProvider = new SHA1CryptoServiceProvider())\n                {\n                    SHA1Hash = BitConverter.ToString(cryptoProvider.ComputeHash(File.ReadAllBytes(filePath))).Replace(\"-\", \"\");\n                }\n            }\n\n            // Get the module's exports\n            DllExports = UnmanagedUtility.GetExports(DLLPath);\n\n            if (DllExports.Count == 0)\n            {\n                Console.WriteLine($\"{DLLPath}: No exports, possibly an invalid DLL\");\n                return;\n            }\n\n            // Try to load the library into our process space\n            dllHandle = UnmanagedUtility.LoadLibrary(filePath);\n            if (dllHandle == IntPtr.Zero)\n            {\n                Console.WriteLine($\"{DLLPath}: LoadLibrary failed\");\n                return;\n            }\n\n            // Try to load addresses of all known exports\n            dllAddressMappings = new Dictionary<string, IntPtr>();\n            foreach (string knownExport in ExportDefinition.KnownExportedFunctions)\n            {\n                if (DllExports.Contains(knownExport))\n                {\n                    dllAddressMappings.Add(knownExport, UnmanagedUtility.GetProcAddress(dllHandle, knownExport));\n                }\n                else\n                {\n                    dllAddressMappings.Add(knownExport, IntPtr.Zero);\n                }\n            }\n\n            // Set capabilities\n            KeyGenerationCapability = DllExports.Contains(\"GenerateKeyEx\") || DllExports.Contains(\"GenerateKeyExOpt\");\n            ModeSpecified = DllExports.Contains(\"GetKeyLength\") && DllExports.Contains(\"GetSeedLength\") && DllExports.Contains(\"GetConfiguredAccessTypes\");\n\n            // Store additional metadata\n            FileDescription = FileVersionInfo.GetVersionInfo(DLLPath).FileDescription;\n\n            LoadAdditionalDataFromDllCalls();\n        }\n\n        public void LoadAdditionalDataFromDllCalls()\n        {\n            ECUName = GetECUName();\n            Comment = GetComment();\n\n            if (!ModeSpecified)\n            {\n                return;\n            }\n\n            // Access level, key size, seed size\n            AccessLevels = new List<Tuple<uint, int, int>>();\n            foreach (uint accessLevel in GetConfiguredAccessTypes())\n            {\n                AccessLevels.Add(new Tuple<uint, int, int>(accessLevel, GetKeyLength(accessLevel), GetSeedLength(accessLevel)));\n            }\n        }\n\n        // Automatically selects and invokes the correct key generation function. Prefers the \"opt\" variant\n        public string GenerateKeyAuto(uint securityLevel, byte[] seed)\n        {\n            if (DllExports.Contains(\"GenerateKeyExOpt\"))\n            {\n                return BitUtility.BytesToHex(GenerateKey(seed, securityLevel, true, out ExportDefinition.VKeyGenResultEx result), true);\n            }\n            else if (DllExports.Contains(\"GenerateKeyEx\"))\n            {\n                return BitUtility.BytesToHex(GenerateKey(seed, securityLevel, false, out ExportDefinition.VKeyGenResultEx result), true);\n            }\n            else\n            {\n                return \"\";\n            }\n        }\n\n        public string GetECUName()\n        {\n            IntPtr procAddress = dllAddressMappings[\"GetECUName\"];\n            if (procAddress == IntPtr.Zero)\n            {\n                return \"(unavailable)\";\n            }\n            var fn = (ExportDefinition.GetECUName)Marshal.GetDelegateForFunctionPointer(procAddress, typeof(ExportDefinition.GetECUName));\n            IntPtr resultPtr = fn();\n            return Marshal.PtrToStringAnsi(resultPtr);\n        }\n        public string GetComment()\n        {\n            IntPtr procAddress = dllAddressMappings[\"GetComment\"];\n            if (procAddress == IntPtr.Zero)\n            {\n                return \"(unavailable)\";\n            }\n            var fn = (ExportDefinition.GetComment)Marshal.GetDelegateForFunctionPointer(procAddress, typeof(ExportDefinition.GetComment));\n            IntPtr resultPtr = fn();\n            return Marshal.PtrToStringAnsi(resultPtr);\n        }\n        public List<uint> GetConfiguredAccessTypes()\n        {\n            IntPtr procAddress = dllAddressMappings[\"GetConfiguredAccessTypes\"];\n            if (procAddress == IntPtr.Zero)\n            {\n                return new List<uint>();\n            }\n            uint[] accessTypes = new uint[1000];\n            var fn = (ExportDefinition.GetConfiguredAccessTypes)Marshal.GetDelegateForFunctionPointer(procAddress, typeof(ExportDefinition.GetConfiguredAccessTypes));\n            int accessTypesCount = fn(accessTypes);\n            return accessTypes.Take(accessTypesCount).ToList();\n        }\n        public int GetSeedLength(uint securityLevel)\n        {\n            IntPtr procAddress = dllAddressMappings[\"GetSeedLength\"];\n            if (procAddress == IntPtr.Zero)\n            {\n                return 0;\n            }\n            var fn = (ExportDefinition.GetSeedLength)Marshal.GetDelegateForFunctionPointer(procAddress, typeof(ExportDefinition.GetSeedLength));\n            return fn(securityLevel);\n        }\n        public int GetKeyLength(uint securityLevel)\n        {\n            IntPtr procAddress = dllAddressMappings[\"GetKeyLength\"];\n            if (procAddress == IntPtr.Zero)\n            {\n                return 0;\n            }\n            var fn = (ExportDefinition.GetKeyLength)Marshal.GetDelegateForFunctionPointer(procAddress, typeof(ExportDefinition.GetKeyLength));\n            return fn(securityLevel);\n        }\n\n        private byte[] GenerateKey(byte[] seed, uint securityLevel, bool addOptionParameter, out ExportDefinition.VKeyGenResultEx returnError)\n        {\n            returnError = ExportDefinition.VKeyGenResultEx.UnknownError;\n\n            IntPtr procAddress = dllAddressMappings[addOptionParameter ? \"GenerateKeyExOpt\" : \"GenerateKeyEx\"];\n            if ((!KeyGenerationCapability) || procAddress == IntPtr.Zero)\n            {\n                return new byte[] { };\n            }\n            byte[] keyResult = new byte[0x1000];\n            uint actualkeySize;\n            int keygenResult = (int)returnError;\n\n            if (addOptionParameter)\n            {\n                var fn = (ExportDefinition.GenerateKeyExOpt)Marshal.GetDelegateForFunctionPointer(procAddress, typeof(ExportDefinition.GenerateKeyExOpt));\n                keygenResult = fn(seed, (uint)seed.Length, securityLevel, null, null, keyResult, (uint)keyResult.Length, out actualkeySize);\n            }\n            else\n            {\n                var fn = (ExportDefinition.GenerateKeyEx)Marshal.GetDelegateForFunctionPointer(procAddress, typeof(ExportDefinition.GenerateKeyEx));\n                keygenResult = fn(seed, (uint)seed.Length, securityLevel, null, keyResult, (uint)keyResult.Length, out actualkeySize);\n            }\n            returnError = (ExportDefinition.VKeyGenResultEx)keygenResult;\n\n            keyResult = keyResult.Take((int)actualkeySize).ToArray();\n            return keyResult;\n        }\n\n        public void UnloadLibrary()\n        {\n            // WARNING: the instance will no longer be able to access native functions after this is called\n            // This is a workaround if many DLLs have to be enumerated for their metadata -- Windows has a limit on the number of DLLs that can be loaded simultaneously\n            UnmanagedUtility.FreeLibrary(dllHandle);\n        }\n\n        ~DllContext()\n        {\n            if (dllHandle != IntPtr.Zero)\n            {\n                UnmanagedUtility.FreeLibrary(dllHandle);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/SecurityAccess/ExportDefinition.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Runtime.InteropServices;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Diogenes.SecurityAccess\n{\n    class ExportDefinition\n    {\n        public static string[] KnownExportedFunctions = new string[] { \"GetECUName\", \"GetComment\", \"GetKeyLength\", \"GetSeedLength\", \"GetConfiguredAccessTypes\", \"GenerateKeyExOpt\", \"GenerateKeyEx\" };\n\n        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\n        public delegate IntPtr GetECUName();\n\n        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\n        public delegate IntPtr GetComment();\n\n        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\n        public delegate int GetKeyLength(uint iSecurityLevel);\n\n        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\n        public delegate int GetSeedLength(uint iSecurityLevel);\n\n        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\n        public delegate int GetConfiguredAccessTypes(uint[] iSecurityLevels);\n\n        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\n        public delegate int GenerateKeyExOpt(byte[] ipSeedArray, uint iSeedArraySize, uint iSecurityLevel, byte[] ipVariant, byte[] ipOptions, byte[] iopKeyArray, uint iMaxKeyArraySize, out uint oActualKeyArraySize);\n\n        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\n        public delegate int GenerateKeyEx(byte[] ipSeedArray, uint iSeedArraySize, uint iSecurityLevel, byte[] ipVariant, byte[] iopKeyArray, uint iMaxKeyArraySize, out uint oActualKeyArraySize);\n\n        public enum VKeyGenResultEx\n        {\n            OK = 0,\n            BufferTooSmall = 1,\n            SecurityLevelInvalid = 2,\n            VariantInvalid = 3,\n            UnknownError = 4\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/SecurityAccess/SecurityAutoLogin.cs",
    "content": "﻿using Caesar;\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\n\nnamespace Diogenes.SecurityAccess\n{\n    public class SecurityAutoLogin\n    {\n        public static void ReceiveSecurityResponse(byte[] response, ECU parentEcu, ECUConnection connection) \n        {\n            if (response.Length == 2)\n            {\n                // level change ack\n                Console.WriteLine($\"Security level has been successfully changed to 0x{(response[1] - 1):X}\");\n            }\n            else\n            {\n                // seed received\n                byte[] seedValue = response.Skip(2).ToArray();\n                string seedValueAsString = BitUtility.BytesToHex(seedValue, true);\n                int receiveLevel = response[1];\n\n                bool manualUnlockRequired = true;\n                if (QueryUnlockEcu(seedValue, parentEcu.Qualifier, receiveLevel, out byte[] key))\n                {\n                    if (RequestUnlock(connection, receiveLevel, key)) \n                    {\n                        Console.WriteLine($\"ECU has been automatically unlocked for level {receiveLevel}\");\n                        manualUnlockRequired = false;\n                    }\n                }\n                if (manualUnlockRequired)\n                {\n                    PromptClipboardCopyOfSeed(seedValueAsString);\n                }\n            }\n        }\n\n        private static bool RequestUnlock(ECUConnection connection, int receiveLevel, byte[] key) \n        {\n            List<byte> keyResponse = new List<byte>();\n            keyResponse.Add(0x27);\n            keyResponse.Add((byte)(receiveLevel + 1));\n            keyResponse.AddRange(key);\n\n            byte[] response = connection.SendMessage(keyResponse);\n\n            if ((response.Length == 2) && (response[0] == 0x67))\n            {\n                return true;\n            }\n            return false;\n        }\n\n        public static bool QueryUnlockEcu(byte[] seed, string ecuName, int level, out byte[] key)\n        {\n            string unlockEcuFolder = $\"{Application.StartupPath}{Path.DirectorySeparatorChar}UnlockECU{Path.DirectorySeparatorChar}\";\n            string binaryPath = $\"{unlockEcuFolder}ConsoleUnlockECU.exe\";\n            string dbPath = $\"{unlockEcuFolder}db.json\";\n\n            key = new byte[] { };\n\n            if (!(File.Exists(binaryPath) && File.Exists(dbPath)))\n            {\n                Console.WriteLine(\"Automatic unlock is unavailable (executable or database could not be found)\");\n                return false;\n            }\n\n            string successIdentifier = \"DIOGENES\";\n\n            string args = $\"-d \\\"{dbPath}\\\" -n {ecuName} -l {level} -s {BitUtility.BytesToHex(seed)} -p {successIdentifier}\";\n            string result = RunProcessCaptureOutput(binaryPath, args);\n            if (!result.StartsWith(successIdentifier)) \n            {\n                return false;\n            }\n            string responseAsString = result.Substring(successIdentifier.Length);\n            Console.WriteLine($\"UnlockECU (automatic) returns {responseAsString} for seed {BitUtility.BytesToHex(seed)} (ECU: {ecuName}, Level: {level})\");\n\n            key = BitUtility.BytesFromHex(responseAsString);\n            return true;\n        }\n\n\n        private static string RunProcessCaptureOutput(string filePath, string args) \n        {\n            // see https://stackoverflow.com/questions/285760/how-to-spawn-a-process-and-capture-its-stdout-in-net\n\n            StringBuilder outputBuilder;\n            ProcessStartInfo processStartInfo;\n            Process process;\n\n            outputBuilder = new StringBuilder();\n\n            processStartInfo = new ProcessStartInfo();\n            processStartInfo.CreateNoWindow = true;\n            processStartInfo.RedirectStandardOutput = true;\n            processStartInfo.RedirectStandardInput = true;\n            processStartInfo.UseShellExecute = false;\n            processStartInfo.Arguments = args;\n            processStartInfo.FileName = filePath;\n\n            process = new Process();\n            process.StartInfo = processStartInfo;\n            // enable raising events because Process does not raise events by default\n            process.EnableRaisingEvents = true;\n            // attach the event handler for OutputDataReceived before starting the process\n            process.OutputDataReceived += new DataReceivedEventHandler\n            (\n                delegate (object sender, DataReceivedEventArgs e)\n                {\n                    // append the new data to the data already read-in\n                    outputBuilder.Append(e.Data);\n                }\n            );\n            // start the process\n            // then begin asynchronously reading the output\n            // then wait for the process to exit\n            // then cancel asynchronously reading the output\n            process.Start();\n            process.BeginOutputReadLine();\n            process.WaitForExit();\n            process.CancelOutputRead();\n\n            // use the output\n            return outputBuilder.ToString();\n        }\n\n        private static void PromptClipboardCopyOfSeed(string seed)\n        {\n            if (MessageBox.Show($\"Received a seed value of {seed}. \\r\\nCopy to clipboard?\", \"Security Access\", MessageBoxButtons.YesNo) == DialogResult.Yes)\n            {\n                Clipboard.SetText(seed);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/Simulation/SimulatedDevice.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Diogenes.Simulation\n{\n    // this whole simulation setup is required for my debugging as I don't always have access to my ECU/J2534 device\n    public class SimulatedDevice\n    {\n        public virtual byte[] ReceiveRequest(IEnumerable<byte> request)\n        {\n            Console.WriteLine(\"ReceiveRequest was not overridden!\");\n            return new byte[] { };\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/Simulation/Simulated_CRD3.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.IO;\nusing Caesar;\n\nnamespace Diogenes.Simulation\n{\n    public class Simulated_CRD3 : SimulatedDevice\n    {\n        // quacks like a CRD3 : 2131 from a DTC perspective\n        public enum UDS : byte\n        {\n            UDS_AccessTimingParameters = 0x83,\n            UDS_Authentication = 0x29,\n            UDS_ClearDiagnosticInformation = 0x14,\n            UDS_CommunicationControl = 0x28,\n            UDS_ControlDTCSettings = 0x85,\n            UDS_DiagnosticSessionControl = 0x10,\n            UDS_DynamicallyDefineDataIdentifier = 0x2C,\n            UDS_ECUReset = 0x11,\n            UDS_InputOutputControlByIdentifier = 0x2F,\n            UDS_LinkControl = 0x87,\n            UDS_NegativeResponse = 0x7F,\n            UDS_ReadDataByIdentifier = 0x22,\n            UDS_ReadDataByIdentifierPeriodic = 0x2A,\n            UDS_ReadDTCInformation = 0x19,\n            UDS_ReadMemoryByAddress = 0x23,\n            UDS_ReadScalingDataByIdentifier = 0x24,\n            UDS_RequestDownload = 0x34,\n            UDS_RequestFileTransfer = 0x38,\n            UDS_RequestTransferExit = 0x37,\n            UDS_RequestUpload = 0x35,\n            UDS_ResponseOnEvent = 0x86,\n            UDS_RoutineControl = 0x31,\n            UDS_SecuredDataTransmission = 0x84,\n            UDS_SecurityAccess = 0x27,\n            UDS_TesterPresent = 0x3E,\n            UDS_TransferData = 0x36,\n            UDS_WriteDataByIdentifier = 0x2E,\n            UDS_WriteMemoryByAddress = 0x3D,\n        }\n\n        public enum NR : byte \n        {\n            NR_PositiveResponse = 0x00,\n            NR_GeneralReject = 0x10,\n            NR_ServiceNotSupported = 0x11,\n            NR_SubfunctionNotSupported = 0x12,\n            NR_IncorrectMessageLengthOrInvalidFormat = 0x13,\n            NR_ResponseTooLong = 0x14,\n            NR_BusyRepeatRequest = 0x21,\n            NR_ConditionsNotCorrect = 0x22,\n            NR_RequestSequenceError = 0x24,\n            NR_NoResponseFromSubnetComponent = 0x25,\n            NR_FailurePreventsExecutionOfRequestedAction = 0x26,\n            NR_RequestOutOfRange = 0x31,\n            NR_SecurityAccessDenied = 0x33,\n            NR_InvalidKey = 0x35,\n            NR_ExceedNumberOfAttempts = 0x36,\n            NR_RequiredTimeDelayNotExpired = 0x37,\n            NR_UploadDownloadNotAccepted = 0x70,\n            NR_TransferDataSuspended = 0x71,\n            NR_GeneralProgrammingFailure = 0x72,\n            NR_WrongBlockSequenceCounter = 0x73,\n            NR_RequestCorrectlyReceivedResponsePending = 0x78,\n            NR_SubfunctionNotSupportedInActiveSession = 0x7E,\n            NR_ServiceNotSupportedInActiveSession = 0x7F,\n            NR_RpmTooHigh = 0x81,\n            NR_RpmTooLow = 0x82,\n            NR_EngineRunning = 0x83,\n            NR_EngineNotRunning = 0x84,\n            NR_EngineRunTimeTooLow = 0x85,\n            NR_TemperatureTooHigh = 0x86,\n            NR_TemperatureTooLow = 0x87,\n            NR_VehicleSpeedTooHigh = 0x88,\n            NR_VehicleSpeedTooLow = 0x89,\n            NR_ThrottlePedalTooHigh = 0x8A,\n            NR_ThrottlePedalTooLow = 0X8B,\n            NR_TransmissionRangeNotInNeutral = 0X8C,\n            NR_TransmissionRangeNotInGear = 0x8D,\n            NR_BrakeSwitchesNotClosed = 0x8F,\n            NR_ShifterLeverNotInPark = 0x90,\n            NR_TorqueConverterClutchLocked = 0x91,\n            NR_VoltageTooHigh = 0x92,\n            NR_VoltageTooLow = 0x93,\n        }\n\n        public enum Identifier : ushort \n        {\n            ID_SessionVariant = 0xF100,\n            ID_SupplierIdentifier = 0xF154,\n            ID_EROTAN = 0xF196,\n            ID_VCFull = 0x1001,\n            ID_VCPartial = 0x1002,\n        }\n\n        public enum Vendor : byte \n        {\n            VENDOR_Unspecified = 0,\n            VENDOR_Becker = 1,\n            VENDOR_Blaupunkt = 2,\n            VENDOR_Bosch = 3,\n            VENDOR_MB = 4,\n            VENDOR_HuF = 5,\n            VENDOR_Kammerer = 6,\n            VENDOR_Kostal = 7,\n            VENDOR_Siemens = 8,\n            VENDOR_Stribel = 9,\n            VENDOR_MicroHeat = 10,\n            VENDOR_JATCO = 11,\n            VENDOR_SWF = 16,\n            VENDOR_VDO = 17,\n            VENDOR_Webasto = 18,\n            VENDOR_Dornier = 19,\n            VENDOR_TEG = 20,\n            VENDOR_Hella = 21,\n            VENDOR_Lucas = 22,\n            VENDOR_GKR = 23,\n            VENDOR_MBB = 24,\n            VENDOR_Motometer = 25,\n            VENDOR_Borg = 32,\n            VENDOR_Temic = 33,\n            VENDOR_Teves = 34,\n            VENDOR_Borg_Warner = 35,\n            VENDOR_MED_SPA = 36,\n            VENDOR_DENSO = 37,\n            VENDOR_ZF = 38,\n            VENDOR_TRW = 39,\n            VENDOR_Dunlop = 40,\n            VENDOR_LUK = 41,\n            VENDOR_Magneti_Marelli = 48,\n            VENDOR_DODUCO = 49,\n            VENDOR_Alpine = 50,\n            VENDOR_AMC_AEG_Mobile = 51,\n            VENDOR_Bose = 52,\n            VENDOR_Dasa = 53,\n            VENDOR_Motorola = 54,\n            VENDOR_Nokia = 55,\n            VENDOR_Panasonic = 56,\n            VENDOR_APAG = 57,\n            VENDOR_Rialtosoft = 58,\n            VENDOR_Applicom = 59,\n            VENDOR_Conti_Temic = 60,\n            VENDOR_Cherry = 61,\n            VENDOR_TI_Automotive = 62,\n            VENDOR_Kongsberg_Company = 63,\n            VENDOR_Delphi = 64,\n            VENDOR_Alfmeier = 65,\n            VENDOR_Sidler = 66,\n            VENDOR_Marquardt = 67,\n            VENDOR_Wehrle = 68,\n            VENDOR_megamos = 69,\n            VENDOR_ADC = 70,\n            VENDOR_BERU = 71,\n            VENDOR_Valeo = 72,\n            VENDOR_Magna = 73,\n            VENDOR_Allison = 74,\n            VENDOR_Isringhausen = 75,\n            VENDOR_Grammer = 76,\n            VENDOR_Funkwerk_Dabendorf = 77,\n            VENDOR_Hella_Behr = 78,\n            VENDOR_Pollak = 79,\n            VENDOR_AKG = 80,\n            VENDOR_Automotive_Lighting = 81,\n            VENDOR_TAG = 82,\n            VENDOR_UNITED_PARTS = 83,\n            VENDOR_catem = 84,\n            VENDOR_Alge = 85,\n            VENDOR_Pierburg = 86,\n            VENDOR_Brusa = 87,\n            VENDOR_Ecostar = 88,\n            VENDOR_Xcellsis = 89,\n            VENDOR_Wabco_Automotive = 90,\n            VENDOR_Voith = 91,\n            VENDOR_Knorr = 92,\n            VENDOR_TVI = 93,\n            VENDOR_Stoneridge = 94,\n            VENDOR_Telma = 95,\n            VENDOR_STW = 96,\n            VENDOR_Koyo = 97,\n            VENDOR_Eberspacher = 98,\n            VENDOR_ADVICS = 99,\n            VENDOR_OMRON = 100,\n            VENDOR_Mitsubishi_Heavy_Industry = 101,\n            VENDOR_Methode = 102,\n            VENDOR_UNISIAJECS = 103,\n            VENDOR_UNISIA_JKC_Steering_Systems = 104,\n            VENDOR_AISIN = 105,\n            VENDOR_Zexel_Valeo = 106,\n            VENDOR_Schrader = 107,\n            VENDOR_Ballard = 108,\n            VENDOR_SFT = 112,\n            VENDOR_Kieckert_AG = 113,\n            VENDOR_Behr = 114,\n            VENDOR_MB_Lenkungen = 115,\n            VENDOR_Sachs_Automotive = 116,\n            VENDOR_Peiker = 117,\n            VENDOR_Petri = 118,\n            VENDOR_Autoliv = 119,\n            VENDOR_Thien_Electronic = 120,\n            VENDOR_Siemens_VDO = 121,\n            VENDOR_Dornier_Consulting_GmbH = 122,\n            VENDOR_Alps = 123,\n            VENDOR_PREH = 124,\n            VENDOR_Hitachi_Unisia = 125,\n            VENDOR_Hitachi = 126,\n            VENDOR_Reserved_127 = 127,\n            VENDOR_Huntsville = 128,\n            VENDOR_Yazaki = 129,\n            VENDOR_Lear = 130,\n            VENDOR_Johnson_Controls = 131,\n            VENDOR_HarmanBecker = 132,\n            VENDOR_Mitsubishi_Electric = 133,\n            VENDOR_Tokico_USA_Inc = 134,\n            VENDOR_Nippon_Seiki_International = 135,\n            VENDOR_Inalfa = 136,\n            VENDOR_Nippon_Seiki_UK = 137,\n            VENDOR_GHSP = 138,\n            VENDOR_Vector = 139,\n            VENDOR_Gentex = 140,\n            VENDOR_Visteon = 141,\n            VENDOR_Tochigi_Fuji = 142,\n            VENDOR_DCA = 143,\n            VENDOR_May_and_Scofield = 144,\n            VENDOR_DaimlerChrysler_Hamburg_Plant = 145,\n            VENDOR_AISIN_AW = 146,\n            VENDOR_TOYODA_MACHINE_WORKS = 147,\n            VENDOR_Solectron_Invotronics = 148,\n            VENDOR_Kicker = 149,\n            VENDOR_American_Axle_Company = 150,\n            VENDOR_GETRAG = 151,\n            VENDOR_Promate = 152,\n            VENDOR_ArvinMeritor = 153,\n            VENDOR_Reserved_MMC = 160,\n            VENDOR_Reserved_MMC_SMART = 161,\n            VENDOR_Reserved_162 = 162,\n            VENDOR_After_Market_Supplier = 254,\n            VENDOR_Unidentified = 255,\n        }\n\n        public Simulated_CRD3() \n        {\n        \n        }\n\n\n        //ushort ECU_VARIANT = 0x2131;\n        ushort ECU_VARIANT = 0x1000; // pretend to be eis166 for a while\n        byte ECU_SUPPLIER_IDENTIFIER = (byte)Vendor.VENDOR_Delphi;\n\n        byte ECU_SESSION = 1; // default\n        byte ECU_GATEWAY_MODE = 2;\n        ushort  ECU_TIMING_RESOLUTION_1MS = 20;\n        ushort ECU_TIMING_RESOLUTION_10MS = 200;\n\n        byte[] ECU_VariantCoding = { 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x10, 0x21, 0x40, 0xAF, 0x8C, 0xE0, 0x24, 0x58, 0x91, 0x59, 0x98, 0x56, 0x20, 0x49, 0x47, 0x7D, 0x00, 0xE5, 0x00, 0x36, 0x36 };\n        byte[] ECU_Fingerprint = { 0x00, 0x40, 0x33, 0x10 };\n        byte[] ECU_SoftwareCalibrationNumber = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38 };\n        byte[] ECU_EROTAN = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };\n\n        byte[] EnvTest = {0x00, 0x90, 0x00, 0x2F, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x06, 0x28, 0x02, 0x00, 0x24, 0x00, 0x93, 0x00, 0x38, 0x02, 0x0F, 0x01, 0x04, 0x7F, 0x7C, 0x00, 0x88, 0x8E, 0xA5, 0x3C, 0x0A, 0x00, 0x00, 0x00, 0x5F, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x03, 0x00, 0x24, 0x00, 0x93, 0x00, 0x38, 0x02, 0x0F, 0x01, 0x04, 0x7F, 0x7C, 0x00, 0x88, 0x8E, 0xA5, 0x3C, 0x0A, 0x00, 0x00, 0x00, 0x5F, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00 };\n\n        // this behaves a bit more like my uC implementation\n        // performance is generally poorer, though the IO is fairly minimal\n        // maybe wrap it in a class with a proper binarywriter\n        List<byte> SharedResponse = new List<byte>();\n\n        public void WriteByte(byte inByte)\n        {\n            SharedResponse.Add(inByte);\n        }\n        public void WriteUint16(ushort inValue)\n        {\n            SharedResponse.Add((byte)((inValue >> 8) & 0xFF));\n            SharedResponse.Add((byte)(inValue & 0xFF));\n        }\n        public void WriteInt16(short inValue)\n        {\n            SharedResponse.Add((byte)((inValue >> 8) & 0xFF));\n            SharedResponse.Add((byte)(inValue & 0xFF));\n        }\n        public void WriteUint32(ushort inValue)\n        {\n            SharedResponse.Add((byte)((inValue >> 24) & 0xFF));\n            SharedResponse.Add((byte)((inValue >> 16) & 0xFF));\n            SharedResponse.Add((byte)((inValue >> 8) & 0xFF));\n            SharedResponse.Add((byte)(inValue & 0xFF));\n        }\n        public void WriteInt32(int inValue)\n        {\n            SharedResponse.Add((byte)((inValue >> 24) & 0xFF));\n            SharedResponse.Add((byte)((inValue >> 16) & 0xFF));\n            SharedResponse.Add((byte)((inValue >> 8) & 0xFF));\n            SharedResponse.Add((byte)(inValue & 0xFF));\n        }\n\n        public void WriteByteArray(byte[] inValue) \n        {\n            SharedResponse.AddRange(inValue);\n        }\n\n\n        public byte[] CreateNegativeResponse(UDS callingFunction, NR reason) \n        {\n            // throw new Exception(\"debugger please\");\n            return new byte[] {0x7F, (byte)callingFunction, (byte)reason };\n        }\n\n        public byte[] MemoryStreamWriterToArray(BinaryWriter writer) \n        {\n            return ((MemoryStream)writer.BaseStream).ToArray();\n        }\n        \n        public override byte[] ReceiveRequest(IEnumerable<byte> request)\n        {\n            SharedResponse = new List<byte>();\n\n            byte[] requestBytes = request.ToArray();\n            if (requestBytes.Length == 0)\n            {\n                // this shouldn't happen\n                return new byte[] { };\n            }\n            \n            if (!Enum.IsDefined(typeof(UDS), requestBytes[0]))\n            {\n                return CreateNegativeResponse((UDS)requestBytes[0], NR.NR_ServiceNotSupported);\n            }\n            UDS requestCommand = (UDS)requestBytes[0];\n            WriteByte((byte)(requestBytes[0] + 0x40));\n\n            ushort identifier = 0;\n            if (requestBytes.Length > 2) \n            {\n                identifier = (ushort)(requestBytes[1] << 8 | requestBytes[2]);\n            }\n\n            if ((requestCommand == UDS.UDS_TesterPresent) && (requestBytes.Length >= 2))\n            {\n                WriteByte(requestBytes[1]);\n            }\n            else if ((requestCommand == UDS.UDS_DiagnosticSessionControl) && (requestBytes.Length >= 2))\n            {\n                ECU_SESSION = requestBytes[1];\n                WriteByte(ECU_SESSION);\n                WriteUint16(ECU_TIMING_RESOLUTION_1MS);\n                WriteUint16(ECU_TIMING_RESOLUTION_10MS);\n            }\n            else if ((requestCommand == UDS.UDS_ReadDataByIdentifier) && (requestBytes.Length >= 3))\n            {\n                WriteUint16(identifier);\n                if (identifier == (ushort)Identifier.ID_SupplierIdentifier)\n                {\n                    WriteByte(ECU_SUPPLIER_IDENTIFIER);\n                }\n                else if (identifier == (ushort)Identifier.ID_SessionVariant)\n                {\n                    WriteByte(ECU_GATEWAY_MODE);\n                    WriteUint16(ECU_VARIANT);\n                    WriteByte(ECU_SESSION);\n                }\n            }\n            else if ((requestCommand == UDS.UDS_WriteDataByIdentifier) && (requestBytes.Length >= 3))\n            {\n\n            }\n            else if ((requestCommand == UDS.UDS_ReadDTCInformation) && (requestBytes.Length >= 2))\n            {\n                byte infoType = requestBytes[1];\n                WriteByte(infoType);\n\n                byte mask = requestBytes[2];\n\n                if (infoType == 0x02)\n                {\n                    /*\n                    // mask should go here?\n                    WriteByte(0xFF); // mask\n                    WriteByte(0x00);\n                    WriteByte(0x90);\n                    WriteByte(0x00);\n                    WriteByte(0x2F);\n                    */\n                    WriteByteArray(BitUtility.BytesFromHex(\"5B D0 3D 2A 0B D0 32 2A 0B C0 19 2A 0B D0 38 2A 08 C1 22 87 0B D1 82 00 0B D1 80 00 0B 06 10 00 0B D1 81 00 03 D1 83 00 03 D1 98 00 41\")); // eis166\n                }\n                else if (infoType == 0x06)\n                {\n                    /*\n                    WriteByte(0xFF); // mask\n                    WriteByteArray(EnvTest);\n                    */\n                    WriteByteArray(BitUtility.BytesFromHex(\"D0 3D 2A 0B 01 00 2A C0 2A C0 09 00 \")); // eis166\n                }\n            }\n            else\n            {\n                // unrecognized\n                return CreateNegativeResponse((UDS)requestBytes[0], NR.NR_ServiceNotSupported);\n            }\n\n            return SharedResponse.ToArray();\n        }\n\n        public static ushort CRC16ARC(byte[] inData) \n        {\n            // tests:\n            /*\n            Console.WriteLine($\"{Simulation.Simulated_CRD3.CRC16ARC(new byte[] { 0x78, 0x65, 0x36, 0x62, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x0B, 0x0B, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x01, 0x81, 0x03, 0xFF, 0xC1, 0x74, 0x0E, 0xE8, 0x03, 0x72, 0x0B, 0xC8, 0x08, 0xC2, 0x01 }):X4}\"); // expects E6 2B (0x2BE6)\n            Console.WriteLine($\"{Simulation.Simulated_CRD3.CRC16ARC(new byte[] { 0x78, 0x64, 0x70, 0x39, 0x0C, 0x00, 0x00, 0x04, 0x00, 0x03, 0x02, 0x02, 0x02, 0x02, 0x00, 0x02, 0x01, 0x00, 0x01, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x1A, 0x00, 0xA6, 0x09, 0xE8, 0x03, 0xE8, 0x03, 0xC6, 0x07, 0x81, 0x01 }):X4}\"); // expects C1 12 (0x12C1)\n             */\n            uint[] crcTable = {\n                0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,\n                0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,\n                0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,\n                0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,\n                0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,\n                0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,\n                0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,\n                0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,\n                0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,\n                0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,\n                0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,\n                0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,\n                0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,\n                0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,\n                0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,\n                0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,\n                0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,\n                0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,\n                0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,\n                0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,\n                0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,\n                0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,\n                0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,\n                0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,\n                0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,\n                0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,\n                0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,\n                0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,\n                0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,\n                0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,\n                0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,\n                0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040,\n            };\n\n            uint crc = 0;\n            foreach (byte b in inData)\n            {\n                crc = (crc >> 8) ^ crcTable[(crc ^ b) & 0xFF];\n            }\n            return (ushort)(crc & 0xFFFF);\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/TextboxWriter.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\n\nnamespace Diogenes\n{\n    public class TextboxWriter : TextWriter\n    {\n        private TextBox InputTextbox;\n        private Timer timer;\n        private StringBuilder sb = new StringBuilder();\n        private bool dirty = false;\n        private readonly object WriteLock = new object();\n\n        public TextboxWriter(TextBox inputTextbox)\n        {\n            InputTextbox = inputTextbox;\n            timer = new Timer();\n            timer.Interval = 30;\n            timer.Tick += Timer_Tick;\n            timer.Enabled = true;\n        }\n\n        private void Timer_Tick(object sender, EventArgs e)\n        {\n            // using a timer since invoking an event on every character write gets expensive quickly\n            if (dirty || (InputTextbox.Text.Length != sb.Length))\n            {\n                InputTextbox.Text = sb.ToString();\n                dirty = false;\n                InputTextbox.SelectionStart = InputTextbox.TextLength;\n                InputTextbox.ScrollToCaret();\n            }\n        }\n\n        // fix append for crossthread : https://stackoverflow.com/questions/12645351/stringbuilder-tostring-throw-an-index-out-of-range-exception\n        public override void Write(char value)\n        {\n            lock (WriteLock)\n            {\n                sb.Append(value);\n                dirty = true;\n            }\n        }\n\n        public override void Write(string value)\n        {\n            lock (WriteLock)\n            {\n                sb.Append(value);\n                dirty = true;\n            }\n        }\n\n        public void Clear()\n        {\n            sb = new StringBuilder();\n            dirty = true;\n        }\n\n        public override Encoding Encoding\n        {\n            get { return Encoding.Unicode; }\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/UnmanagedUtility.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Runtime.InteropServices;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Diogenes\n{\n    class UnmanagedUtility\n    {   /*\n        Symbol enumeration: \n        https://stackoverflow.com/questions/18249566/c-sharp-get-the-list-of-unmanaged-c-dll-exports\n        */\n\n        [DllImport(\"dbghelp.dll\", SetLastError = true, CharSet = CharSet.Unicode)]\n        [return: MarshalAs(UnmanagedType.Bool)]\n        public static extern bool SymInitialize(IntPtr hProcess, string UserSearchPath, [MarshalAs(UnmanagedType.Bool)] bool fInvadeProcess);\n\n        [DllImport(\"dbghelp.dll\", SetLastError = true, CharSet = CharSet.Unicode)]\n        [return: MarshalAs(UnmanagedType.Bool)]\n        public static extern bool SymCleanup(IntPtr hProcess);\n\n        [DllImport(\"dbghelp.dll\", SetLastError = true, CharSet = CharSet.Unicode)]\n        public static extern ulong SymLoadModuleEx(IntPtr hProcess, IntPtr hFile, string ImageName, string ModuleName, long BaseOfDll, int DllSize, IntPtr Data, int Flags);\n\n        [DllImport(\"dbghelp.dll\", SetLastError = true, CharSet = CharSet.Unicode)]\n        [return: MarshalAs(UnmanagedType.Bool)]\n        public static extern bool SymEnumerateSymbols64(IntPtr hProcess, ulong BaseOfDll, SymEnumerateSymbolsProc64 EnumSymbolsCallback, IntPtr UserContext);\n\n        public delegate bool SymEnumerateSymbolsProc64(string SymbolName, ulong SymbolAddress, uint SymbolSize, IntPtr UserContext);\n\n        /*\n        DLL invocation:\n        https://stackoverflow.com/questions/16518943/dllimport-or-loadlibrary-for-best-performance\n        */\n\n        [DllImport(\"kernel32.dll\")]\n        public static extern IntPtr LoadLibrary(string dllToLoad);\n\n        [DllImport(\"kernel32.dll\")]\n        public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);\n\n        [DllImport(\"kernel32.dll\")]\n        public static extern bool FreeLibrary(IntPtr hModule);\n\n        public const int TVM_SETEXTENDEDSTYLE = 0x1100 + 44;\n        public const int TVM_GETEXTENDEDSTYLE = 0x1100 + 45;\n        public const int TVS_EX_DOUBLEBUFFER = 0x0004;\n        public const int EM_SETCUEBANNER = 0x1501;\n\n        [DllImport(\"user32.dll\", CharSet = CharSet.Auto)]\n        public static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);\n\n        [DllImport(\"user32.dll\", CharSet = CharSet.Auto)]\n        public static extern Int32 SendMessage(IntPtr hWnd, int msg, int wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);\n\n        private static List<string> LibraryExports = new List<string>();\n\n        public static bool SymbolEnumeratedCallback(string name, ulong address, uint size, IntPtr context)\n        {\n            // Useful for debug:\n            // Console.WriteLine(name);\n            LibraryExports.Add(name);\n            return true;\n        }\n        private static bool EnumerateDllExports(string modulePath)\n        {\n            IntPtr hCurrentProcess = Process.GetCurrentProcess().Handle;\n\n            ulong dllBase;\n\n            // Initialize symbol handler with our own process handle \n            if (!SymInitialize(hCurrentProcess, null, false))\n            {\n                Console.WriteLine(\"SymInitialize function (dbghelp.h) failed\");\n                return false;\n            }\n\n            // Load dll\n            dllBase = SymLoadModuleEx(hCurrentProcess, IntPtr.Zero, modulePath, null, 0, 0, IntPtr.Zero, 0);\n\n            if (dllBase == 0)\n            {\n                Console.Out.WriteLine($\"Failed to load module: {modulePath}\");\n                SymCleanup(hCurrentProcess);\n                return false;\n            }\n\n            // Clean up the results list before it gets populated\n            LibraryExports.Clear();\n\n            // Enumerate symbols. For every symbol, the callback method SymbolEnumeratedCallback is called.\n            if (SymEnumerateSymbols64(hCurrentProcess, dllBase, SymbolEnumeratedCallback, IntPtr.Zero) == false)\n            {\n                Console.Out.WriteLine($\"Failed to enumerate symbols for library {modulePath}\");\n                return false;\n            }\n\n            SymCleanup(hCurrentProcess);\n            return true;\n        }\n\n        public static List<string> GetExports(string modulePath)\n        {\n            if (EnumerateDllExports(modulePath))\n            {\n                return LibraryExports;\n            }\n            else\n            {\n                return new List<string>();\n            }\n        }\n\n        public static void DumpExportsToConsole(string modulePath)\n        {\n            List<string> exports = UnmanagedUtility.GetExports(modulePath);\n            Console.WriteLine($\"Retrieving exports for {modulePath}\");\n            foreach (string s in exports)\n            {\n                Console.WriteLine($\"{modulePath}: {s}\");\n            }\n            Console.WriteLine($\"End of {modulePath} exports.\");\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/VariantCoding.cs",
    "content": "﻿using Caesar;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\n\nnamespace Diogenes\n{\n    public class VariantCoding\n    {\n\n        private static void ExecVCWrite(byte[] request, DiagService service, ECUConnection connection, bool writesEnabled)\n        {\n            bool allowVcWrite = writesEnabled; // allowWriteVariantCodingToolStripMenuItem.Checked;\n            if (allowVcWrite)\n            {\n                connection.ExecUserDiagJob(request, service);\n                Console.WriteLine(\"VC Write completed\");\n            }\n            else\n            {\n                MessageBox.Show(\"This VC write action has to be manually enabled under \\r\\nFile >  Allow Write Variant Coding\\r\\nPlease make sure that you understand the risks before doing so.\",\n                    \"Accidental Brick Protection\");\n            }\n        }\n\n        /*\n            test: med40\n\n            jg: dumping pres\n            jg: q: SID_RQ pos byte: 0 size bytes: 1 modecfg:323 fieldtype: IntegerType dump: 2E 00 00 00\n            jg: q: RecordDataIdentifier pos byte: 1 size bytes: 2 modecfg:324 fieldtype: IntegerType dump: 01 10 00 00\n            jg: q: #0 pos byte: 33 size bytes: 16 modecfg:6430 fieldtype: BitDumpType dump: \n            jg: q: #1 pos byte: 49 size bytes: 1 modecfg:6423 fieldtype: IntegerType dump: \n            jg: q: #2 pos byte: 50 size bytes: 1 modecfg:6423 fieldtype: IntegerType dump: \n            jg: q: #3 pos byte: 51 size bytes: 1 modecfg:6423 fieldtype: IntegerType dump: \n            jg: q: #4 pos byte: 52 size bytes: 1 modecfg:6423 fieldtype: IntegerType dump: \n            jg: q: #5 pos byte: 3 size bytes: 50 modecfg:6410 fieldtype: ExtendedBitDumpType dump: \n            jg: done dumping pres\n\n            */\n\n\n        public static void DoVariantCoding(ECUConnection connection, VCForm vcForm, bool writesEnabled) \n        {\n            Console.WriteLine($\"Operator requesting for VC: {BitUtility.BytesToHex(vcForm.VCValue, true)}\");\n\n            RunDiagForm runDiagForm = new RunDiagForm(vcForm.WriteService);\n\n            // construct a write command from presentations: fill up the VC value first, fill up all available dumps, then inherit the last values (fingerprints, scn) from the read command\n            byte[] vcParameter = vcForm.VCValue;\n            byte[] writeCommand = vcForm.WriteService.RequestBytes;\n            byte[] priorReadCommand = vcForm.UnfilteredReadValue;\n\n\n            // start with a list of all values that we will have to fill\n            List<DiagPreparation> preparationsToProcess = new List<DiagPreparation>(vcForm.WriteService.InputPreparations);\n\n            // fill up vc, which pretty much always uses the ExtendedBitDumpType type\n            DiagPreparation vcPrep = preparationsToProcess.Find(x => x.FieldType == DiagPreparation.InferredDataType.ExtendedBitDumpType);\n            if (vcPrep is null)\n            {\n                MessageBox.Show(\"VC: Could not find the VC ExtendedBitDump prep, stopping early to save your ECU.\", \"VC Error\", MessageBoxButtons.OK, MessageBoxIcon.Error);\n                return;\n            }\n            int vcPrepSizeInBytes = vcPrep.SizeInBits / 8;\n            int vcPrepBytePosition = vcPrep.BitPosition / 8;\n            if (vcPrepSizeInBytes < vcParameter.Length)\n            {\n                MessageBox.Show(\"VC: VC string is longer than the parameter can fit, stopping early to save your ECU.\", \"VC Error\", MessageBoxButtons.OK, MessageBoxIcon.Error);\n                return;\n            }\n            // zero out the destination buffer for the param that we intend to write since there's a possibility that our param is shorter than the actual prep's size\n            for (int i = vcPrepBytePosition; i < (vcPrepBytePosition + vcPrepSizeInBytes); i++)\n            {\n                writeCommand[i] = 0;\n            }\n            // copy the parameter in\n            Array.ConstrainedCopy(vcParameter, 0, writeCommand, vcPrepBytePosition, vcParameter.Length);\n            preparationsToProcess.Remove(vcPrep);\n            // done with vc prep\n\n\n            // merge prefilled constants such as the (SID_RQ, id..)\n            List<DiagPreparation> prefilledValues = new List<DiagPreparation>();\n            foreach (DiagPreparation prep in preparationsToProcess)\n            {\n                if (prep.Dump.Length > 0)\n                {\n                    prefilledValues.Add(prep);\n                    if (prep.FieldType == DiagPreparation.InferredDataType.IntegerType)\n                    {\n                        byte[] fixedDump = prep.Dump.Take(prep.SizeInBits / 8).Reverse().ToArray();\n                        Array.ConstrainedCopy(vcParameter, 0, writeCommand, vcPrepBytePosition, vcParameter.Length);\n                    }\n                    else\n                    {\n                        Console.WriteLine($\"Skipping prefill for {prep.Qualifier} as the data type {prep.FieldType} is unsupported.\");\n                    }\n                }\n            }\n            // \"mark\" the constants as done\n            foreach (DiagPreparation prep in prefilledValues)\n            {\n                preparationsToProcess.Remove(prep);\n            }\n\n            // isolate the SCN if it exists\n            foreach (DiagPreparation prep in preparationsToProcess)\n            {\n                int bytePosition = prep.BitPosition / 8;\n                int byteLength = prep.SizeInBits / 8;\n                // SCN is always 16-bytes\n                if (byteLength != 16)\n                {\n                    continue;\n                }\n                byte[] originalValue = new byte[byteLength];\n                Array.ConstrainedCopy(priorReadCommand, bytePosition, originalValue, 0, byteLength);\n\n                // SCN values are ASCII numerals (between 0x30 - 0x39)\n                bool isValidSCN = true;\n                foreach (byte b in originalValue) \n                {\n                    if ((b > 0x39) || (b < 0x30)) \n                    {\n                        isValidSCN = false;\n                        break;\n                    }\n                }\n                if (!isValidSCN) \n                {\n                    continue;\n                }\n\n                Console.WriteLine($\"Found SCN value: {Encoding.ASCII.GetString(originalValue)}\");\n\n                // check if operator is using vediamo-style variant-coding, where the SCN is set to 0000000000000000 when writing VC\n                // otherwise, we can reuse the last value as read from the ECU\n                bool useVediamoBehaviorZeroSCN = Preferences.GetValue(Preferences.PreferenceKey.EnableSCNZero) == \"true\";\n                if (useVediamoBehaviorZeroSCN) \n                {\n                    for (int i = 0; i < originalValue.Length; i++) \n                    {\n                        originalValue[i] = 0x30;\n                    }\n                }\n\n                Console.WriteLine($\"Using {Encoding.ASCII.GetString(originalValue)} as new SCN value\");\n\n                // write-back the recognized (and optionally, modified) SCN\n                Array.ConstrainedCopy(originalValue, 0, writeCommand, bytePosition, byteLength);\n                preparationsToProcess.Remove(prep);\n                break;\n            }\n\n            // isolate the fingerprint if it exists\n            // normally fingerprint is appended at the tail of the VC command\n            List<int> tailIndices = new List<int>() { writeCommand.Length - 1, writeCommand.Length - 2, writeCommand.Length - 3, writeCommand.Length - 4 };\n            List<DiagPreparation> possibleFingerprintFields = new List<DiagPreparation>();\n            foreach (DiagPreparation prep in preparationsToProcess)\n            {\n                int bytePosition = prep.BitPosition / 8;\n                int byteLength = prep.SizeInBits / 8;\n\n                if ((prep.FieldType == DiagPreparation.InferredDataType.IntegerType) && (byteLength == 1) && (tailIndices.Contains(bytePosition)))\n                {\n                    tailIndices.Remove(bytePosition);\n                    possibleFingerprintFields.Add(prep);\n                }\n            }\n            if (possibleFingerprintFields.Count == 4)\n            {\n                // copy in the fingerprint, and \"mark\" the constants as done\n                byte[] fingerprint = priorReadCommand.Skip(priorReadCommand.Length - 4).ToArray();\n                Console.WriteLine($\"Found original fingerprint as {BitUtility.BytesToHex(fingerprint)}\");\n\n                // default behavior is to clone last fingerprint, else use stored fingerprint\n                if (Preferences.GetValue(Preferences.PreferenceKey.EnableFingerprintClone) == \"false\") \n                {\n                    uint altFingerprintValue = uint.Parse(Preferences.GetValue(Preferences.PreferenceKey.FingerprintValue));\n                    fingerprint[3] = (byte)(altFingerprintValue & 0xFF);\n                    altFingerprintValue >>= 8;\n                    fingerprint[2] = (byte)(altFingerprintValue & 0xFF);\n                    altFingerprintValue >>= 8;\n                    fingerprint[1] = (byte)(altFingerprintValue & 0xFF);\n                    altFingerprintValue >>= 8;\n                    fingerprint[0] = (byte)(altFingerprintValue & 0xFF);\n                }\n\n                Console.WriteLine($\"Using {BitUtility.BytesToHex(fingerprint)} as new fingerprint value.\");\n\n                Array.ConstrainedCopy(fingerprint, 0, writeCommand, writeCommand.Length - 4, 4);\n\n                foreach (DiagPreparation prep in possibleFingerprintFields)\n                {\n                    preparationsToProcess.Remove(prep);\n                }\n            }\n\n\n            // at this point, whatever that's left in preparationsToProcess are stuff that are variable, but should be copied verbatim from the original read request (e.g. fingerprints, scn)\n            // log the assumptions, show it the operator just in case\n            StringBuilder assumptionsMade = new StringBuilder();\n            if (preparationsToProcess.Count > 0)\n            {\n                if (writeCommand.Length != priorReadCommand.Length)\n                {\n                    MessageBox.Show(\"There are some preparations that do not have a default value. \\r\\n\" +\n                        \"The input and output values do not have matching lengths, which means that the automatic assumption may be wrong. \\r\\n\" +\n                        \"Please be very careful when proceeding.\", \"Warning\");\n                }\n\n                foreach (DiagPreparation prep in preparationsToProcess)\n                {\n                    int bytePosition = prep.BitPosition / 8;\n                    int byteLength = prep.SizeInBits / 8;\n                    Array.ConstrainedCopy(priorReadCommand, bytePosition, writeCommand, bytePosition, byteLength);\n                    assumptionsMade.Append($\"{prep.Qualifier} : {BitUtility.BytesToHex(priorReadCommand.Skip(bytePosition).Take(byteLength).ToArray(), true)}\\r\\n\");\n                }\n            }\n\n            /*\n            // lazy me dumping the values\n            for (int i = 0; i < vcForm.WriteService.InputPreparations.Count; i++)\n            {\n                DiagPreparation prep = vcForm.WriteService.InputPreparations[i];\n                Console.WriteLine($\"debug: q: {prep.Qualifier} pos byte: {(prep.BitPosition / 8)} size bytes: {(prep.SizeInBits / 8)} modecfg:{prep.ModeConfig:X} fieldtype: {prep.FieldType} dump: {BitUtility.BytesToHex(prep.Dump, true)}\");\n            }\n            */\n\n            // we are done preparing the command, if we are confident we can send the command straight to the ECU, else, let the user review\n            if (assumptionsMade.Length > 0)\n            {\n                if (MessageBox.Show(\"Some assumptions were made when preparing the write parameters. \\r\\n\\r\\n\" +\n                    \"You may wish to review them by selecting Cancel, or select OK to execute the write command immediately.\\r\\n\\r\\n\" + assumptionsMade.ToString(),\n                    \"Review assumptions\", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.OK)\n                {\n                    ExecVCWrite(writeCommand, vcForm.WriteService, connection, writesEnabled);\n                }\n                else\n                {\n                    runDiagForm.Result = writeCommand;\n                    if (runDiagForm.ShowDialog() == DialogResult.OK)\n                    {\n                        ExecVCWrite(runDiagForm.Result, vcForm.WriteService, connection, writesEnabled);\n                    }\n                }\n            }\n            else\n            {\n                // everything accounted for, immediately write\n                ExecVCWrite(writeCommand, vcForm.WriteService, connection, writesEnabled);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Diogenes/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Be.Windows.Forms.HexBox\" version=\"1.6.1\" targetFramework=\"net46\" />\n  <package id=\"J2534-Sharp\" version=\"1.0.0-CI00026\" targetFramework=\"net46\" />\n</packages>"
  },
  {
    "path": "Caesar/Trafo/App.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<configuration>\n    <startup> \n        <supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.6\" />\n    </startup>\n</configuration>"
  },
  {
    "path": "Caesar/Trafo/Program.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Caesar;\nusing System.IO;\nusing Newtonsoft.Json;\n\nnamespace Trafo\n{\n    class Program\n    {\n        static List<object> VariantList;\n\n        static void ReadScales (CaesarContainer container, DiagPresentation presentation, List<object> scaleslist)\n        {\n            foreach (Scale Scale in presentation.Scales)\n            {\n                var ScaleRow = new\n                {\n                    LowBound = Scale.EnumLowBound,\n                    UpBound = Scale.EnumUpBound,\n                    //PrepLowBound = Scale.PrepLowBound, //commented out fields purpose unknown\n                    //PrepUpBound = Scale.PrepUpBound,\n                    MultiplyFactor = Scale.MultiplyFactor,\n                    AddConstOffs = Scale.AddConstOffset,\n                    //SICount =Scale.SICount,\n                    //OffsetSI = Scale.OffsetSI,\n                    //USCount = Scale.USCount,\n                    //OffsetUS = Scale.OffsetUS,\n                    EnumDesc = container.CaesarCTFHeader.CtfLanguages[0].GetString(Scale.EnumDescription)\n                };\n\n                scaleslist.Add(ScaleRow);\n            }\n        }\n\n        static void ReadPreparation (CaesarContainer container, DiagPreparation prep, List<object> preplist)\n        {\n            DiagPresentation Presentation = container.CaesarECUs[0].GlobalPresentations[prep.PresPoolIndex];\n            List<object> ScalesList = new List<object>();\n\n            ReadScales(container, Presentation, ScalesList);\n\n            var PresentationRow = new\n            {\n                Qualifier = Presentation.Qualifier,\n                Desc = container.CaesarCTFHeader.CtfLanguages[0].GetString(Presentation.Description_CTF),\n                Units = container.CaesarCTFHeader.CtfLanguages[0].GetString(Presentation.DisplayedUnit_CTF),\n                EnumMaxVal = container.CaesarCTFHeader.CtfLanguages[0].GetString(Presentation.EnumMaxValue),\n                Desc2 = container.CaesarCTFHeader.CtfLanguages[0].GetString(Presentation.Description2_CTF),\n                Scales = ScalesList\n            };\n\n            var PreparationRow = new\n            {\n                Name = prep.Qualifier,\n                LongName = container.CaesarCTFHeader.CtfLanguages[0].GetString(prep.Name_CTF),\n                BitPos = prep.BitPosition,\n                BitLen = prep.SizeInBits,\n                Presentation = PresentationRow\n            };\n\n            preplist.Add(PreparationRow);\n        }\n\n        static void ReadDiagService (CaesarContainer container, DiagService diagservice, List<object> diagserviceslist)\n        {\n            List<object> InputPrepList = new List<object>();\n\n            foreach (DiagPreparation InputPrep in diagservice.InputPreparations)\n                ReadPreparation(container, InputPrep, InputPrepList);\n\n            List<object> OutputPrepList = new List<object>();\n\n            foreach (List<DiagPreparation> OutputPreps in diagservice.OutputPreparations)\n            {\n                foreach (DiagPreparation OutputPrep in OutputPreps)\n                    ReadPreparation(container, OutputPrep, OutputPrepList);\n            }\n\n            string RequestArr = string.Join(\"\", diagservice.RequestBytes.Select(b => string.Format(\"{0:X2} \", b)));\n            var RequestBytesRow = new { RequestBytes = RequestArr };\n            var servicetype = (DiagService.ServiceType) diagservice.DataClass_ServiceType;\n\n            var DiagServiceRow = new\n            {\n                DiagServiceName = diagservice.Qualifier,\n                Desc = container.CaesarCTFHeader.CtfLanguages[0].GetString(diagservice.Description_CTF),\n                Type = servicetype.ToString(),\n                ClientAccessLevel = diagservice.ClientAccessLevel,\n                SecurityAccessLevel = diagservice.SecurityAccessLevel,\n                RequestBytes = RequestArr,\n                InputPreps = InputPrepList,\n                OutputPreps = OutputPrepList\n            };\n\n            diagserviceslist.Add(DiagServiceRow);\n        }\n\n        static void ReadECUVariant (CaesarContainer container, ECUVariant variant )\n        {\n            List<object> domainList = new List<object>();\n\n            foreach (VCDomain domain in variant.VCDomains)\n            {\n                DiagService ReadService = variant.GetDiagServiceByName(domain.ReadServiceName);\n                DiagService WriteService = variant.GetDiagServiceByName(domain.WriteServiceName);\n                string ReadArr = string.Join(\"\", ReadService.RequestBytes.Select(b => string.Format(\"{0:X2} \", b)));\n                string WriteArr = string.Join(\"\", WriteService.RequestBytes.Select(b => string.Format(\"{0:X2} \", b)));\n                \n                List<object> fragmentList = new List<object>();\n\n                foreach (VCFragment fragment in domain.VCFragments)\n                {\n                    List<object> PresList = new List<object>();\n                    DiagPresentation Presentation = container.CaesarECUs[0].GlobalPresentations[fragment.MeaningB];\n                    List<object> ScalesList = new List<object>();\n                    ReadScales(container, Presentation, ScalesList);\n\n                    var FragmentInfo = new\n                    {\n                        Qualifier = Presentation.Qualifier,\n                        Desc = container.CaesarCTFHeader.CtfLanguages[0].GetString(Presentation.Description_CTF),\n                        Units = container.CaesarCTFHeader.CtfLanguages[0].GetString(Presentation.DisplayedUnit_CTF),\n                        EnumMaxVal = container.CaesarCTFHeader.CtfLanguages[0].GetString(Presentation.EnumMaxValue),\n                        Desc2 = container.CaesarCTFHeader.CtfLanguages[0].GetString(Presentation.Description2_CTF),\n                        Scales = ScalesList\n                    };\n\n                    var fragmentRow = new\n                    {\n                        FragName = container.CaesarCTFHeader.CtfLanguages[0].GetString(fragment.Name_CTF),\n                        FragDesc = container.CaesarCTFHeader.CtfLanguages[0].GetString(fragment.Description_CTF),\n                        BitPos = fragment.ByteBitPos,\n                        BitLen = fragment.BitLength,\n                        ReadAccessLevel = fragment.ReadAccessLevel,\n                        WriteAccessLevel = fragment.WriteAccessLevel,\n                        ByteOrder = fragment.ByteOrder,\n                        Info = FragmentInfo\n                    };\n\n                    fragmentList.Add(fragmentRow);\n                }\n                var domainRow = new\n                {\n                    VCDName = domain.Qualifier,\n                    DumpSize = domain.DumpSize,\n                    ReadService = domain.ReadServiceName,\n                    WriteService = domain.WriteServiceName,\n                    ReadBytes = ReadArr,\n                    WriteBytes = WriteArr,\n                    VCDFragments = fragmentList\n                };\n\n                var RequestBytesRow = new { ReadRequestBytes = ReadArr, WriteRequestBytes = WriteArr };\n                domainList.Add(domainRow);\n            }\n\n            List<object> DTCList = new List<object>();\n\n            foreach (DTC dtc in variant.DTCs)\n            {\n                List<string> XrefsList = new List<string>();\n                List<DiagService> EnvCtxForDTC = variant.GetEnvironmentContextsForDTC(dtc);\n\n                for (int i = 0; i < dtc.XrefCount; i++)\n                    XrefsList.Add(EnvCtxForDTC[i].Qualifier);\n\n                var DTCRow = new\n                {\n                    Code = dtc.Qualifier,\n                    Desc = container.CaesarCTFHeader.CtfLanguages[0].GetString(dtc.Description_CTF),\n                    Ref = container.CaesarCTFHeader.CtfLanguages[0].GetString(dtc.Reference_CTF),\n                    Xrefs = XrefsList\n                };\n\n                DTCList.Add(DTCRow);\n            }\n\n            List<object> EnvCtxList = new List<object>();\n\n            foreach (DiagService EnvCtx in variant.EnvironmentContexts)\n                ReadDiagService(container, EnvCtx, EnvCtxList);\n\n            List<object> DiagServicesList = new List<object>();\n\n            foreach (DiagService DiagService in variant.DiagServices)\n                ReadDiagService(container, DiagService, DiagServicesList);\n\n            var variantRow = new\n            {\n                VariantName = variant.Qualifier,\n                VarcodingDomains = domainList,\n                DTCs = DTCList,\n                EnvironmentContexts = EnvCtxList,\n                DiagServices = DiagServicesList\n            };\n            VariantList.Add(variantRow);\n        }\n\n        static void Main(string[] args)\n        {\n\n#if DEBUG\n            string path = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + @\"\\temp.CBF\";\n#else\n            if ((args.Length == 0) || (args.Length > 2))\n            {\n                Console.WriteLine(\"Usage:\");\n                Console.WriteLine(\"trafo.exe [target CBF file] <optional>[parameter]\");\n                Console.WriteLine(\"[parameter] can be:\");\n                Console.WriteLine(\"listvar: list all variant names present in CBF file\");\n                Console.WriteLine(\"[variant name]: export varcoding, DTC, environment context, diagnostic services sections of one specified variant\");\n                Console.WriteLine(\"if no [parameter] is specified - export varcoding, DTC, environment context, diagnostic services sections of all variants\");\n                return;\n            }\n\n            if (!File.Exists(args[0])) \n            {\n                Console.WriteLine(\"Specified CBF file does not exist, exiting\");\n                return;\n            }\n\n            string path = args[0];\n#endif\n            byte[] cbfBytes = File.ReadAllBytes(path);\n            \n            CaesarContainer container = new CaesarContainer(cbfBytes);\n            string mode = \"\";\n\n            if (args.Length == 2)\n                mode = args[1];\n\n            bool VariantFound = false;\n\n            if (mode == \"listvar\")\n            {\n                string combinedString = \"\";\n\n                foreach (ECU ecu in container.CaesarECUs)\n                {\n                    foreach (ECUVariant variant in ecu.ECUVariants)\n                        combinedString = combinedString + \" \" + variant.Qualifier;\n                }\n\n                Console.WriteLine(combinedString);\n            }\n            else\n            {\n                VariantList = new List<object>();\n\n                foreach (ECU ecu in container.CaesarECUs)\n                {\n                    foreach (ECUVariant variant in ecu.ECUVariants)\n                    {\n                        if (mode == \"\")\n                        {\n                            ReadECUVariant(container, variant);\n                        }\n                        else if (mode == variant.Qualifier)\n                        {\n                            VariantFound = true;\n                            ReadECUVariant(container, variant);\n                            break;\n                        }\n                    }\n                }\n\n                if (mode != \"\" && !VariantFound)\n                {\n                    Console.WriteLine(\"Specified variant does not exist in provided CBF file, exiting\");\n                    return;\n                }\n\n                string newFilename = $\"{Path.GetDirectoryName(path)}{Path.DirectorySeparatorChar}{Path.GetFileNameWithoutExtension(path)}_{mode}.json\";\n\n                var caesarContainerJson = new\n                {\n                    TrafoVersion = GetVersion(),\n                    OriginalFile = Path.GetFileName(path),\n                    container.CaesarCFFHeader,\n                    Variants = VariantList\n                };\n\n                File.WriteAllText(newFilename, JsonConvert.SerializeObject(caesarContainerJson));\n                Console.WriteLine($\"Converted CBF file {mode} variant to JSON at {newFilename}\");\n            }\n            \n#if DEBUG\n            Console.ReadKey();\n#endif\n        }\n\n        public static string GetVersion() \n        {\n            System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();\n            System.Diagnostics.FileVersionInfo fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(assembly.Location);\n            return fvi.FileVersion;\n        }\n    }\n}\n"
  },
  {
    "path": "Caesar/Trafo/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following\n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"Trafo\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"Trafo\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2020\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible\n// to COM components.  If you need to access a type in this assembly from\n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"42a6f1fd-82cc-4721-bf0c-1658ae902875\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version\n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers\n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "Caesar/Trafo/Trafo.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{42A6F1FD-82CC-4721-BF0C-1658AE902875}</ProjectGuid>\n    <OutputType>Exe</OutputType>\n    <RootNamespace>Trafo</RootNamespace>\n    <AssemblyName>Trafo</AssemblyName>\n    <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>\n    <Deterministic>true</Deterministic>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup>\n    <ApplicationIcon>trafo-256.ico</ApplicationIcon>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>..\\packages\\Newtonsoft.Json.12.0.3\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Program.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"App.config\" />\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\Caesar\\Caesar.csproj\">\n      <Project>{71c43c61-7dc7-4d47-9947-1dd73e559911}</Project>\n      <Name>Caesar</Name>\n    </ProjectReference>\n  </ItemGroup>\n  <ItemGroup>\n    <Content Include=\"trafo-256.ico\" />\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n</Project>"
  },
  {
    "path": "Caesar/Trafo/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Newtonsoft.Json\" version=\"12.0.3\" targetFramework=\"net46\" />\n</packages>"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2020 JinGen Lim\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "![CaesarSuite Banner](https://raw.githubusercontent.com/jglim/CaesarSuite/main/docs/resources/caesarsuite-banner.png)\n\n# Caesar Suite\n\n![Counter](https://raw.githubusercontent.com/jglim/CaesarSuite/main/docs/resources/gh_shield_0.svg)\n\nLibrary and applications to work with Dаіmlеr diagnostics CBF files.\n\n- Caesar : Library to operate on CBF files\n- Diogenes: ECU-Coding utility\n- Trafo: Transforms CBF files into JSON\n- UnlockECU: [(External)](https://github.com/jglim/UnlockECU) ECU-Unlocking utility\n\n![Header Image](https://raw.githubusercontent.com/jglim/CaesarSuite/main/docs/resources/diogenes-2.png)\n\n## Warning\n\nThis project is far from production ready. Please be careful if you are planning to use this with your vehicle.\n\n## Getting Started\n\nBuilds are available on the [Releases page](https://github.com/jglim/CaesarSuite/releases/) for the adventurous. Ensure that [.NET Framework 4.6 or newer](https://dotnet.microsoft.com/download) is installed. Optionally install .NET 5 too, if you intend to use [UnlockECU](https://github.com/jglim/UnlockECU).\n\n## License\n\nMIT\n\nIcons from [http://www.famfamfam.com/lab/icons/silk/](http://www.famfamfam.com/lab/icons/silk/)\n\n---\n\n# Caesar\n\nCaesar is an experimental parser for CBF files that is reverse engineered from the official, proprietary `c32s.dll` library. \n\nNames of classes, functions, properties will change often as they are matched with their disassembly's names. Please be mindful of this when referencing the Caesar library.\n\n# Trafo\n\nTrafo converts a CBF file into a simplified JSON representation and is backed by Caesar. At this point, the JSON should contain enough information to work with variant-coding strings. Usage is straightforward: drop a CBF file onto `Trafo.exe` and a JSON file will be created in the same folder as the input file.\n\n# Diogenes\n\nDiogenes is intended to be a FOSS replacement for Vediamo's variant-coding capabilities over J2534 interfaces. \n\nAt this point, Diogenes can: \n\n- Load CBF files and display ECUs and their variants\n- Parse a variant's VC domain\n- Parse, visually modify and reinterpret a variant-coding string\n- Generate authentication seed-keys from standalone DLLS (borrowed from my [SecurityAccessQuery](https://github.com/jglim/SecurityAccessQuery))\n\n(New:)\n- Open a UDS connection over J2534 (✅)\n- Enumerate connected ECUs and identify online devices with compatible CBF files (✅ : UDS)\n- Complete a seed-key challenge with a target ECU (✅ : Paired with [UnlockECU](https://github.com/jglim/UnlockECU))\n- Write a new variant-coding string on a target ECU (✅* : Experimental, reuses fingerprints, still needs more testing)\n\nDiogenes will be \"complete\" when it can:\n\n- ❌: Test on an ECU that is installed in a vehicle. So far, tests have been made on a real ECU, but only on the bench.\n\n*If you are looking for an alternative with a broader feature set, check out [OpenVehicleDiag](https://github.com/rnd-ash/OpenVehicleDiag) instead*\n\n# Demo\n\n## Establishing a connection\n\n![Connection](https://raw.githubusercontent.com/jglim/CaesarSuite/main/docs/resources/demo-connect.gif)\n\n## Reading ECU data\n\n![Read Data](https://raw.githubusercontent.com/jglim/CaesarSuite/main/docs/resources/demo-data.gif)\n\n## Variant coding\n\n![VC](https://raw.githubusercontent.com/jglim/CaesarSuite/main/docs/resources/demo-vc.gif)\n\n_More information on variant coding in [this discussion](https://github.com/jglim/CaesarSuite/discussions/7)_\n\n## CFF flash export\n\n_Dump a CFF flash file's raw memory contents (assumes unencrypted, uncompressed data). Files are labeled with its intended memory address (IDA: File -> Load file -> Additional binary file)_\n\n![CFF](https://raw.githubusercontent.com/jglim/CaesarSuite/main/docs/resources/demo-cff.gif)\n\n## (New!) CFF Splicer\n\n_Modify a CFF flash file's memory segment data (assumes unencrypted, uncompressed data). New segment data can be of different file sizes, and the destination ECU memory address can be changed._\n\n![CFF2](https://raw.githubusercontent.com/jglim/CaesarSuite/main/docs/resources/demo-cff-splice.gif)\n\n---\n\n# Contributing\n\n## Issues\n\nThe primary roadblock for Caesar/Diogenes is the inability to parse Diagnostic Service code blobs, which are compiled binary scripts that automate tasks such as session switching, variant identification, ECU unlocking, and (apparently) variant coding. While Diogenes is usable on UDS, it still falls short for protocols like KW2C3PE because of this issue.\n\n### Workaround\n\n - Session switching and variant identification on UDS devices is generally consistent and standardized.\n - ECU unlocking can be deferred to [UnlockECU](https://github.com/jglim/UnlockECU). \n - Variant coding typically contains 4 bytes for the signature of the last system that modified it. Diogenes will automatically clone this value. \n \t- By default, the 4 bytes contain seemingly random data (`00 40 33 10`) on a \"fresh\" ECU, and become `00 00 00 01` when written with Vediamo.\n \t- Some devices also include the SCN as part of the variant coding, which appears as an additional 128-bit/16-byte field. \n \t- Diogenes will detect \"unfilled\" values, and prompt for the next course of action.\n\n### My lack of understanding\n\nThere are concepts which I do not understand that may impede the development of this project:\n\n - The SCN seems to be a specific 16-byte string, where the first 10 characters are the part number (as printed on the device), and an unknown 6 characters. Are these 6 characters unique to the device?\n - The 16-character string is typically queried via `DT_STO_ID_Calibration_Identification`. There is also a function for `DT_STO_ID_Calibration_Verification_Number` which returns an unknown 4 bytes. Are these values matched?\n - Is there a way to query the ECU if the current SCN is valid and accepted? This is crucial to check if the variant-coding was successful.\n\n\n# Contributors\n\nThese individuals have helped to improve Diogenes in some form (e.g. code, testing, traces/logs, knowledge sharing, assets).\n\n- @N0cynym\n- @Feezex\n- @rnd-ash\n\nThank you for your contributions."
  }
]