From 226901607cd688951dec958ffeaec502a3e1b65e Mon Sep 17 00:00:00 2001 From: feyris-tan <4116042+feyris-tan@users.noreply.github.com> Date: Sat, 5 Jul 2025 22:26:42 +0200 Subject: [PATCH] First attempts at scraping Freesat. --- .gitignore | 3 + Documentation/TODO.md | 17 +- .../DVBServices/Decompressors/HuffmanEntry.cs | 76 + .../Decompressors/MultiTreeDictionaryEntry.cs | 515 +++ .../EPGCollectorSide/DVBServices/Utils.cs | 67 + .../DomainObjects/DebugEntry.cs | 16 + .../DomainObjects/Enumerations.cs | 1806 ++++++++++ .../EPGCollectorSide/DomainObjects/Logger.cs | 51 + .../Properties/Resources.Designer.cs | 83 + .../Properties/Resources.resx | 127 + .../Huffman Dictionary Freesat T1.cfg | 2027 +++++++++++ .../Huffman Dictionary Freesat T2.cfg | 3160 +++++++++++++++++ .../SkyscraperSide/FreesatBatSdtContestant.cs | 60 + .../SkyscraperSide/FreesatEpgContestant.cs | 58 + .../SkyscraperSide/FreesatNitContestant.cs | 58 + .../SkyscraperSide/FreesatTdtContestant.cs | 61 + .../SkyscraperSide/FreesatTextDecoder.cs | 36 + .../FreesatTunnelDataStorage.cs | 111 + .../SkyscraperSide/FreesatTunnelScraper.cs | 115 + .../skyscraper8.EPGCollectorPort.csproj | 28 + skyscraper8.sln | 7 + skyscraper8/Dvb/Psi/BatEventHandler.cs | 2 +- skyscraper8/Dvb/Psi/EitEventHandler.cs | 2 +- skyscraper8/Dvb/Psi/EitParser.cs | 2 +- skyscraper8/Dvb/Psi/NitEventHandler.cs | 2 +- skyscraper8/Dvb/Psi/NitParser.cs | 2 +- skyscraper8/Dvb/Psi/SdtEventHandler.cs | 2 +- skyscraper8/Dvb/Psi/TdtParserHandler.cs | 2 +- skyscraper8/Dvb/Psi/TimetableParser.cs | 2 +- skyscraper8/Dvb/Psi/TotEventHandler.cs | 2 +- skyscraper8/Properties/launchSettings.json | 1 + skyscraper8/Ses/SgtCandidate.cs | 5 + .../Skyscraper/Plugins/PluginLogger.cs | 2 +- .../Skyscraper/Plugins/PluginManager.cs | 38 +- .../Scraper/FreesatTunnelScraper.cs | 49 - .../Skyscraper/Scraper/SkyscraperContext.cs | 35 +- .../Scraper/StreamAutodetection/Contestant.cs | 2 + .../Contestants/AitContestant.cs | 5 + .../Contestants/BatContestant.cs | 24 +- .../Contestants/CatContestant.cs | 4 + .../Contestants/DataCarouselContestant.cs | 7 +- .../Contestants/DisqualifiedContestant.cs | 5 + .../Contestants/EitContestant.cs | 5 + .../Contestants/Id3Contestant.cs | 5 + .../Contestants/IntContestant.cs | 5 + .../InteractionChannelContestant.cs | 5 + .../Contestants/MpeContestant.cs | 5 + .../Contestants/NitContestant.cs | 5 + .../Contestants/PatContestant.cs | 5 + .../Contestants/Pid0x11Contestant.cs | 28 +- .../Contestants/PmtContestant.cs | 5 + .../Contestants/RdsContestant.cs | 5 + .../Contestants/Scte35Contestant.cs | 5 + .../Contestants/SdtContestant.cs | 5 + .../Contestants/SubtitleContestant.cs | 5 + .../Contestants/T2MiContestant.cs | 5 + .../Contestants/TeletextContestant.cs | 7 +- .../Contestants/TimeContestant.cs | 14 +- .../Contestants/TsdtContestant.cs | 5 + .../Contestants/UntContestant.cs | 5 + .../StreamAutodetection/ProgramContext.cs | 12 + .../StreamTypeAutodetection.cs | 81 +- .../Skyscraper/Text/En300468TextDecoder.cs | 15 +- skyscraper8/Skyscraper/Text/EncodingTypeId.cs | 19 + skyscraper8/Skyscraper/Text/TextDecoder.cs | 14 + skyscraper8/Skyscraper/Text/TextException.cs | 23 + 66 files changed, 8850 insertions(+), 115 deletions(-) create mode 100644 PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/EPGCollectorSide/DVBServices/Decompressors/HuffmanEntry.cs create mode 100644 PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/EPGCollectorSide/DVBServices/Decompressors/MultiTreeDictionaryEntry.cs create mode 100644 PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/EPGCollectorSide/DVBServices/Utils.cs create mode 100644 PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/EPGCollectorSide/DomainObjects/DebugEntry.cs create mode 100644 PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/EPGCollectorSide/DomainObjects/Enumerations.cs create mode 100644 PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/EPGCollectorSide/DomainObjects/Logger.cs create mode 100644 PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/Properties/Resources.Designer.cs create mode 100644 PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/Properties/Resources.resx create mode 100644 PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/Resources/Huffman Dictionary Freesat T1.cfg create mode 100644 PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/Resources/Huffman Dictionary Freesat T2.cfg create mode 100644 PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatBatSdtContestant.cs create mode 100644 PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatEpgContestant.cs create mode 100644 PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatNitContestant.cs create mode 100644 PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatTdtContestant.cs create mode 100644 PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatTextDecoder.cs create mode 100644 PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatTunnelDataStorage.cs create mode 100644 PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatTunnelScraper.cs create mode 100644 PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/skyscraper8.EPGCollectorPort.csproj delete mode 100644 skyscraper8/Skyscraper/Scraper/FreesatTunnelScraper.cs create mode 100644 skyscraper8/Skyscraper/Text/EncodingTypeId.cs create mode 100644 skyscraper8/Skyscraper/Text/TextDecoder.cs create mode 100644 skyscraper8/Skyscraper/Text/TextException.cs diff --git a/.gitignore b/.gitignore index 3120936..aa15769 100644 --- a/.gitignore +++ b/.gitignore @@ -110,3 +110,6 @@ imgui.ini /.vs/skyscraper8/CopilotIndices/17.14.698.11175 /GUIs/skyscraper8.UI.ImGui/bin/Debug/net8.0 /.vs/skyscraper8/CopilotIndices/17.14.734.62261 +/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/bin/Debug/net8.0 +/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/obj/Debug/net8.0 +/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/obj diff --git a/Documentation/TODO.md b/Documentation/TODO.md index 46daf21..53955e0 100644 --- a/Documentation/TODO.md +++ b/Documentation/TODO.md @@ -77,7 +77,7 @@ * Unbekanntes Text Encoding auf Eutelsat 7, 12648 H, MIS3 * [DONE] "Unknown Protocol" 50 * [DONE] "Unknown Protocal" 47 -* In MinioObjectStorage.cs bei Zeile 132 - behandeln dass nicht immer unbedingt eine MinioException rauskommt! +* [DONE] In MinioObjectStorage.cs bei Zeile 132 - behandeln dass nicht immer unbedingt eine MinioException rauskommt! * skyscraper5.Ietf.Rfc971.InternetHeader sollte Validatable implementieren. * In Testdrid: Einen Notizblock * Wenn ein Blindscan false zurückgibt, aber dennoch Ergebnisse geliefert hat, diese trotzdem abklopfen. @@ -133,8 +133,17 @@ * [DONE] IP-Protokoll 139 (skyscraper_20230408_1727_0390E_12739_H_3926_gse.ts) * [DONE] DNS Record Type 20366 (skyscraper_20230410_1450_0660E_12626_V_38329.ts) * [DONE] DNS IN ( {Z:\Freebies\Datasets\SkyscraperLibrarian\DVB-S August 2024\Telstar15\skyscraper_20240826_1530_0150W_12596_V_44999.ts} ) -* ScraperStorage: Big File -* ScraperStorage: Big File mit Index * [DONE] Für BigFiles: Gesplitteter Stream, für FAT32 und Freunde * [DONE] Einen "Forget Blindscan Job" Button in der UI -* TransportProtocolDescriptor - unbekannte ProtocolIDs ohne Exception behandeln. (Vielleicht eine Warning?) \ No newline at end of file +* TransportProtocolDescriptor - unbekannte ProtocolIDs ohne Exception behandeln. (Vielleicht eine Warning?) +* Weitere Datenbanktreiber + * Microsoft SQL Server + * Oracle + * Cassandra + * SQLite + * MongoDB + * Redis + * IBM DB2 + * Firebird + * ScraperStorage: Big File + * ScraperStorage: Big File mit Index diff --git a/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/EPGCollectorSide/DVBServices/Decompressors/HuffmanEntry.cs b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/EPGCollectorSide/DVBServices/Decompressors/HuffmanEntry.cs new file mode 100644 index 0000000..edfbc8f --- /dev/null +++ b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/EPGCollectorSide/DVBServices/Decompressors/HuffmanEntry.cs @@ -0,0 +1,76 @@ +////////////////////////////////////////////////////////////////////////////////// +// // +// Copyright © 2005-2020 nzsjb // +// // +// This Program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation; either version 2, or (at your option) // +// any later version. // +// // +// This Program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with GNU Make; see the file COPYING. If not, write to // +// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. // +// http://www.gnu.org/copyleft/gpl.html // +// // +////////////////////////////////////////////////////////////////////////////////// + +namespace DVBServices +{ + /// + /// The class that describes a Huffman dictionary entry. + /// + public class HuffmanEntry + { + /// + /// Get or set the zero bit link. + /// + public HuffmanEntry P0 + { + get { return (p0); } + set { p0 = value; } + } + + /// + /// Get or set the one bit link. + /// + public HuffmanEntry P1 + { + get { return (p1); } + set { p1 = value; } + } + + /// + /// Get or set the entry value. + /// + public string Value + { + get { return (value); } + set + { + this.value = value; + holdsValue = true; + } + } + + /// + /// Returns true if the value has been set; false otherwise. + /// + public bool HoldsValue { get { return (holdsValue); } } + + private HuffmanEntry p0; + private HuffmanEntry p1; + private string value; + private bool holdsValue; + + /// + /// Intialize a new instance of the HuffmanEntry. + /// + public HuffmanEntry() { } + } +} + diff --git a/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/EPGCollectorSide/DVBServices/Decompressors/MultiTreeDictionaryEntry.cs b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/EPGCollectorSide/DVBServices/Decompressors/MultiTreeDictionaryEntry.cs new file mode 100644 index 0000000..ea46b5d --- /dev/null +++ b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/EPGCollectorSide/DVBServices/Decompressors/MultiTreeDictionaryEntry.cs @@ -0,0 +1,515 @@ +////////////////////////////////////////////////////////////////////////////////// +// // +// Copyright © 2005-2020 nzsjb // +// // +// This Program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation; either version 2, or (at your option) // +// any later version. // +// // +// This Program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with GNU Make; see the file COPYING. If not, write to // +// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. // +// http://www.gnu.org/copyleft/gpl.html // +// // +////////////////////////////////////////////////////////////////////////////////// +using System; +using System.IO; +using System.Text; +using System.Globalization; +using System.Collections.ObjectModel; + +using DomainObjects; + +namespace DVBServices +{ + /// + /// The class that describes a dictionary entry for a multi-tree Hufmman scenario. + /// + public class MultiTreeDictionaryEntry + { + /// + /// Return true if the translation tables have been loaded; false otherwise. + /// + public static bool Loaded { get { return (loaded); } } + + /// + /// Get the count of escape sequences for a text string. + /// + public static int EscapeCount { get; private set; } + + private const int stop = 0x02; + private const int start = 0x00; + private const int escape = 0x01; + + private static HuffmanEntry[] table1Roots = new HuffmanEntry[256]; + private static HuffmanEntry[] table2Roots = new HuffmanEntry[256]; + + /// + /// Get the decode string. + /// + public string Decode { get { return (decode); } } + + private string decode; + private string pattern; + private static bool loaded; + + private static Collection encodings; + private static int singleByteEscapes; + private static int multiByteEscapes; + + /// + /// Initialize a new instance of the MultiTreeDictionaryEntry class. + /// + /// The Huffman bit pattern. + /// The decode for the bit pattern. + public MultiTreeDictionaryEntry(string pattern, string decode) + { + this.pattern = pattern; + this.decode = decode; + } + + /// + /// Load the reference tables. + /// + /// The full name of the T1 file. + /// The full name of the T2 file. + /// True if the file is loaded successfully;false otherwise. + public static bool Load(Stream fileName1, Stream fileName2) + { + if (loaded) + return (true); + + Logger.Instance.Write("Loading Huffman Dictionary 1"); + try + { + loadFile(table1Roots, fileName1); + } + catch (IOException e) + { + Logger.Instance.Write("Huffman Dictionary file not available"); + Logger.Instance.Write(e.Message); + return (false); + } + + Logger.Instance.Write("Loading Huffman Dictionary 2 from " + fileName2); + try + { + loadFile(table2Roots, fileName2); + } + catch (IOException e) + { + Logger.Instance.Write("Huffman Dictionary file not available"); + Logger.Instance.Write(e.Message); + return (false); + } + + Logger.Instance.Write("Dictionaries loaded"); + + loaded = true; + return (true); + } + + private static void loadFile(HuffmanEntry[] roots, Stream fileStream) + { + StreamReader streamReader = new StreamReader(fileStream); + + while (!streamReader.EndOfStream) + { + string line = streamReader.ReadLine(); + + if (line != string.Empty && !line.StartsWith("####")) + { + string[] parts = line.Split(new char[] { ':' }); + if (parts.Length == 4) + { + int rootOffSet = (int)(resolveChar(parts[0])); + + if (roots[rootOffSet] == null) + roots[rootOffSet] = new HuffmanEntry(); + + HuffmanEntry currentEntry = roots[rootOffSet]; + string pattern = parts[1]; + + for (int index = 0; index < parts[1].Length; index++) + { + char patternChar = pattern[index]; + + switch (patternChar) + { + case '0': + if (currentEntry.P0 == null) + { + currentEntry.P0 = new HuffmanEntry(); + currentEntry = currentEntry.P0; + if (index == pattern.Length - 1) + currentEntry.Value = resolveChar(parts[2]).ToString(); + } + else + { + currentEntry = currentEntry.P0; + if (currentEntry.HoldsValue && index == pattern.Length - 1) + Logger.Instance.Write("Dictionary entry already set"); + } + break; + case '1': + if (currentEntry.P1 == null) + { + currentEntry.P1 = new HuffmanEntry(); + currentEntry = currentEntry.P1; + if (index == pattern.Length - 1) + currentEntry.Value = resolveChar(parts[2]).ToString(); + } + else + { + currentEntry = currentEntry.P1; + if (currentEntry.HoldsValue && index == pattern.Length - 1) + Logger.Instance.Write("Dictionary entry already set: " + line); + } + break; + default: + break; + } + } + } + } + } + + streamReader.Close(); + fileStream.Close(); + } + + /// + /// Decode a Multi-tree text string which includes the text prefix (ie 0x1f?? where ?? indicates the table number 1 or 2). + /// + /// The encoded string. + /// The encoding used for the decompressed bytes. + /// The decoded string. + public static string DecodeData(byte[] byteData, string encoding) + { + if (byteData[1] == 1) + return(decodeData(byteData, table1Roots, 2, encoding)); + else + return(decodeData(byteData, table2Roots, 2, encoding)); + } + + /// + /// Decode a Multi-tree text string with no prefix. + /// + /// The decode table to use (1 or 2). + /// The encoded string. + /// The encoding used for the decompressed bytes. + /// The decoded string. + public static string DecodeData(int table, byte[] byteData, string encoding) + { + if (table == 1) + return (decodeData(byteData, table1Roots, 0, encoding)); + else + return (decodeData(byteData, table2Roots, 0, encoding)); + } + + private static string decodeData(byte[] byteData, HuffmanEntry[] roots, int startIndex, string encoding) + { + byte[] decompressedBytes = getByteBuffer(null); + int decompressedIndex = 0; + + Encoding sourceEncoding = sourceEncoding = Encoding.GetEncoding(encoding); + + if (encodings == null) + encodings = new Collection(); + if (!encodings.Contains(encoding)) + encodings.Add(encoding); + + HuffmanEntry currentEntry = roots[0]; + byte mask = 0x80; + bool finished = false; + EscapeCount = 0; + + for (int index = startIndex; index < byteData.Length && !finished; index++) + { + byte dataByte = byteData[index]; + + while (mask > 0 && !finished) + { + if (currentEntry.HoldsValue) + { + switch ((int)currentEntry.Value[0]) + { + case stop: + finished = true; + break; + case escape: + bool escapeDone = false; + + while (!escapeDone) + { + byte encodedValue = 0x00; + + for (int bitCount = 0; bitCount < 8; bitCount++) + { + encodedValue = (byte)(encodedValue << 1); + + if ((dataByte & mask) != 0) + encodedValue |= 0x01; + + mask = (byte)(mask >> 1); + if (mask == 0) + { + index++; + if (index >= byteData.Length) + { + //This if condition was added by feyris-tan + //to prevent random crash. + finished = true; + bitCount = 8; + escapeDone = true; + continue; + } + dataByte = byteData[index]; + mask = 0x80; + } + } + + if (encodedValue > 0x1f) + decompressedBytes = storeDecompressedByte(encodedValue, decompressedBytes, ref decompressedIndex); + + int length; + + if ((encodedValue & 0xe0) == 0xc0) // UTF-8 2 bytes + length = 2; + else + { + if ((encodedValue & 0xf0) == 0xe0) // UTF-8 3 bytes + length = 3; + else + { + if ((encodedValue & 0xf8) == 0xf0) // UTF-8 4 bytes + length = 4; + else + length = 1; // ASCII byte + } + } + + if (DebugEntry.IsDefined(DebugName.LogHuffman)) + Logger.Instance.Write("HD: Escaped length is " + length + " byte 0 encoded value was 0x" + encodedValue.ToString("x")); + + if (length == 1) + singleByteEscapes++; + else + { + multiByteEscapes++; + EscapeCount++; + } + + while (length > 1) + { + encodedValue = 0x00; + + for (int bitCount = 0; bitCount < 8; bitCount++) + { + encodedValue = (byte)(encodedValue << 1); + + if ((dataByte & mask) != 0) + encodedValue |= 0x01; + + mask = (byte)(mask >> 1); + if (mask == 0) + { + index++; + dataByte = byteData[index]; + mask = 0x80; + } + } + + decompressedBytes = storeDecompressedByte(encodedValue, decompressedBytes, ref decompressedIndex); + if (DebugEntry.IsDefined(DebugName.LogHuffman) && length > 1) + Logger.Instance.Write("HD: byte encoded value was 0x" + encodedValue.ToString("x")); + + length--; + } + + if (encodedValue < 0x20) + { + /*finished = true; + escapeDone = true;*/ + currentEntry = roots[encodedValue]; + escapeDone = true; + } + else + { + if (encodedValue < 0x80) + { + currentEntry = roots[encodedValue]; + escapeDone = true; + } + } + } + + break; + default: + decompressedBytes = storeDecompressedByte((byte)currentEntry.Value[0], decompressedBytes, ref decompressedIndex); + currentEntry = roots[(int)currentEntry.Value[0]]; + break; + } + } + + if (!finished) + { + if ((dataByte & mask) == 0) + { + if (currentEntry != null && currentEntry.P0 != null) + currentEntry = currentEntry.P0; + else + { + string outputString = sourceEncoding.GetString(decompressedBytes, 0, decompressedIndex); + + Logger.Instance.Write(" ** DECOMPRESSION FAILED **"); + Logger.Instance.Write("Original data: " + Utils.ConvertToHex(byteData)); + Logger.Instance.Write("Decoded data: " + outputString.ToString()); + return (outputString.ToString() + " ** DECOMPRESSION FAILED **"); + } + } + else + { + if (currentEntry != null && currentEntry.P1 != null) + currentEntry = currentEntry.P1; + else + { + string outputString = sourceEncoding.GetString(decompressedBytes, 0, decompressedIndex); + + Logger.Instance.Write(" ** DECOMPRESSION FAILED **"); + Logger.Instance.Write("Original data: " + Utils.ConvertToHex(byteData)); + Logger.Instance.Write("Decoded data: " + outputString.ToString()); + return (outputString.ToString() + " ** DECOMPRESSION FAILED **"); + } + } + + mask = (byte)(mask >> 1); + } + } + + mask = 0x80; + } + + if (decompressedIndex != 0) + { + string response = sourceEncoding.GetString(decompressedBytes, 0, decompressedIndex); + /*if (WasEscaped) + Logger.Instance.Write("HD: " + response);*/ + + return (response); + } + else + return (string.Empty); + } + + private static byte[] storeDecompressedByte(byte decompressedByte, byte[] decompressedBytes, ref int decompressedIndex) + { + if (decompressedByte == 0x00) + return (decompressedBytes); + + byte[] outputBuffer; + + if (decompressedIndex > decompressedBytes.Length) + outputBuffer = getByteBuffer(decompressedBytes); + else + outputBuffer = decompressedBytes; + + outputBuffer[decompressedIndex] = decompressedByte; + decompressedIndex++; + + return (outputBuffer); + } + + private static byte[] getByteBuffer(byte[] existingBuffer) + { + int size = 1024; + + if (existingBuffer != null) + size += existingBuffer.Length; + + byte[] newBuffer = new byte[size]; + + if (existingBuffer != null) + Array.Copy(existingBuffer, newBuffer, existingBuffer.Length); + + return (newBuffer); + } + + private static char resolveChar(string input) + { + int val = new int(); + char myChar = input[0]; //default value + + switch (input.ToUpper()) + { + case "START": + myChar = (char)0x00; + break; + case "STOP": + myChar = (char)0x02; + break; + case "ESCAPE": + myChar = (char)0x01; + break; + default: + try + { + if (input.Length > 2) + { + if (input.Substring(0, 2) == "0x") + { + val = int.Parse(input.Substring(2, input.Length - 2), + NumberStyles.AllowHexSpecifier); //ASCII for the input character + } + + myChar = (char)val; + } + } + catch (Exception e) + { + Logger.Instance.Write("OMG WUT: {0}" + e.Message); + } + break; + } + + return (myChar); + } + + /// + /// Log the decoding usage. + /// + public static void LogUsage() + { + if (encodings == null) + return; + + Logger.Instance.WriteSeparator("Huffman Usage"); + + StringBuilder text = new StringBuilder(); + + foreach (string encoding in encodings) + { + if (text.Length != 0) + text.Append(", "); + text.Append(encoding); + } + + Logger.Instance.Write("Huffman encodings used: " + text); + Logger.Instance.Write("Huffman single byte escape sequences: " + singleByteEscapes); + Logger.Instance.Write("Huffman multi byte escape sequences: " + multiByteEscapes); + + Logger.Instance.WriteSeparator("End Of Huffman Usage"); + + encodings = null; + singleByteEscapes = 0; + multiByteEscapes = 0; + } + } +} + diff --git a/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/EPGCollectorSide/DVBServices/Utils.cs b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/EPGCollectorSide/DVBServices/Utils.cs new file mode 100644 index 0000000..48ae93a --- /dev/null +++ b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/EPGCollectorSide/DVBServices/Utils.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DVBServices +{ + internal class Utils + { + /// + /// Convert a string of bytes to a hex string. + /// + /// The string to be converted. + /// The string of hex characters. + public static string ConvertToHex(byte[] inputChars) + { + return (ConvertToHex(inputChars, inputChars.Length)); + } + + /// + /// Convert a string of bytes to a hex string. + /// + /// The array holding the bytes to be converted. + /// The number of byte to be converted. + /// The string of hex characters. + public static string ConvertToHex(byte[] inputChars, int length) + { + return (ConvertToHex(inputChars, 0, length)); + } + + /// + /// Convert a string of bytes to a hex string. + /// + /// The array holding the bytes to be converted. + /// The the offset to the first byte to be converted. + /// The number of byte to be converted. + /// The string of hex characters. + public static string ConvertToHex(byte[] inputChars, int offset, int length) + { + char[] outputChars = new char[length * 2]; + int outputIndex = 0; + + for (int inputIndex = 0; inputIndex < length; inputIndex++) + { + int hexByteLeft = inputChars[offset] >> 4; + int hexByteRight = inputChars[offset] & 0x0f; + + outputChars[outputIndex] = getHex(hexByteLeft); + outputChars[outputIndex + 1] = getHex(hexByteRight); + + outputIndex += 2; + offset++; + } + + return ("0x" + new string(outputChars)); + } + + private static char getHex(int value) + { + if (value < 10) + return ((char)('0' + value)); + + return ((char)('a' + (value - 10))); + } + } +} diff --git a/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/EPGCollectorSide/DomainObjects/DebugEntry.cs b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/EPGCollectorSide/DomainObjects/DebugEntry.cs new file mode 100644 index 0000000..98e4b39 --- /dev/null +++ b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/EPGCollectorSide/DomainObjects/DebugEntry.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DomainObjects +{ + internal class DebugEntry + { + public static bool IsDefined(DebugName name) + { + return true; + } + } +} diff --git a/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/EPGCollectorSide/DomainObjects/Enumerations.cs b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/EPGCollectorSide/DomainObjects/Enumerations.cs new file mode 100644 index 0000000..3076495 --- /dev/null +++ b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/EPGCollectorSide/DomainObjects/Enumerations.cs @@ -0,0 +1,1806 @@ +////////////////////////////////////////////////////////////////////////////////// +// // +// Copyright © 2005-2020 nzsjb // +// // +// This Program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation; either version 2, or (at your option) // +// any later version. // +// // +// This Program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with GNU Make; see the file COPYING. If not, write to // +// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. // +// http://www.gnu.org/copyleft/gpl.html // +// // +////////////////////////////////////////////////////////////////////////////////// + +namespace DomainObjects +{ + /// + /// TV Station types. + /// + public enum TVStationType + { + /// + /// The type is DVB. + /// + Dvb, + /// + /// The type is ATSC. + /// + Atsc, + /// + /// The type is undefined. + /// + Undefined + } + + /// + /// Tuner node types. + /// + public enum TunerNodeType + { + /// + /// The tuner node type for satellite. + /// + Satellite, + /// + /// The tuner node type for terrestrial. + /// + Terrestrial, + /// + /// The tuner node type for cable. + /// + Cable, + /// + /// The tuner node type for ATSC. + /// + ATSC, + /// + /// The tuner node type for ISDB satellite. + /// + ISDBS, + /// + /// The tuner node type for ISDB terrestrial. + /// + ISDBT, + /// + /// The tuner node type for undefined types. + /// + Other + } + + /// + /// Tuner types. + /// + public enum TunerType + { + /// + /// The tuner type for satellite. + /// + Satellite, + /// + /// The tuner type for terrestrial. + /// + Terrestrial, + /// + /// The tuner type for cable. + /// + Cable, + /// + /// The tuner type for ATSC terrestrial. + /// + ATSC, + /// + /// The tuner type for ATSC cable. + /// + ATSCCable, + /// + /// The tuner type for Clear QAM. + /// + ClearQAM, + /// + /// The tuner type for ISDB-S. + /// + ISDBS, + /// + /// The tuner type for ISDB-T. + /// + ISDBT, + /// + /// The tuner type for SAT>IP servers. + /// + SATIP, + /// + /// The tuner type for file types. + /// + File, + /// + /// The tuner type for stream types. + /// + Stream, + /// + /// The tuner type for undefined types. + /// + Other + } + + /// + /// EPG sources. + /// + public enum EPGSource + { + /// + /// The EPG originated from the MHEG5 protocol. + /// + MHEG5, + /// + /// The EPG originated from the DVB EIT protocol. + /// + EIT, + /// + /// The EPG originated from the OpenTV protocol. + /// + OpenTV, + /// + /// The EPG originated from the FreeSat protocol. + /// + FreeSat, + /// + /// The EPG originated from the MediaHighway1 protocol. + /// + MediaHighway1, + /// + /// The EPG originated from the MediaHighway2 protocol. + /// + MediaHighway2, + /// + /// The EPG originated from the ATSC PSIP protocol. + /// + PSIP, + /// + /// The EPG originated from the Dish Network EEPG protocol. + /// + DishNetwork, + /// + /// The EPG originated from the Bell TV EEPG protocol. + /// + BellTV, + /// + /// The EPG originated from the Siehfern Info protocol. + /// + SiehfernInfo + } + + /// + /// The types of EPG collection. + /// + public enum CollectionType + { + /// + /// The collection is for the MHEG5 protocol. + /// + MHEG5, + /// + /// The collection is for the DVB EIT protocol. + /// + EIT, + /// + /// The collection is for the OpenTV protocol. + /// + OpenTV, + /// + /// The collection is for the FreeSat protocol. + /// + FreeSat, + /// + /// The collection is for the MediaHighway1 protocol. + /// + MediaHighway1, + /// + /// The collection is for the MediaHighway2 protocol. + /// + MediaHighway2, + /// + /// The collection is for the ATSC PSIP protocol. + /// + PSIP, + /// + /// The collection is for the Dish Network EEPG protocol. + /// + DishNetwork, + /// + /// The collection is for the Bell TV EEPG protocol. + /// + BellTV, + /// + /// The collection is for the Siehfern Info protocol. + /// + SiehfernInfo, + /// + /// The collection is for the NDS protocol. + /// + NDS + } + + /// + /// The values that a diseqc switch can have. + /// + public enum DiseqcSettings + { + /// + /// The switch is not used + /// + None, + /// + /// Simple A. + /// + A, + /// + /// Simple B. + /// + B, + /// + /// Use satellite A port A (Disqec 1.0 committed switch) + /// + AA, + /// + /// Use satellite A port B (Disqec 1.0 committed switch) + /// + AB, + /// + /// Use satellite B port A (Disqec 1.0 committed switch) + /// + BA, + /// + /// Use satellite B port B (Disqec 1.0 committed switch) + /// + BB, + /// + /// Use port 1 (Disqec 1.1 uncommitted switch) + /// + PORT1, + /// + /// Use port 2 (Disqec 1.1 uncommitted switch) + /// + PORT2, + /// + /// Use port 3 (Disqec 1.1 uncommitted switch) + /// + PORT3, + /// + /// Use port 4 (Disqec 1.1 uncommitted switch) + /// + PORT4, + /// + /// Use port 5 (Disqec 1.1 uncommitted switch) + /// + PORT5, + /// + /// Use port 6 (Disqec 1.1 uncommitted switch) + /// + PORT6, + /// + /// Use port 7 (Disqec 1.1 uncommitted switch) + /// + PORT7, + /// + /// Use port 8 (Disqec 1.1 uncommitted switch) + /// + PORT8, + /// + /// Use port 9 (Disqec 1.1 uncommitted switch) + /// + PORT9, + /// + /// Use port 10 (Disqec 1.1 uncommitted switch) + /// + PORT10, + /// + /// Use port 11 (Disqec 1.1 uncommitted switch) + /// + PORT11, + /// + /// Use port 12 (Disqec 1.1 uncommitted switch) + /// + PORT12, + /// + /// Use port 13 (Disqec 1.1 uncommitted switch) + /// + PORT13, + /// + /// Use port 14 (Disqec 1.1 uncommitted switch) + /// + PORT14, + /// + /// Use port 15 (Disqec 1.1 uncommitted switch) + /// + PORT15, + /// + /// Use port 16 (Disqec 1.1 uncommitted switch) + /// + PORT16, + /// + /// Use committed port AA uncommitted port 1 (Combination committed/uncommited switch) + /// + AAPORT1, + /// + /// Use committed port AB uncommitted port 1 (Combination committed/uncommited switch) + /// + ABPORT1, + /// + /// Use committed port BA uncommitted port 1 (Combination committed/uncommited switch) + /// + BAPORT1, + /// + /// Use committed port BB uncommitted port 1 (Combination committed/uncommited switch) + /// + BBPORT1, + /// + /// Use committed port AA uncommitted port 2 (Combination committed/uncommited switch) + /// + AAPORT2, + /// + /// Use committed port AB uncommitted port 2 (Combination committed/uncommited switch) + /// + ABPORT2, + /// + /// Use committed port BA uncommitted port 2 (Combination committed/uncommited switch) + /// + BAPORT2, + /// + /// Use committed port BB uncommitted port 2 (Combination committed/uncommited switch) + /// + BBPORT2, + /// + /// Use committed port AA uncommitted port 3 (Combination committed/uncommited switch) + /// + AAPORT3, + /// + /// Use committed port AB uncommitted port 3 (Combination committed/uncommited switch) + /// + ABPORT3, + /// + /// Use committed port BA uncommitted port 3 (Combination committed/uncommited switch) + /// + BAPORT3, + /// + /// Use committed port BB uncommitted port 3 (Combination committed/uncommited switch) + /// + BBPORT3, + /// + /// Use committed port AA uncommitted port 4 (Combination committed/uncommited switch) + /// + AAPORT4, + /// + /// Use committed port AB uncommitted port 4 (Combination committed/uncommited switch) + /// + ABPORT4, + /// + /// Use committed port BA uncommitted port 4 (Combination committed/uncommited switch) + /// + BAPORT4, + /// + /// Use committed port BB uncommitted port 4 (Combination committed/uncommited switch) + /// + BBPORT4 + + } + + /// + /// The state of a data update control. + /// + public enum DataState + { + /// + /// There are unresolved errors. + /// + HasErrors, + /// + /// The data does not need saving. + /// + NotChanged, + /// + /// The data needs saving. + /// + Changed + } + + /// + /// The function of the parameters. + /// + public enum ParameterSet + { + /// + /// The parameters are used by the Collector. + /// + Collector, + /// + /// The parameters are used by the DVBLogic plugin. + /// + Plugin + } + + /// + /// The type of run. + /// + public enum RunType + { + /// + /// The parameters are being loaded to run a collection. + /// + Collection, + /// + /// The parameters are being loaded into EPG Centre. + /// + Centre + } + + /// + /// The matching method for lookups. + /// + public enum MatchMethod + { + /// + /// The title must match exactly. + /// + Exact, + /// + /// The title must contain the string. + /// + Contains, + /// + /// The title must be the nearest match to the string. + /// + Nearest + } + + /// + /// The search priority for TV series episodes. + /// + public enum EpisodeSearchPriority + { + /// + /// The season and episode numbers are the priority when searching for an episode. + /// + SeasonEpisode, + /// + /// The subtitle is the priority when searching for an episode. + /// + Subtitle + } + + /// + /// The merge method for channel update. + /// + public enum ChannelMergeMethod + { + /// + /// No matching. + /// + None, + /// + /// Match on station name. + /// + Name, + /// + /// Match on channel number. + /// + Number, + /// + /// Match on channel name and number. + /// + NameNumber + } + + /// + /// The EPG scan method for channel update. + /// + public enum ChannelEPGScanner + { + /// + /// No scanning. + /// + None, + /// + /// Default scanning. + /// + Default, + /// + /// Scan using EPG Collector. + /// + EPGCollector, + /// + /// Scan using EIT scanner. + /// + EITScanner, + /// + /// XMLTV epg. + /// + Xmltv + } + + /// + /// Program exit codes. + /// + public enum ExitCode + { + /// + /// The run finished normally. + /// + OK, + /// + /// There are no suitable tuners installed. + /// + NoDVBTuners, + /// + /// The ini file cannot be opened. + /// + ParameterFileNotFound, + /// + /// There is an error in the ini file. + /// + ParameterError, + /// + /// The command line is incorrect. + /// + CommandLineWrong, + /// + /// A software exception has occurred. + /// + SoftwareException, + /// + /// Not all EPG data has been collected. + /// + EPGDataIncomplete, + /// + /// The user abandoned the run. + /// + AbandonedByUser, + /// + /// The ini file does not match the hardware configuration. + /// + ParameterTunerMismatch, + /// + /// The log file cannot be written. + /// + LogFileNotAvailable, + /// + /// Some frequencies could not be processed. + /// + SomeFrequenciesNotProcessed, + /// + /// The output file could not be created. + /// + OutputFileNotCreated, + /// + /// The simulation file could not be located or failed to load. + /// + SimulationFileError, + /// + /// No data was collected. + /// + NoDataCollected, + /// + /// The tuner filter could not be loaded. + /// + NoBDATunerFilter, + /// + /// The hardware filter chain could not be created. + /// + HardwareFilterChainNotBuilt, + /// + /// The DVBLogic plugin could not start. + /// + PluginNotStarted, + /// + /// The WMCUtility program has failed. + /// + WMCUtilityFailed + } + + /// + /// The precedence of data for an import files. + /// + public enum DataPrecedence + { + /// + /// The file data takes precedence over the broadcast data. + /// + File, + /// + /// The broadcast data takes precedence over the file data. + /// + Broadcast, + /// + /// The imported data is appended to the broadcast data. + /// + ImportAppend, + /// + /// The imported data replaces broadcast data. + /// + ImportReplace + } + + /// + /// The format of the ID attribute in an xmltv import file. + /// + public enum XmltvIdFormat + { + /// + /// The id attribute has no specific format. + /// + Undefined, + /// + /// The id attribue is the service id. + /// + ServiceId, + /// + /// The id attribute is the user channel number. + /// + UserChannelNumber, + /// + /// The id attribute contains the full channel identification (ie nid:tid:sid:name). + /// + FullChannelId, + /// + /// The id attribute contains the name of the channel. + /// + Name, + /// + /// The id attribute contains the Zap2it ATSC string. + /// + Zap2ItAtsc + } + + /// + /// The amount of data a collection controller collects. + /// + public enum CollectionSpan + { + /// + /// The controller collects all possible data. + /// + AllData, + /// + /// The controller collects only the station data. + /// + StationsOnly, + /// + /// The controller collects only the station and/or channel data. + /// + ChannelsOnly + } + + /// + /// The location of a text substring. + /// + public enum TextLocation + { + /// + /// The substring is at the start of the text. + /// + Start, + /// + /// The substring is at the end of the text. + /// + End, + /// + /// The substring can occur anywhere. + /// + Anywhere + } + + /// + /// The method used to replace text. + /// + public enum TextReplacementMode + { + /// + /// Replace only the specified text. + /// + TextOnly, + /// + /// Replace the specified text plus everything that follows. + /// + TextAndFollowing, + /// + /// Replace the specified text plus everything that preceeded it. + /// + TextAndPreceeding, + /// + /// Replace the specified text plus everything else. + /// + Everything + } + + /// + /// The metadata lookup image type. + /// + public enum LookupImageType + { + /// + /// Type is thumbnail. + /// + Thumbnail, + /// + /// Type is poster. + /// + Poster, + /// + /// Type is banner. + /// + Banner, + /// + /// Type is fanart. + /// + Fanart, + /// + /// Type is small poster. + /// + SmallPoster, + /// + /// Type is small banner. + /// + SmallFanart, + /// + /// No image downloaded. + /// + None + } + + /// + /// The service type of a service. + /// + public enum ServiceType + { + /// + /// Type is satellite. + /// + Satellite, + /// + /// Type is terrestrial. + /// + Terrestrial, + /// + /// Type is cable. + /// + Cable + } + + /// + /// The protocols supported by stream collections. + /// + public enum StreamProtocol + { + /// + /// The protocol is RTSP. + /// + Rtsp, + /// + /// The protocol is RTP/RTCP. + /// + Rtp, + /// + /// The protocol is UDP. + /// + Udp, + /// + /// The protocol is HTTP. + /// + Http + } + + /// + /// The methods used to select a character set + /// + public enum CharacterSetUsage + { + /// + /// The character set has not been used. + /// + NotUsed, + /// + /// The default method was used. + /// + Default, + /// + /// The character set was determined by the data broadcast. + /// + Broadcast, + /// + /// The character set was determined by a user parameter. + /// + User + } + + /// + /// The identifiers used with the Option parameter. + /// + public enum OptionName + { + /// + /// Don't log breaks in the data. + /// + AcceptBreaks, + /// + /// Add season/episode numbers to description. + /// + AddSeasonEpisodeToDesc, + /// + /// Autmatically map the data to the channels. + /// + AutoMapEpg, + /// + /// Output the full name as the identity. + /// + ChannelIdFullName, + /// + /// Output the channel name as the identity. + /// + ChannelIdName, + /// + /// Output a sequential number as the identity. + /// + ChannelIdSeqNo, + /// + /// Output the service ID as the identity. + /// + ChannelIdSid, + /// + /// Check for programme repeats. + /// + CheckForRepeats, + /// + /// Create an audio description tag. + /// + CreateAdTag, + /// + /// Create rhe area/region cross reference file. + /// + CreateArChannels, + /// + /// Create the Bladerunner file. + /// + CreateBrChannels, + /// + /// Create the channel definition file. + /// + CreateChannelDefFile, + /// + /// Create channels that don't appear in the SDT. + /// + CreateMissingChannels, + /// + /// Create a Plex compatible episode-num tag in XMLTV files. + /// + CreatePlexEpisodeNumTag, + /// + /// Create the SageTV frequency file. + /// + CreateSageTvFrq, + /// + /// Create satellite reference files. + /// + CreateSatIni, + /// + /// Custom categories override the broadcasters categories. + /// + CustomCategoryOverride, + /// + /// Disable the drivers DiSEqc commands. + /// + DisableDriverDiseqc, + /// + /// Disable the WMC guide loader. + /// + DisableInbandLoader, + /// + /// Don't create a channel when importing if channel changes present and channel not in list. + /// + DontCreateImportChannels, + /// + /// Duplicate data for channels with the same name. + /// + DuplicateSameChannels, + /// + /// Duplicate data for channels with the same name if the destination has no data. + /// + DuplicateSameChannelsNoData, + /// + /// Clear the DVBViewer before loading. + /// + DvbViewerClear, + /// + /// Import the data to DVBViewer. + /// + DvbViewerImport, + /// + /// Import the data to the DVBViewer Recording Service. + /// + DvbViewerRecSvcImport, + /// + /// Make subtitles visible in the DVBViewer EPG. + /// + DvbViewerSubtitleVisible, + /// + /// EIT collections finish on record count. + /// + EitDoneOnCount, + /// + /// Ouput each element of a category in a separate xmltv tag. + /// + ElementPerTag, + /// + /// Convert EIT format bytes. + /// + FormatConvert, + /// + /// Convert EIT format bytes using a conversion table. + /// + FormatConvertTable, + /// + /// Remove EIT format bytes. + /// + FormatRemove, + /// + /// Replace EIT format bytes with a space. + /// + FormatReplace, + /// + /// Ignore WMC recordings when checking for repeats. + /// + IgnoreWmcRecordings, + /// + /// Ensure no output file if no data collected. + /// + NoDataNoFile, + /// + /// Don't create an episode tag. + /// + NoEpisodeTag, + /// + /// Don't create EPG entries if the times are incorrect. + /// + NoInvalidEntries, + /// + /// Don't use the keyboard during the collection process. + /// + NoLogExcluded, + /// + /// Don't remove data from descriptions. + /// + NoRemoveData, + /// + /// Dont check simulcast channels for repeats. + /// + NoSimulcastRepeats, + /// + /// Don't create dummy WMC affiliates. + /// + NoWmcDummyAffiliates, + /// + /// Omit the part number from the xmltv episode tag. + /// + OmitPartNumber, + /// + /// Import the data to DVBLogic. + /// + PluginImport, + /// + /// Prepend air date to description. + /// + PrefixDescriptionWithAirDate, + /// + /// Prepend season and episode number to subtitle. + /// + PrefixSubtitleWithSeasonEpisode, + /// + /// Process all channels irrespective of type. + /// + ProcessAllStations, + /// + /// Repeat DiSEqC commands if they fail. + /// + RepeatDiseqc, + /// + /// Round programme times. + /// + RoundTime, + /// + /// Run the collection process as a Windows service. + /// + RunFromService, + /// + /// Run the WMC tasks for reindexing and PVR scheduling after import. + /// + RunWmcTasks, + /// + /// Don't output to the SageTV file if a channel has no EPG data. + /// + SageTvOmitNoEpg, + /// + /// Set the previously shown XMLTV tag to a default date if it is present but empty. + /// + SetXmltvPreviouslyShownDefault, + /// + /// Use SID only to match EPG data with channel. + /// + SidMatchOnly, + /// + /// Save the channel information. + /// + StoreStationInfo, + /// + /// Change the DiSEqC switch after starting the DirectShow graph. + /// + SwitchAfterPlay, + /// + /// Change the DiSEqC switch after tuning the frequency. + /// + SwitchAfterTune, + /// + /// Only terrestrial channels are relevant. + /// + TcRelevantOnly, + /// + /// Use the codepage from the broadcast. + /// + UseBroadcastCp, + /// + /// Create an XMLTV file suitable for BSEPG. + /// + UseBsepg, + /// + /// Use the channel ID as the idfentity. + /// + UseChannelId, + /// + /// Use the content subtype when processing content type. + /// + UseContentSubtype, + /// + /// Use the programme description as the category. + /// + UseDescAsCategory, + /// + /// Use the programme description as the subtitle. + /// + UseDescAsSubtitle, + /// + /// Use DiSEqC commands to change the switch. + /// + UseDiseqcCommand, + /// + /// Export to DVBViewer. + /// + UseDvbViewer, + /// + /// Use FreeSat tables to decode compressed EIT data. + /// + UseFreeSatTables, + /// + /// Download station images. + /// + UseImage, + /// + /// Use the logical channel number as the identity. + /// + UseLcn, + /// + /// Ignore the programme description. + /// + UseNoDesc, + /// + /// Use the numeric part of the CRID as the eisode identifier. + /// + UseNumericCrid, + /// + /// Use the whole CRID as the episode identifier. + /// + UseRawCrid, + /// + /// Only change the DiSEqC switch if the tuner is not in use. + /// + UseSafeDiseqc, + /// + /// Use the stored channel information in place of the broadcast data. + /// + UseStoredStationInfo, + /// + /// Use the in-built WMC repeat checking with the programme titles. + /// + UseWmcRepeatCheck, + /// + /// Use the in-built WMC repeat checking with broadcaster references. + /// + UseWmcRepeatCheckBroadcast, + /// + /// Only create valid episode tags. + /// + ValidEpisodeTag, + /// + /// Only a VBox compatible episode tags. + /// + VBoxEpisodeTag, + /// + /// Import the data to WMC. + /// + WmcImport, + /// + /// Mark 4 star programmes as special for WMC. + /// + WmcStarSpecial, + } + + /// + /// The identifiers used with the TraceId parameter. + /// + public enum TraceName + { + /// + /// Log new channels. + /// + AddChannel, + /// + /// Log BDA information. + /// + Bda, + /// + /// Log BDA pid mapping. + /// + BdaPidMap, + /// + /// Log BDA signal statistics. + /// + BdaSigStats, + /// + /// Dump BellTV sections. + /// + BellTvSections, + /// + /// Log the bouquet data. + /// + BouquetSections, + /// + /// Log continuity errors. + /// + ContinuityErrors, + /// + /// Log the D3 descriptor. + /// + DescriptorD3, + /// + /// Log Dish Network data. + /// + DishNetworkSections, + /// + /// Log the completion status of DSMCC blocks. + /// + DsmccComplete, + /// + /// Log the DSMCC directory layout. + /// + DsmccDirLayout, + /// + /// Log the contents of DSMCC files. + /// + DsmccDumpFiles, + /// + /// Log the contents of the DSMCC EPG files. + /// + DsmccFile, + /// + /// Log the DSMCC modules. + /// + DsmccModules, + /// + /// Log the DSMCC EPG fields. + /// + DsmccRecLayout, + /// + /// Log the DSMCC records. + /// + DsmccRecord, + /// + /// Dump the MHW1/2 category data. + /// + DumpCategorySections, + /// + /// Dump the MHW1/2 channel data. + /// + DumpChannelSections, + /// + /// Dump the MHW1/2 summary sections. + /// + DumpSummarySections, + /// + /// Dump the MHW1/2 title sections. + /// + DumpTitleSections, + /// + /// Log programme repeats. + /// + DuplicatesFlagged, + /// + /// Log the EIT format control bytes. + /// + EitControlBytes, + /// + /// Dump the FreeSat data. + /// + FreeSatSections, + /// + /// Log generic descriptors. + /// + GenericDescriptor, + /// + /// Log only generic descriptors. + /// + GenericDescriptorOnly, + /// + /// Only log the protocol for OpenTV. + /// + GenericOpenTvRecord, + /// + /// Log metadata lookup results. + /// + LookupName, + /// + /// Log metadata lookup results for specified name. + /// + Lookups, + /// + /// Log metadata lookup details. + /// + LookupsDetail, + /// + /// Log metadata lookup errors. + /// + LookupsError, + /// + /// Log metadata lookup thatv were not located. + /// + LookupsNotFound, + /// + /// Dump the MPEG2 data packets. + /// + Mpeg2Packets, + /// + /// Log the MPEG2 sections stored and ignored. + /// + Mpeg2SectionsStored, + /// + /// Log the PID's used. + /// + PidHandler, + /// + /// Log the data blocks created by the PID handlers. + /// + PidHandlerBlocks, + /// + /// Log the PID activity for service information. + /// + PidHandlerSi, + /// + /// Log the PID numbers used. + /// + PidNumbers, + /// + /// Log the names of DSMCC PNG files. + /// + PngNames, + /// + /// Dump the protocol. + /// + Protocol, + /// + /// Set the PSIFilter up for logging. + /// + PsiFilter, + /// + /// Log the service entries in Australian MHEG5 data. + /// + ServiceEntries, + /// + /// Log the transport packets. + /// + TransportPackets, + /// + /// Log the packets from a transport stream file. + /// + TsFilePackets, + /// + /// Log the packets if they are relevant. + /// + TsPidPackets + } + + /// + /// The identifiers used with the DebugId parameter. + /// + public enum DebugName + { + /// + /// Adjust programme start times. + /// + AdjustStartTimes, + /// + /// Dump OpenTV data as a bit pattern. + /// + BitPattern, + /// + /// Extract the CanalSat zip files from the DSMCC carousel. + /// + CanalSatEpg, + /// + /// Process unknown carousels. + /// + Carousels, + /// + /// Generate a category cross-reference. + /// + CatXref, + /// + /// Create channels if they don't exist. + /// + DontLogGaps, + /// + /// Don't log programme start time overlaps. + /// + DontLogOverlaps, + /// + /// Finish MHEG5 collections even if the data is incomplete. + /// + DsmccIgnoreIncomplete, + /// + /// Dump AIT sections. + /// + DumpAitSections, + /// + /// Dump EIT sections. + /// + DumpEitSections, + /// + /// Dump OpenTV summary sections. + /// + DumpOpenTvSummarySections, + /// + /// Dump the service description data blocks. + /// + DumpSdtBlock, + /// + /// Log the contents of an EIT Zip file. + /// + EitZipContents, + /// + /// Log the result of an episode metadata lookup. + /// + EpisodeResult, + /// + /// Dump the ATSC event information table. + /// + EventInformationTable, + /// + /// Create an extended log file (up to 64mb). + /// + ExtendedLogFile, + /// + /// Dump the ATSC extended text table. + /// + ExtendedTextTable, + /// + /// Dump unspecified FeeSat sections. + /// + GetOtherSections, + /// + /// Switch off the xml character checking. + /// + IgnoreXmlChars, + /// + /// Log titles and descriptions that should be combined. + /// + LogBrokenTitles, + /// + /// Log the CA data blocks. + /// + LogCaData, + /// + /// Log an OpenTV category. + /// + LogCatEvent, + /// + /// Log all channels. + /// + LogChannels, + /// + /// Log the channel information in detail. + /// + LogChannelData, + /// + /// Log the channel groups (OpenTV only). + /// + LogChannelGroups, + /// + /// Log the codepages used. + /// + LogCodepages, + /// + /// Log the programme descriptions. + /// + LogDescriptions, + /// + /// Log descriptors. + /// + LogDescriptorData, + /// + /// Log the progress of the DVBViewer import process. + /// + LogDvbViewerImport, + /// + /// Log EPG linkage information. + /// + LogEpgLinkage, + /// + /// Log episode information. + /// + LogEpisodeInfo, + /// + /// Log OpenTV extended descriptions. + /// + LogExtendedDescriptions, + /// + /// Log escaped Huffman strings. + /// + LogHuffman, + /// + /// Log a JSON structure. + /// + LogJsonStructure, + /// + /// Log JSON text. + /// + LogJsonText, + /// + /// Set the Sat>IP log level. + /// + LogLevel, + /// + /// Log incomplete EIT entries. + /// + LogIncompleteEit, + /// + /// Log merged channels. + /// + LogMergedChannels, + /// + /// Log the series information from an MXF file. + /// + LogMxfSeries, + /// + /// Log the warninga when creating an MXF file. + /// + LogMxfWarnings, + /// + /// Log the network data. + /// + LogNetwork, + /// + /// Log the network map. + /// + LogNetworkMap, + /// + /// Log the BellTV or Dish Network original description. + /// + LogOriginal, + /// + /// Log descriptors that are out of scope. + /// + LogOutOfScope, + /// + /// Log the program map table. + /// + LogPmt, + /// + /// Dump the ATSC extended text data. + /// + LogPsipExtendedText, + /// + /// Log the response keys from lookup requests. + /// + LogResponseKeys, + /// + /// Log the use of Schedules Direct genres. + /// + LogSdGenres, + /// + /// Log the use of Schedules Direct prefixes. + /// + LogSdPrefixes, + /// + /// Log the use of season/episode Id's. + /// + LogSeIds, + /// + /// Log the use of season/episode CRId's. + /// + LogSeCrids, + /// + /// Log the station type. + /// + LogStationType, + /// + /// Log the stream data. + /// + LogStreamInfo, + /// + /// Log the programme titles. + /// + LogTitles, + /// + /// Log undefined OpenTV records. + /// + LogUndefinedRecords, + /// + /// Log unknown OpenTV records. + /// + LogUnknownRecords, + /// + /// Dump the ATSC master guide table. + /// + MasterGuideTable, + /// + /// Set the MHEG5 PID. + /// + Mheg5Pid, + /// + /// Dump MHW1 category sections. + /// + Mhw1CategorySections, + /// + /// Log missing MHW2 summary sections. + /// + Mhw2SummaryMissing, + /// + /// Log unknown MHW2 sections. + /// + Mhw2Unknown, + /// + /// Don't output a default original air date of the programme start time. + /// + MxfNoDefAirDate, + /// + /// Don't output a separate program entry if a program is flagged as new. + /// + MxfNoNewProgEntry, + /// + /// Dump NagraGuide data. + /// + NagraBlocks, + /// + /// Process NDS data. + /// + NDS, + /// + /// Log NDS binXml data. + /// + NDSBinXml, + /// + /// Log NDS binXml block data. + /// + NDSBinXmlBlocks, + /// + /// Log NDS SQL event data. + /// + NDSSqlEvents, + /// + /// Log NDS SQL group data. + /// + NDSSqlGroups, + /// + /// Log NDS SQL service data. + /// + NDSSqlServices, + /// + /// Log NDS SQL string data. + /// + NDSSqlStrings, + /// + /// Dump network information table sections. + /// + NitSections, + /// + /// Don't output log messages to the console window. + /// + NotQuiet, + /// + /// WMC is not present. + /// + NoWmc, + /// + /// Dump the data from other sections. + /// + OtherSections, + /// + /// Dump the ATSC rating region data. + /// + RatingRegionTable, + /// + /// Log replays. + /// + Replays, + /// + /// Don't delete the EIT carousel zip data. + /// + RetainZipData, + /// + /// Schedules Direct testing. + /// + SchedulesDirect, + /// + /// Log multiple colons in OpenTV data. + /// + ShowColons, + /// + /// Dump SiehFern data. + /// + SiehfernBlocks, + /// + /// Dump SiehFern channel data. + /// + SiehfernChannelBlocks, + /// + /// Dump SiehFern EPG blocks. + /// + SiehfernEpgBlocks, + /// + /// Dump SiehFern EPG details. + /// + SiehfernEpgDetail, + /// + /// Log the contents of the stack. + /// + StackTrace, + /// + /// Dump the OpenTV title data. + /// + TitleSection, + /// + /// Log unknown descriptors. + /// + UnknownDescriptors, + /// + /// Update the channel information. + /// + UpdateChannels, + /// + /// Update the station information. + /// + UpdateStation, + /// + /// Use DVBLink virtual tuners. + /// + UseDvbLink, + /// + /// Use the specific network provider. + /// + UseSpecificNp, + /// + /// Dump the ATSC virtual channel data. + /// + VirtualChannelTable, + /// + /// Create new WMC channels if they don't exist. + /// + WmcNewChannels, + /// + /// Create one MXF programme for each unique programme + /// + WmcUniqueProgramme, + /// + /// Don't set a default date if previously-shown has no value + /// + XmltvNoDefPlayDate + } + + /// + /// The level to be used in equality testing. + /// + public enum EqualityLevel + { + /// + /// All properties must be checked. + /// + Entirely, + /// + /// Only identification fields are checked. + /// + Identity, + } + + /// + /// The streaming server type. + /// + public enum StreamServerType + { + /// + /// Undefined. + /// + Any, + /// + /// Sat>IP. + /// + SatIP, + /// + /// VBox. + /// + VBox, + } + + /// + /// The mode used to extract the correct event category depending on the output. + /// + public enum EventCategoryMode + { + /// + /// The category is for an XMLTV file + /// + Xmltv, + /// + /// The category is for Windows Media Centre + /// + Wmc, + /// + /// The category is for the DVBLogic plugin + /// + DvbLogic, + /// + /// The category is for DVBViewer + /// + DvbViewer + } + + /// + /// The mode used to extract the correct event category depending on the output. + /// + public enum ImportImageMode + { + /// + /// Do not download images + /// + None, + /// + /// Download just channel images. + /// + Channels, + /// + /// Download just programme images. + /// + Programmes, + /// + /// Download both channel and programme images. + /// + Both + } + + /// + /// The providers of TV metadata. + /// + public enum TVLookupProvider + { + /// + /// The provider is TheTVDB database + /// + Tvdb, + /// + /// The provider is the TMDB database. + /// + Tmdb + } +} + diff --git a/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/EPGCollectorSide/DomainObjects/Logger.cs b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/EPGCollectorSide/DomainObjects/Logger.cs new file mode 100644 index 0000000..d646e97 --- /dev/null +++ b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/EPGCollectorSide/DomainObjects/Logger.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using skyscraper8.Skyscraper.Plugins; + +namespace DomainObjects +{ + internal class Logger + { + private static Logger _instance; + public static Logger Instance + { + get + { + if(_instance == null) + _instance = new Logger(); + return _instance; + } + } + + private class EPGCollector + { + + } + + private PluginLogger _realLogger; + + private Logger() + { + _realLogger = PluginLogManager.GetLogger(typeof(EPGCollector)); + } + + public void Write(string s) + { + _realLogger.Log(PluginLogLevel.All, s); + } + + /// + /// Write a log separator line. + /// + /// The text of the separator. + public void WriteSeparator(string identity) + { + Write(""); + Write("============================ " + identity + " =============================="); + Write(""); + } + } +} diff --git a/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/Properties/Resources.Designer.cs b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/Properties/Resources.Designer.cs new file mode 100644 index 0000000..771cd3b --- /dev/null +++ b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/Properties/Resources.Designer.cs @@ -0,0 +1,83 @@ +//------------------------------------------------------------------------------ +// +// Dieser Code wurde von einem Tool generiert. +// Laufzeitversion:4.0.30319.42000 +// +// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn +// der Code erneut generiert wird. +// +//------------------------------------------------------------------------------ + +namespace skyscraper8.EPGCollectorPort.Properties { + using System; + + + /// + /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. + /// + // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert + // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. + // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen + // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("skyscraper8.EPGCollectorPort.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle + /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Byte[]. + /// + internal static byte[] Huffman_Dictionary_Freesat_T1 { + get { + object obj = ResourceManager.GetObject("Huffman Dictionary Freesat T1", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Sucht eine lokalisierte Ressource vom Typ System.Byte[]. + /// + internal static byte[] Huffman_Dictionary_Freesat_T2 { + get { + object obj = ResourceManager.GetObject("Huffman Dictionary Freesat T2", resourceCulture); + return ((byte[])(obj)); + } + } + } +} diff --git a/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/Properties/Resources.resx b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/Properties/Resources.resx new file mode 100644 index 0000000..ce82a57 --- /dev/null +++ b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/Properties/Resources.resx @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\Huffman Dictionary Freesat T1.cfg;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\Huffman Dictionary Freesat T2.cfg;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/Resources/Huffman Dictionary Freesat T1.cfg b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/Resources/Huffman Dictionary Freesat T1.cfg new file mode 100644 index 0000000..d110fc5 --- /dev/null +++ b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/Resources/Huffman Dictionary Freesat T1.cfg @@ -0,0 +1,2027 @@ +START:00:T: +START:010:B: +START:1000:C: +START:1001:I: +START:1101:S: +START:01100:L: +START:01110:D: +START:01111:H: +START:10100:R: +START:10101:N: +START:10110:E: +START:11000:F: +START:11001:A: +START:11100:M: +START:11101:P: +START:11110:W: +START:011011:Q: +START:101111:G: +START:111110:J: +START:0110100:K: +START:1011101:U: +START:1111110:O: +START:01101010:6: +START:01101011:.: +START:10111000:V: +START:11111110:Y: +START:101110011:2: +START:111111111:X: +START:1011100100:Z: +START:1111111100:8: +START:10111001010:1: +START:10111001011:3: +START:111111110100:4: +START:111111110101:': +START:111111110111: : +START:11111111011000:5: +START:11111111011011:0: +START:111111110110011:m: +START:1111111101100100:c: +START:1111111101101000:9: +START:1111111101101010:a: +START:1111111101101011:d: +START:11111111011001010:s: +START:11111111011001011:p: +START:11111111011010010:(: +START:111111110110100110:t: +START:1111111101101001110:7: +START:11111111011010011110:ESCAPE: +START:11111111011010011111:l: +ESCAPE:0:ESCAPE: +ESCAPE:1:ESCAPE: +STOP:0:ESCAPE: +STOP:1:ESCAPE: +0x03:0:ESCAPE: +0x03:1:ESCAPE: +0x04:0:ESCAPE: +0x04:1:ESCAPE: +0x05:0:ESCAPE: +0x05:1:ESCAPE: +0x06:0:ESCAPE: +0x06:1:ESCAPE: +0x07:0:ESCAPE: +0x07:1:ESCAPE: +0x08:0:ESCAPE: +0x08:1:ESCAPE: +0x09:0:ESCAPE: +0x09:1:ESCAPE: +0x0a:0:ESCAPE: +0x0a:1:ESCAPE: +0x0b:0:ESCAPE: +0x0b:1:ESCAPE: +0x0c:0:ESCAPE: +0x0c:1:ESCAPE: +0x0d:0:ESCAPE: +0x0d:1:ESCAPE: +0x0e:0:ESCAPE: +0x0e:1:ESCAPE: +0x0f:0:ESCAPE: +0x0f:1:ESCAPE: +0x10:0:ESCAPE: +0x10:1:ESCAPE: +0x11:0:ESCAPE: +0x11:1:ESCAPE: +0x12:0:ESCAPE: +0x12:1:ESCAPE: +0x13:0:ESCAPE: +0x13:1:ESCAPE: +0x14:0:ESCAPE: +0x14:1:ESCAPE: +0x15:0:ESCAPE: +0x15:1:ESCAPE: +0x16:0:ESCAPE: +0x16:1:ESCAPE: +0x17:0:ESCAPE: +0x17:1:ESCAPE: +0x18:0:ESCAPE: +0x18:1:ESCAPE: +0x19:0:ESCAPE: +0x19:1:ESCAPE: +0x1a:0:ESCAPE: +0x1a:1:ESCAPE: +0x1b:0:ESCAPE: +0x1b:1:ESCAPE: +0x1c:0:ESCAPE: +0x1c:1:ESCAPE: +0x1d:0:ESCAPE: +0x1d:1:ESCAPE: +0x1e:0:ESCAPE: +0x1e:1:ESCAPE: +0x1f:0:ESCAPE: +0x1f:1:ESCAPE: + :0000:W: + :0011:M: + :0100:C: + :0101:B: + :0111:P: + :1001:T: + :1100:N: + :1111:S: + :00011:I: + :00100:G: + :01100:H: + :01101:D: + :10000:o: + :10001:A: + :10100:t: + :10110:a: + :10111:F: + :11010:L: + :11011:R: + :001011:U: + :101011:O: + :111001:J: + :111010:E: + :0001000:f: + :0001001:Q: + :0001011:V: + :0010100:STOP: + :0010101:w: + :1110000:2: + :1110001:K: + :1110110:Y: + :1110111:i: + :00010100:-: + :10101001:1: + :101010000:&: + :101010101:X: + :0001010101:r: + :1010100010:5: + :1010100011:Z: + :1010101001:9: + :1010101101:s: + :1010101110:4: + :1010101111:3: + :00010101000:7: + :00010101100:b: + :00010101110:y: + :10101010000:': + :10101011000:6: + :000101011010:v: + :000101011011:d: + :000101011110:(: + :101010100010: : + :101010100011:0: + :101010110010:n: + :101010110011:8: + :0001010100110:g: + :0001010111110:u: + :00010101001000:+: + :00010101001001:.: + :00010101001010:ESCAPE: + :00010101001011:l: + :00010101001111:m: + :00010101111110:p: + :000101010011100:\: + :000101010011101:/: + :000101011111111:e: + :0001010111111101:": + :00010101111111001:c: + :000101011111110000:k: + :000101011111110001:h: +!:1:STOP: +!:01: : +!:001:.: +!:0001:!: +!:00001:": +!:000000:ESCAPE: +!:000001:0x3a: +":0: : +":10:ESCAPE: +":11:I: +#:0:ESCAPE: +#:1:ESCAPE: +$:0:ESCAPE: +$:1:ESCAPE: +%:1: : +%:00:ESCAPE: +%:01:STOP: +&:1: : +&:01:B: +&:000:ESCAPE: +&:001:.: +':1:s: +':000:m: +':010:C: +':0010:t: +':0011: : +':01100:d: +':01110:v: +':011011:r: +':011111:A: +':0110101:n: +':01101000:G: +':01111001:l: +':011010011:D: +':011110000:B: +':011110001:e: +':011110101:i: +':011110110:6: +':0110100100:L: +':0111101001:STOP: +':0111101111:w: +':01101001010:O: +':01111010000:S: +':01111010001:E: +':01111011101:N: +':011110111001:R: +':0110100101100:a: +':0110100101101:M: +':0110100101110:K: +':0110100101111:F: +':0111101110000:0: +':01111011100010:ESCAPE: +':01111011100011:c: +(:1:c: +(:000:1: +(:0010:M: +(:0011:U: +(:0100:R: +(:0101:D: +(:0110:H: +(:01110:S: +(:011110:F: +(:0111110:G: +(:01111110:ESCAPE: +(:01111111:Y: +):1:STOP: +):00:ESCAPE: +):01: : +*:0:*: +*:101: : +*:1000:d: +*:1100:m: +*:1101:t: +*:1111:s: +*:10010:e: +*:11100:g: +*:11101:k: +*:100110:ESCAPE: +*:100111:y: ++:0:ESCAPE: ++:1: : +,:1: : +,:01:0: +,:000:ESCAPE: +,:001:.: +-:11: : +-:011:S: +-:100:G: +-:101:O: +-:0011:T: +-:0100:U: +-:00000:E: +-:00010:D: +-:000010:m: +-:000110:0: +-:000111:I: +-:001010:6: +-:010100:F: +-:010101:o: +-:0000110:L: +-:0000111:C: +-:0010001:A: +-:0010010:t: +-:0010011:Y: +-:0010111:2: +-:0101100:B: +-:0101101:.: +-:00100000:P: +-:00100001:Z: +-:01011100:8: +-:01011101:i: +-:01011110:d: +-:01011111:H: +-:001011001:N: +-:001011011:R: +-:0010110000:1: +-:0010110001:W: +-:00101101001:c: +-:00101101010:a: +-:00101101011:M: +-:001011010000:ESCAPE: +-:001011010001:Q: +.:1:.: +.:01:STOP: +.:0010: : +.:00000:I: +.:00001:T: +.:00010:C: +.:00110:p: +.:00111:0: +.:000111:H: +.:00011010:W: +.:000110001:S: +.:000110110:3: +.:000110111:B: +.:0001100000:1: +.:0001100001:M: +.:0001100110:c: +.:00011001000:t: +.:00011001001:R: +.:00011001010:F: +.:00011001110:E: +.:00011001111:A: +.:0001100101100:ESCAPE: +.:0001100101101:l: +.:0001100101110:d: +.:0001100101111:U: +/:00:1: +/:10:7: +/:010:4: +/:011:2: +/:110:3: +/:1110:5: +/:111100:6: +/:111110:C: +/:1111010:9: +/:1111011: : +/:1111110:8: +/:11111111:U: +/:1111111000:G: +/:1111111010:0: +/:11111110010:ESCAPE: +/:11111110011:W: +/:11111110110:V: +/:11111110111:S: +0:00:6: +0:01: : +0:11:0: +0:1001:p: +0:1010:STOP: +0:10000:1: +0:10001:a: +0:10111:7: +0:1011000:-: +0:1011010:s: +0:10110011:4: +0:10110110:t: +0:101101111:%: +0:1011001000:8: +0:1011001001:0x3a: +0:1011001010:5: +0:1011001011:2: +0:1011011100:/: +0:10110111011:U: +0:101101110101:,: +0:1011011101000:.: +0:10110111010010:ESCAPE: +0:10110111010011:l: +1:01:STOP: +1:000:.: +1:101:0: +1:111:1: +1:0010:2: +1:0011: : +1:1101:/: +1:10010:8: +1:11000:3: +1:100000:5: +1:100001:s: +1:100010:6: +1:100011:0x3a: +1:100110:': +1:110010:X: +1:110011:9: +1:1001111:4: +1:10011101:-: +1:100111001:7: +1:1001110000:): +1:10011100010:ESCAPE: +1:10011100011:,: +2:0:0: +2:11:4: +2:101:STOP: +2:1001: : +2:10000:0x3a: +2:1000101:5: +2:1000111:/: +2:10001000:.: +2:10001001:1: +2:10001100:W: +2:100011011:7: +2:10001101001:3: +2:10001101011:Z: +2:100011010000:n: +2:100011010001:6: +2:100011010101:': +2:1000110101000:ESCAPE: +2:1000110101001:s: +3:0: : +3:10:STOP: +3:1100:r: +3:1101:/: +3:1111:B: +3:11100:0: +3:1110100:0x3a: +3:1110110:-: +3:11101010:1: +3:11101011:8: +3:11101111:4: +3:1110111000:6: +3:1110111011:9: +3:11101110011:t: +3:11101110100:3: +3:111011100100:ESCAPE: +3:111011100101:e: +3:111011101010:7: +3:111011101011:5: +4:0:STOP: +4:11: : +4:1001:0x3a: +4:1011:/: +4:10001:8: +4:10101:.: +4:100000:9: +4:101000:0: +4:1010010:M: +4:10000101:I: +4:10000110:): +4:10100110:R: +4:10100111:-: +4:100001000:W: +4:100001110:P: +4:100001111:5: +4:1000010011:2: +4:10000100100:ESCAPE: +4:10000100101:': +5:0:STOP: +5:11: : +5:101:0: +5:1001:/: +5:100001:-: +5:100011:0x3a: +5:1000001:t: +5:1000100:3: +5:1000101:1: +5:10000000:ESCAPE: +5:10000001:a: +6:00:STOP: +6:01: : +6:10:0: +6:111:0x3a: +6:11001:.: +6:11011:i: +6:110000:-: +6:110101:a: +6:1100011:4: +6:1101000:8: +6:1101001:/: +6:11000100:6: +6:110001011:9: +6:1100010100:3: +6:11000101010:ESCAPE: +6:11000101011:t: +7:1:STOP: +7:01: : +7:000:0: +7:0011:.: +7:00101:/: +7:0010000:1: +7:0010010:5: +7:00100010:ESCAPE: +7:00100011:4: +7:00100110:3: +7:00100111:2: +8:1: : +8:00:0: +8:010:0x3a: +8:01101:STOP: +8:011000:t: +8:011001:p: +8:011101:8: +8:011110:.: +8:011111:6: +8:0111000:5: +8:01110010:9: +8:011100110:M: +8:0111001110:F: +8:01110011110:ESCAPE: +8:01110011111:c: +9:0:1: +9:11:STOP: +9:1000:9: +9:1010:.: +9:10011:0: +9:100100: : +9:100101:8: +9:101100:7: +9:101101:/: +9:101110:6: +9:1011111:0x3a: +9:10111101:4: +9:101111000:ESCAPE: +9:101111001:3: +0x3a:1: : +0x3a:00:0: +0x3a:011:.: +0x3a:0100:2: +0x3a:01010:1: +0x3a:010111:3: +0x3a:0101101:C: +0x3a:01011000:ESCAPE: +0x3a:01011001:T: +;:1: : +;:00:ESCAPE: +;:01:.: +<:0:ESCAPE: +<:1:ESCAPE: +=:0:ESCAPE: +=:1:ESCAPE: +>:0:ESCAPE: +>:1:ESCAPE: +?:1:STOP: +?:01: : +?:001:0x3a: +?:0000:ESCAPE: +?:0001:.: +@:0:ESCAPE: +@:1:H: +A:001:r: +A:010: : +A:100:l: +A:110:n: +A:0000:m: +A:0111:g: +A:1111:d: +A:00010:w: +A:01100:T: +A:01101:c: +A:10101:t: +A:10110:f: +A:10111:i: +A:11100:s: +A:000110:u: +A:000111:STOP: +A:101001:R: +A:111010:b: +A:1010001:v: +A:1110110:p: +A:10100000:S: +A:11101110:M: +A:101000011:P: +A:111011111:.: +A:10100001000:e: +A:10100001001:B: +A:10100001010:1: +A:11101111011:-: +A:101000010110:k: +A:101000010111:h: +A:111011110000:a: +A:111011110100:y: +A:111011110101:*: +A:1110111100010:x: +A:1110111100011:': +A:1110111100100:N: +A:1110111100110:2: +A:11101111001010:0x3a: +A:11101111001111:z: +A:111011110010110:L: +A:111011110010111:F: +A:111011110011100:D: +A:1110111100111010:ESCAPE: +A:1110111100111011:q: +B:00:C: +B:01:B: +B:101:r: +B:1001:i: +B:1100:o: +B:1101:u: +B:1110:a: +B:1111:e: +B:10001:l: +B:1000000:STOP: +B:1000010:y: +B:10000010:O: +B:10000110:3: +B:100000111:A: +B:100001110:S: +B:1000001101:0x3a: +B:10000011000:.: +B:10000011001:w: +B:10000111101:h: +B:10000111110:*: +B:10000111111: : +B:100001111001:R: +B:1000011110000:': +B:10000111100011:T: +B:100001111000100:ESCAPE: +B:100001111000101:4: +C:00:o: +C:01: : +C:100:l: +C:110:h: +C:1010:r: +C:1110:a: +C:10110:i: +C:10111:e: +C:111100:u: +C:111101:B: +C:1111100:y: +C:1111110:!: +C:11111011:.: +C:111110100:w: +C:111111100:STOP: +C:111111110:S: +C:111111111:T: +C:1111101011:2: +C:1111111011:I: +C:11111010100:4: +C:11111010101:*: +C:11111110101:D: +C:111111101000:U: +C:1111111010010:': +C:11111110100110:n: +C:111111101001110:z: +C:11111110100111100:O: +C:11111110100111101:E: +C:11111110100111110:A: +C:111111101001111110:ESCAPE: +C:111111101001111111:s: +D:01:o: +D:10:a: +D:000:r: +D:110:e: +D:111:i: +D:00100:t: +D:00111:u: +D:001011: : +D:0010101:J: +D:0011000:y: +D:0011010:STOP: +D:0011011:I: +D:00110011:0x3a: +D:001010001:*: +D:001010010:-: +D:001010011:&: +D:001100100:': +D:0010100000:A: +D:0010100001:h: +D:00110010101:N: +D:00110010110:V: +D:001100101110:D: +D:001100101111:w: +D:0011001010000:O: +D:0011001010001:E: +D:0011001010011:d: +D:00110010100100:ESCAPE: +D:00110010100101:T: +E:00:m: +E:011:v: +E:101:n: +E:111:a: +E:0100:E: +E:1000:STOP: +E:1101:x: +E:10011:d: +E:11001:l: +E:010100:4: +E:010101:y: +E:010110:u: +E:100100:r: +E:110000:i: +E:0101111:s: +E:1001010:F: +E:1100010:X: +E:10010110:R: +E:11000111: : +E:010111010:g: +E:100101111:0x3a: +E:110001100:T: +E:110001101:': +E:0101110001:c: +E:0101110011:q: +E:0101110110:e: +E:0101110111:C: +E:1001011100:p: +E:01011100000:-: +E:01011100101:Z: +E:10010111011:t: +E:010111000010:S: +E:010111000011:.: +E:100101110101:W: +E:0101110010000:!: +E:1001011101000:o: +E:01011100100010:f: +E:01011100100011:U: +E:01011100100100:N: +E:01011100100101:M: +E:01011100100110:L: +E:01011100100111:A: +E:10010111010011:D: +E:100101110100100:ESCAPE: +E:100101110100101:w: +F:00:i: +F:10:a: +F:011:r: +F:110:u: +F:111:o: +F:0100:e: +F:01011:l: +F:0101000:A: +F:0101010:O: +F:01010010: : +F:010100110:h: +F:010100111:t: +F:010101101:f: +F:010101111:L: +F:0101011001:STOP: +F:01010111000:j: +F:01010111001:I: +F:01010111010:.: +F:01010111011:1: +F:010101100000:M: +F:010101100010:*: +F:010101100011:K: +F:0101011000010:y: +F:01010110000111:H: +F:010101100001100:ESCAPE: +F:010101100001101:!: +G:10:r: +G:001:M: +G:010:a: +G:011:o: +G:110:i: +G:111:e: +G:00001:u: +G:00010:X: +G:000001:h: +G:000111:l: +G:0000001:y: +G:0001100:w: +G:00000000:0x3a: +G:00011011:C: +G:000000011:STOP: +G:000110100:-: +G:0001101010:P: +G:0001101011: : +G:00000001000:': +G:00000001010:A: +G:000000010010:U: +G:000000010110:T: +G:000000010111:4: +G:0000000100110:ESCAPE: +G:0000000100111:Y: +H:0:o: +H:100:a: +H:101:i: +H:110:e: +H:1110:u: +H:11110:R: +H:111110:A: +H:1111110:.: +H:111111101:y: +H:111111110:S: +H:1111111110:E: +H:1111111111:r: +H:11111110000:STOP: +H:11111110010:L: +H:11111110011:M: +H:111111100011:w: +H:1111111000101:D: +H:11111110001000:ESCAPE: +H:11111110001001:I: +I:0:T: +I:100:s: +I:101:n: +I:1101:t: +I:11001: : +I:11101:': +I:11111:r: +I:110000:I: +I:110001:STOP: +I:111001:m: +I:1110000:d: +I:1110001:N: +I:1111001:z: +I:1111010:.: +I:11110000:a: +I:11110001:Y: +I:111101100:S: +I:111101110:c: +I:11110110101:D: +I:11110110110:f: +I:11110111100:l: +I:11110111111:y: +I:111101101000:V: +I:111101101110:o: +I:111101111011:F: +I:1111011010010:,: +I:1111011010011:A: +I:1111011011110:O: +I:1111011110101:g: +I:1111011111000:C: +I:1111011111001:0x3a: +I:1111011111011:v: +I:11110110111110:p: +I:11110110111111:E: +I:11110111101000:B: +I:11110111110100:k: +I:11110111110101:b: +I:1111011110100100:ESCAPE: +I:1111011110100101:R: +I:1111011110100110:L: +I:1111011110100111:G: +J:00:a: +J:01:u: +J:11:e: +J:101:o: +J:1001:i: +J:10000: : +J:100010:K: +J:1000111:STOP: +J:100011001:s: +J:100011010:F: +J:1000110000:V: +J:1000110001:': +J:1000110111:f: +J:10001101101:G: +J:100011011000:ESCAPE: +J:100011011001:D: +K:01:i: +K:11:y: +K:001:e: +K:101: : +K:0000:a: +K:1000:o: +K:00010:STOP: +K:00011:r: +K:100101:t: +K:100110:n: +K:100111:S: +K:10010011:G: +K:100100000:-: +K:100100011:O: +K:100100100:h: +K:100100101:w: +K:1001000010:1: +K:1001000011:': +K:10010001011:u: +K:100100010000:T: +K:100100010001:N: +K:100100010010:0x3a: +K:100100010011:.: +K:100100010100:,: +K:1001000101010:ESCAPE: +K:1001000101011:l: +L:00:a: +L:10:o: +L:11:i: +L:010:e: +L:0111:u: +L:01101:K: +L:0110000:l: +L:0110010:A: +L:0110011: : +L:01100011:y: +L:0110001000:L: +L:0110001001:I: +L:01100010100:C: +L:01100010101:.: +L:01100010111:STOP: +L:011000101101:': +L:0110001011000:E: +L:01100010110010:ESCAPE: +L:01100010110011:Y: +M:01:a: +M:10:o: +M:000:e: +M:111:i: +M:0010:T: +M:1100:y: +M:1101:u: +M:00110:STOP: +M:001111:c: +M:00111001:r: +M:00111010:E: +M:001110111:F: +M:0011100001:Z: +M:0011100011: : +M:0011101100:1: +M:0011101101:I: +M:00111000001:h: +M:00111000100:C: +M:001110000001:Q: +M:001110001010:K: +M:0011100010110:P: +M:00111000000000:0x3a: +M:00111000000001:.: +M:00111000000010:': +M:00111000101110:M: +M:001110000000110:ESCAPE: +M:001110000000111:w: +M:001110001011110:S: +M:001110001011111:R: +N:1:e: +N:00:o: +N:011:i: +N:0101:a: +N:01001:u: +N:010000:C: +N:01000100:E: +N:01000110:F: +N:010001110:B: +N:010001111:H: +N:0100010110:Y: +N:01000101000:G: +N:01000101001:': +N:01000101011:I: +N:01000101110:A: +N:010001010100:M: +N:010001011110: : +N:010001011111:STOP: +N:0100010101010:T: +N:01000101010110:.: +N:010001010101110:ESCAPE: +N:010001010101111:Z: +O:000:': +O:010:f: +O:110:u: +O:111:n: +O:0010:M: +O:0011:l: +O:1001:m: +O:01101:r: +O:01110:d: +O:10000:p: +O:10100:h: +O:10110:STOP: +O:011001:S: +O:011110:z: +O:011111:b: +O:100011:v: +O:101010:w: +O:101011:U: +O:1011100:T: +O:1011101:O: +O:1011110:K: +O:01100001:C: +O:01100010:x: +O:01100011:.: +O:10001001:t: +O:10001011: : +O:10111110:s: +O:10111111:N: +O:011000001:g: +O:100010000:-: +O:100010101:a: +O:1000100010:i: +O:1000100011:e: +O:1000101001:o: +O:01100000000:A: +O:01100000001:j: +O:01100000010:c: +O:10001010000:2: +O:011000000111:R: +O:100010100010:P: +O:100010100011:0x3a: +O:0110000001100:E: +O:01100000011010:ESCAPE: +O:01100000011011:L: +P:01:r: +P:10:l: +P:000:e: +P:001:a: +P:111:o: +P:1101:i: +P:110000:D: +P:110001:u: +P:110011:h: +P:11001000: : +P:11001010:2: +P:110010010:H: +P:110010011:M: +P:110010110:S: +P:11001011100:0x3a: +P:11001011101:*: +P:110010111101:s: +P:1100101111001:I: +P:1100101111100:STOP: +P:1100101111101:G: +P:1100101111110:': +P:11001011111110:y: +P:110010111100000:Y: +P:110010111100001:L: +P:110010111100010:C: +P:110010111100011:ESCAPE: +P:110010111111110:O: +P:110010111111111:.: +Q:1:u: +Q:000:I: +Q:001:STOP: +Q:010:V: +Q:0111: : +Q:01101:C: +Q:011000:ESCAPE: +Q:011001:': +R:00:a: +R:01:o: +R:11:e: +R:100:i: +R:1011:u: +R:10101:E: +R:101000:D: +R:1010011:STOP: +R:10100101:h: +R:1010010000:I: +R:1010010010:y: +R:1010010011:n: +R:101001000110: : +R:1010010001000:': +R:1010010001011:S: +R:1010010001110:N: +R:10100100010010:B: +R:10100100010011:.: +R:10100100010100:&: +R:10100100011110:T: +R:10100100011111:1: +R:101001000101010:ESCAPE: +R:101001000101011:C: +S:001:o: +S:010:p: +S:011:u: +S:110:h: +S:111:t: +S:0001:a: +S:1001:e: +S:1011:c: +S:00000:n: +S:10001:i: +S:10101:k: +S:000011:w: +S:101000:m: +S:0000101:A: +S:1000010:l: +S:1010010:q: +S:1010011:M: +S:00001000:2: +S:00001001:P: +S:10000000:O: +S:10000010:I: +S:10000011: : +S:10000111:STOP: +S:100000010:y: +S:100001100:E: +S:1000000111:?: +S:1000011011:H: +S:10000001100:B: +S:10000110100:g: +S:100000011011:r: +S:100001101010:*: +S:1000011010110:3: +S:1000011010111:.: +S:10000001101000:5: +S:10000001101010:0x3a: +S:10000001101011:1: +S:100000011010010:C: +S:1000000110100110:ESCAPE: +S:1000000110100111:Y: +T:0:h: +T:101:o: +T:111:V: +T:1000:e: +T:1001:r: +T:11000:a: +T:11010:w: +T:110011:i: +T:1101101:O: +T:1101111:H: +T:11001001:y: +T:11001010:M: +T:11011000:.: +T:11011100:u: +T:11011101:W: +T:110010001:P: +T:110010110:0x3a: +T:110010111:4: +T:110110011:I: +T:1101100100: : +T:1101100101:STOP: +T:11001000010:X: +T:11001000011:s: +T:110010000000:T: +T:110010000001:S: +T:110010000010:B: +T:1100100000110:U: +T:11001000001110:A: +T:1100100000111100:C: +T:1100100000111101:*: +T:1100100000111111:N: +T:11001000001111100:ESCAPE: +T:11001000001111101:Y: +U:0:n: +U:10:p: +U:1101:K: +U:1111:l: +U:11000:R: +U:11100:S: +U:110011:E: +U:111011:s: +U:1100101:g: +U:1110101:T: +U:11001001: : +U:110010000:-: +U:110010001:r: +U:111010000:2: +U:111010001:m: +U:111010011:STOP: +U:1110100100:.: +U:11101001010:c: +U:111010010110:k: +U:11101001011100:ESCAPE: +U:11101001011101:z: +U:11101001011110:t: +U:11101001011111:B: +V:1: : +V:000:0x3a: +V:011:i: +V:0010:e: +V:0011:a: +V:0100:3: +V:010101:C: +V:010111:STOP: +V:0101000:': +V:0101001:4: +V:0101101:o: +V:01011001:I: +V:0101100000:s: +V:0101100001:D: +V:0101100010:.: +V:01011000110:8: +V:0101100011101:u: +V:0101100011110:r: +V:0101100011111:B: +V:01011000111000:ESCAPE: +V:01011000111001:E: +W:01:o: +W:11:e: +W:001:h: +W:100:a: +W:101:i: +W:00000:.: +W:00010:O: +W:00011:r: +W:000011:y: +W:0000100:u: +W:00001010:STOP: +W:000010111:A: +W:00001011001:Y: +W:00001011010:T: +W:00001011011: : +W:000010110000:I: +W:0000101100010:ESCAPE: +W:0000101100011:l: +X:00:STOP: +X:10: : +X:11:t: +X:010:T: +X:0111:c: +X:01101:m: +X:011001:U: +X:01100000:a: +X:01100001:X: +X:01100010:-: +X:011000110:x: +X:0110001111:9: +X:01100011100:ESCAPE: +X:01100011101:i: +Y:1:o: +Y:01:e: +Y:000:u: +Y:0011: : +Y:00100:v: +Y:001010:a: +Y:00101110:P: +Y:00101111:': +Y:001011000:n: +Y:001011011:r: +Y:0010110010:D: +Y:00101100110:w: +Y:00101100111:s: +Y:00101101000:R: +Y:00101101001:L: +Y:00101101010:STOP: +Y:001011010110:C: +Y:0010110101110:ESCAPE: +Y:0010110101111:N: +Z:1:o: +Z:00:a: +Z:010:i: +Z:01100:O: +Z:01101:u: +Z:01110:e: +Z:011110: : +Z:0111111:STOP: +Z:01111101:0x3a: +Z:011111000:ESCAPE: +Z:011111001:-: +[:0:ESCAPE: +[:1:ESCAPE: +\:0:ESCAPE: +\:1:x: +]:0:ESCAPE: +]:1:ESCAPE: +^:0:ESCAPE: +^:1:ESCAPE: +_:0:ESCAPE: +_:1:ESCAPE: +`:0:ESCAPE: +`:1:ESCAPE: +a:001:r: +a:011:t: +a:100:l: +a:110:n: +a:0001:m: +a:0100:c: +a:1010:s: +a:1110:y: +a:10110: : +a:10111:d: +a:11110:i: +a:11111:k: +a:000010:b: +a:000011:STOP: +a:010110:p: +a:010111:g: +a:0000000:e: +a:0000001:': +a:0000011:w: +a:0101001:u: +a:0101010:z: +a:0101011:v: +a:00000101:f: +a:01010001:h: +a:000001001:0x3a: +a:0000010000:!: +a:0101000000:o: +a:0101000001:x: +a:00000100010:-: +a:00000100011:a: +a:01010000101:.: +a:01010000110:N: +a:01010000111:,: +a:010100001000:q: +a:0101000010010:j: +a:01010000100111:?: +a:010100001001101:J: +a:0101000010011000:ESCAPE: +a:0101000010011001:U: +b:000:r: +b:001:o: +b:010:e: +b:011:a: +b:100:i: +b:1011:u: +b:1100:y: +b:1101:l: +b:1111: : +b:10101:s: +b:11100:b: +b:11101:STOP: +b:101000:h: +b:1010010:3: +b:10100111:': +b:1010011001:t: +b:1010011010:j: +b:10100110000:n: +b:10100110001:d: +b:10100110111:w: +b:101001101101:m: +b:1010011011001:.: +b:10100110110000:ESCAPE: +b:10100110110001:0x3a: +c:00:k: +c:010:o: +c:100:h: +c:110:t: +c:111:e: +c:0111:r: +c:10100: : +c:10110:i: +c:10111:a: +c:011000:l: +c:011001:y: +c:011010:s: +c:011011:STOP: +c:1010100:c: +c:1010111:u: +c:10101010:0x3a: +c:10101011:P: +c:101011001:D: +c:1010110100:G: +c:1010110110:b: +c:10101100000:L: +c:10101100001:K: +c:10101100011:A: +c:10101101010:q: +c:10101101110:.: +c:10101101111:C: +c:101011000100:n: +c:101011000101:': +c:1010110101100:B: +c:1010110101101:I: +c:10101101011101:f: +c:10101101011110:8: +c:101011010111000:M: +c:101011010111001:ESCAPE: +c:101011010111111:F: +c:1010110101111100:w: +c:1010110101111101:Q: +d:11: : +d:001:e: +d:100:STOP: +d:101:a: +d:0001:y: +d:0100:i: +d:0110:s: +d:00000:o: +d:01010:d: +d:000011:u: +d:010110:r: +d:010111:l: +d:011101:v: +d:011110:g: +d:0000100:': +d:0111111:.: +d:00001010:0x3a: +d:00001011:h: +d:01110000:c: +d:01110010:n: +d:01110011:w: +d:011100010:?: +d:011111000:!: +d:011111001:-: +d:011111010:f: +d:0111000111:m: +d:0111110110:,: +d:01111101110:t: +d:01111101111:b: +d:011100011001:): +d:011100011010:/: +d:011100011011:k: +d:0111000110001:p: +d:01110001100001:z: +d:011100011000000:ESCAPE: +d:011100011000001:4: +e:01: : +e:000:s: +e:101:r: +e:0010:t: +e:1001:n: +e:1100:STOP: +e:1110:a: +e:1111:w: +e:10000:l: +e:11011:e: +e:001110:m: +e:100010:c: +e:100011:d: +e:0011010:i: +e:0011011:p: +e:0011110:b: +e:1101000:v: +e:1101011:y: +e:00110000:g: +e:00110001:f: +e:00110010:x: +e:00111110:k: +e:00111111:0x3a: +e:11010011:o: +e:11010100:': +e:001100111:h: +e:110100101:.: +e:0011001100:P: +e:0011001101:B: +e:1101001000:,: +e:1101010100:V: +e:1101010101:z: +e:1101010111:j: +e:11010010010:4: +e:11010010011:?: +e:11010101101:u: +e:110101011001:-: +e:1101010110001:!: +e:11010101100001:q: +e:110101011000001:G: +e:1101010110000000:ESCAPE: +e:1101010110000001:S: +f:0: : +f:101:o: +f:1001:t: +f:1100:a: +f:1101:i: +f:1111:e: +f:10000:.: +f:11100:r: +f:11101:f: +f:100010:STOP: +f:10001101:y: +f:10001111:u: +f:100011000:': +f:100011101:l: +f:1000110011:n: +f:1000111000:g: +f:10001100100:c: +f:10001110010:-: +f:100011001010:,: +f:100011001011:s: +f:100011100111:0x3a: +f:1000111001101:k: +f:10001110011000:ESCAPE: +f:10001110011001:b: +g:00:h: +g:10: : +g:010:STOP: +g:011:e: +g:1100:i: +g:11100:0x3a: +g:11101:r: +g:11111:a: +g:110100:s: +g:110111:l: +g:111101:u: +g:1101011:b: +g:1101100:g: +g:1101101:o: +g:1111001:n: +g:11010100:2: +g:11110000:!: +g:111100011:d: +g:1101010100:.: +g:1101010101:,: +g:1101010110:': +g:1101010111:t: +g:1111000101:y: +g:11110001000:w: +g:111100010011:m: +g:11110001001011:?: +g:111100010010000:p: +g:111100010010001:f: +g:111100010010010:@: +g:111100010010011:-: +g:111100010010101:;: +g:1111000100101000:ESCAPE: +g:1111000100101001:z: +h:0:e: +h:101:o: +h:1001:i: +h:1100:a: +h:1110: : +h:1111:t: +h:11010:r: +h:11011:STOP: +h:100000:b: +h:100001:u: +h:10001000:w: +h:10001001:d: +h:10001010:n: +h:10001011:y: +h:10001100:!: +h:10001101:l: +h:10001111:.: +h:100011100:': +h:1000111010:s: +h:10001110110:m: +h:100011101111:0x3a: +h:10001110111000:f: +h:10001110111001:?: +h:10001110111010:c: +h:1000111011101100:v: +h:1000111011101101:q: +h:1000111011101110:g: +h:100011101110111100:h: +h:100011101110111101:ESCAPE: +h:100011101110111110:,: +h:100011101110111111:*: +i:01:n: +i:000:c: +i:1001:o: +i:1010:l: +i:1100:g: +i:1101:s: +i:1110:t: +i:1111:e: +i:00101:a: +i:00110:v: +i:10000:r: +i:10001:d: +i:10110:m: +i:001000:p: +i:001110: : +i:101111:f: +i:0011110:z: +i:0011111:STOP: +i:1011100:b: +i:1011101:k: +i:00100101:-: +i:00100110:x: +i:001001001:': +i:001001111:q: +i:0010011100:u: +i:0010011101:i: +i:00100100001:h: +i:00100100010:0x3a: +i:00100100011:w: +i:0010010000001:,: +i:0010010000010:y: +i:0010010000011:/: +i:00100100000000:.: +i:001001000000010:ESCAPE: +i:001001000000011:j: +j:0:y: +j:11:o: +j:101:e: +j:1001:a: +j:10001:u: +j:100001:i: +j:1000000:STOP: +j:10000010:ESCAPE: +j:10000011: : +k:00: : +k:10:e: +k:010:i: +k:110:STOP: +k:0110:y: +k:0111:s: +k:1111:f: +k:111001:a: +k:111010:l: +k:1110001:0x3a: +k:1110110:k: +k:11100000:': +k:11101111:.: +k:111000011:w: +k:111011100:o: +k:1110000101:h: +k:11100001000:b: +k:11100001001:,: +k:11101110111:n: +k:111011101010:?: +k:111011101100:m: +k:111011101101:!: +k:1110111010010:u: +k:1110111010011:c: +k:1110111010110:d: +k:1110111010111:t: +k:11101110100001:j: +k:11101110100010:-: +k:111011101000000:p: +k:111011101000001:/: +k:111011101000111:S: +k:1110111010001100:ESCAPE: +k:1110111010001101:r: +l:01:e: +l:000:l: +l:101:a: +l:0011:y: +l:1000:STOP: +l:1001:d: +l:1100:o: +l:1110:i: +l:1111: : +l:00100:u: +l:11010:s: +l:001010:t: +l:001011:m: +l:1101101:k: +l:11011000:f: +l:11011100:b: +l:11011110:': +l:11011111:c: +l:110110011:v: +l:110111010:0x3a: +l:1101100101:.: +l:1101110110:w: +l:11011001000:z: +l:11011101111:p: +l:110110010010:h: +l:110110010011:*: +l:1101110111000:g: +l:1101110111001:,: +l:11011101110100:r: +l:11011101110101:n: +l:11011101110111:-: +l:110111011101100:!: +l:1101110111011011:?: +l:11011101110110101:C: +l:110111011101101000:ESCAPE: +l:110111011101101001:j: +m:10:e: +m:001:m: +m:011: : +m:111:a: +m:0000:i: +m:0001:STOP: +m:0100:y: +m:1101:p: +m:01010:b: +m:11000:o: +m:110010:n: +m:110011:s: +m:0101100:l: +m:0101110:f: +m:01011010:0x3a: +m:01011110:4: +m:010110110:h: +m:010111110:w: +m:0101101111:': +m:0101111110:r: +m:0101111111:u: +m:01011011101:.: +m:010110111001:k: +m:0101101110000:ESCAPE: +m:0101101110001:d: +n:000:i: +n:100:g: +n:101: : +n:110:d: +n:0011:a: +n:0100:s: +n:0110:e: +n:1110:STOP: +n:1111:t: +n:01110:c: +n:01111:n: +n:001010:y: +n:010100:': +n:010101:k: +n:010111:o: +n:0010000:r: +n:0010011:f: +n:0010110:u: +n:0010111:j: +n:00100010:v: +n:00100100:-: +n:00100101:.: +n:01011000:l: +n:01011010:x: +n:01011011:0x3a: +n:001000111:,: +n:010110011:m: +n:0010001100:!: +n:00100011010:z: +n:01011001001:?: +n:01011001010:h: +n:01011001011:b: +n:001000110110:B: +n:001000110111:*: +n:010110010000:w: +n:0101100100011:q: +n:01011001000101:p: +n:010110010001000:;: +n:0101100100010010:/: +n:0101100100010011:ESCAPE: +o:00:r: +o:110:n: +o:0100:f: +o:0101: : +o:0110:w: +o:1000:o: +o:1011:u: +o:01111:t: +o:10010:c: +o:10100:p: +o:10101:d: +o:11100:m: +o:11110:l: +o:011100:a: +o:011101:b: +o:100110:y: +o:100111:STOP: +o:111010:s: +o:111011:k: +o:1111101:v: +o:1111110:g: +o:11111111:i: +o:111110001:h: +o:111110010:!: +o:111111100:e: +o:111111101:j: +o:1111100110:': +o:11111000001:?: +o:11111000010:0x3a: +o:11111001110:z: +o:11111001111:x: +o:111110000000:J: +o:111110000110:.: +o:111110000111:-: +o:11111000000100:4: +o:11111000000110:,: +o:11111000000111:G: +o:111110000001011:): +o:1111100000010100:S: +o:11111000000101010:D: +o:111110000001010110:ESCAPE: +o:111110000001010111:q: +p:00:e: +p:010:STOP: +p:100:i: +p:110:o: +p:0110:s: +p:1010: : +p:1110:p: +p:01110:l: +p:01111:r: +p:10110:h: +p:11110:a: +p:101110:t: +p:101111:': +p:1111100:d: +p:1111101:m: +p:1111110:y: +p:111111101:0x3a: +p:111111111:!: +p:1111111100:w: +p:1111111101:u: +p:11111110000:b: +p:11111110010:-: +p:11111110011:.: +p:111111100011:n: +p:1111111000101:k: +p:11111110001001:,: +p:111111100010000:ESCAPE: +p:111111100010001:c: +q:1:u: +q:01:STOP: +q:001:0x3a: +q:0000:ESCAPE: +q:0001:': +r:000: : +r:011:i: +r:101:e: +r:0011:y: +r:0100:d: +r:1000:s: +r:1001:t: +r:1100:a: +r:1101:STOP: +r:1111:o: +r:01011:n: +r:11101:l: +r:001001:k: +r:001010:r: +r:001011:m: +r:010101:u: +r:111001:g: +r:0010000:': +r:0101001:c: +r:1110001:0x3a: +r:00100010:f: +r:00100011:.: +r:01010001:b: +r:11100000:v: +r:010100000:,: +r:010100001:p: +r:111000010:w: +r:1110000111:j: +r:11100001100:-: +r:111000011010:h: +r:1110000110110:G: +r:11100001101110:q: +r:111000011011111:S: +r:1110000110111100:!: +r:111000011011110100:*: +r:111000011011110110:T: +r:1110000110111101010:ESCAPE: +r:1110000110111101011:E: +r:1110000110111101110:1: +r:1110000110111101111:/: +s:10: : +s:11:STOP: +s:011:t: +s:0000:s: +s:0010:i: +s:0011:h: +s:00011:;: +s:01010:e: +s:010001:o: +s:010011:c: +s:010110:0x3a: +s:0001000:.: +s:0001001:!: +s:0001011:y: +s:0100000:p: +s:0100100:a: +s:0101111:u: +s:00010100:,: +s:00010101:f: +s:01000011:': +s:01001011:n: +s:01011100:l: +s:01011101:r: +s:010000101:k: +s:010010100:d: +s:0100001001:m: +s:0100101011:b: +s:01000010000:?: +s:01000010001:w: +s:01001010100:g: +s:010010101010:q: +s:01001010101101:E: +s:01001010101110:-: +s:010010101011000:ESCAPE: +s:010010101011001:): +s:010010101011110:W: +s:010010101011111:1: +t:000:i: +t:011:STOP: +t:100: : +t:111:h: +t:0010:a: +t:0100:r: +t:1010:s: +t:1011:o: +t:1101:e: +t:00111:t: +t:01010:y: +t:11000:u: +t:010110:m: +t:110010:c: +t:110011:l: +t:0011000:': +t:0011010:0x3a: +t:00110010:w: +t:00110110:!: +t:01011100:.: +t:01011101:b: +t:01011110:E: +t:01011111:f: +t:001100110:?: +t:001101110:n: +t:0011001110:z: +t:0011011110:d: +t:00110011111:,: +t:00110111110:P: +t:001100111100:v: +t:001100111101:-: +t:001101111110:): +t:0011011111110:g: +t:00110111111110:ESCAPE: +t:001101111111110:S: +t:0011011111111111:4: +t:00110111111111100:k: +t:001101111111111010:j: +t:001101111111111011:p: +u:00:r: +u:100:s: +u:111:n: +u:0100:e: +u:0101:m: +u:1100:t: +u:01100:c: +u:01101:g: +u:01110:b: +u:10100:p: +u:10101:i: +u:10110:l: +u:11010:d: +u:11011:a: +u:011110:STOP: +u:101110:y: +u:0111110:z: +u:1011110: : +u:01111111:': +u:10111110:-: +u:011111100:k: +u:101111111:0x3a: +u:0111111010:f: +u:0111111011:,: +u:1011111100:w: +u:101111110100:v: +u:101111110101:x: +u:101111110111:o: +u:1011111101100:j: +u:10111111011010:u: +u:101111110110110:.: +u:1011111101101111:h: +u:10111111011011100:?: +u:10111111011011101:ESCAPE: +v:1:e: +v:01:i: +v:001:a: +v:0001:o: +v:00000: : +v:000011:STOP: +v:0000100:y: +v:00001011:s: +v:000010101:r: +v:0000101000:ESCAPE: +v:0000101001:.: +w:0:s: +w:100: : +w:110:STOP: +w:1011:i: +w:1110:o: +w:10100:a: +w:11110:n: +w:11111:e: +w:1010111:y: +w:10101000:m: +w:10101011:d: +w:10101101:l: +w:101010011:b: +w:101010100:k: +w:101010101:r: +w:1010100100:j: +w:1010110001:,: +w:1010110011:h: +w:10101001011:-: +w:10101100000:c: +w:10101100001:f: +w:10101100101:p: +w:101010010100:g: +w:101011001000:t: +w:1010100101010:.: +w:1010100101011:0x3a: +w:1010110010011:q: +w:10101100100101:': +w:101011001001001:?: +w:1010110010010000:ESCAPE: +w:1010110010010001:B: +x:00:p: +x:10: : +x:11:t: +x:0110:STOP: +x:01000:o: +x:01010:c: +x:01110:i: +x:01111:m: +x:010010:e: +x:010110:y: +x:0100110:u: +x:0100111:f: +x:0101111:,: +x:010111000:g: +x:010111001:a: +x:010111011:9: +x:0101110101:': +x:01011101001:x: +x:010111010000:ESCAPE: +x:010111010001:s: +y:0: : +y:11:STOP: +y:10001:o: +y:10010:s: +y:10100:a: +y:10110:l: +y:10111:0x3a: +y:100110:d: +y:1000001:n: +y:1000010:t: +y:1010100:': +y:1010101:b: +y:1010111:.: +y:10000000:i: +y:10000110:,: +y:10000111:p: +y:10011100:m: +y:10011110:c: +y:10101100:w: +y:10101101:e: +y:100000010:?: +y:100000011:f: +y:100111010:r: +y:100111011:g: +y:1001111100:z: +y:1001111110:-: +y:1001111111:T: +y:100111110100:2: +y:100111110110:!: +y:100111110111:k: +y:1001111101010:v: +y:10011111010110:y: +y:100111110101110:h: +y:1001111101011111:j: +y:10011111010111100:ESCAPE: +y:10011111010111101:): +z:00:z: +z:01:STOP: +z:101:i: +z:1000:y: +z:1001:e: +z:1100:w: +z:1101: : +z:1110:l: +z:11110:a: +z:111110:o: +z:11111100:m: +z:11111101:0x3a: +z:11111111:c: +z:111111100:,: +z:1111111011:b: +z:11111110100:u: +z:111111101011:!: +z:11111110101000:ESCAPE: +z:11111110101001:t: +z:11111110101010:h: +z:11111110101011:?: +{:0:ESCAPE: +{:1:ESCAPE: +|:0:ESCAPE: +|:1:ESCAPE: +}:0:ESCAPE: +}:1:ESCAPE: +~:0:ESCAPE: +~:1:ESCAPE: +0x7f:0:ESCAPE: +0x7f:1:ESCAPE: diff --git a/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/Resources/Huffman Dictionary Freesat T2.cfg b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/Resources/Huffman Dictionary Freesat T2.cfg new file mode 100644 index 0000000..3617a76 --- /dev/null +++ b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/Resources/Huffman Dictionary Freesat T2.cfg @@ -0,0 +1,3160 @@ +START:010:A: +START:100:C: +START:111:T: +START:0001:J: +START:0011:D: +START:1010:S: +START:00000:H: +START:00100:I: +START:00101:R: +START:01101:F: +START:01110:.: +START:01111:W: +START:10111:M: +START:11000:B: +START:11001:P: +START:11011:N: +START:000010:O: +START:011001:[: +START:101101:L: +START:110101:E: +START:0000110:K: +START:1101000:Y: +START:1101001:G: +START:00001110:2: +START:01100000:p: +START:01100001:b: +START:01100010:U: +START:01100011:(: +START:10110000:1: +START:10110011:V: +START:000011110:Q: +START:101100010:3: +START:0000111110:9: +START:0000111111:8: +START:1011000110:6: +START:1011000111:5: +START:1011001000:Z: +START:1011001001:7: +START:1011001010:4: +START:101100101110:X: +START:101100101111: : +START:1011001011001:w: +START:1011001011010:': +START:1011001011011:": +START:10110010110000:t: +START:101100101100010:a: +START:1011001011000110:`: +START:10110010110001110:ESCAPE: +START:10110010110001111:m: +ESCAPE:0:ESCAPE: +ESCAPE:1:ESCAPE: +STOP:0:ESCAPE: +STOP:1:ESCAPE: +0x03:0:ESCAPE: +0x03:1:ESCAPE: +0x04:0:ESCAPE: +0x04:1:ESCAPE: +0x05:0:ESCAPE: +0x05:1:ESCAPE: +0x06:0:ESCAPE: +0x06:1:ESCAPE: +0x07:0:ESCAPE: +0x07:1:ESCAPE: +0x08:0:ESCAPE: +0x08:1:ESCAPE: +0x09:0:ESCAPE: +0x09:1:ESCAPE: +0x0a:0:ESCAPE: +0x0a:1:ESCAPE: +0x0b:0:ESCAPE: +0x0b:1:ESCAPE: +0x0c:0:ESCAPE: +0x0c:1:ESCAPE: +0x0d:0:ESCAPE: +0x0d:1:ESCAPE: +0x0e:0:ESCAPE: +0x0e:1:ESCAPE: +0x0f:0:ESCAPE: +0x0f:1:ESCAPE: +0x10:0:ESCAPE: +0x10:1:ESCAPE: +0x11:0:ESCAPE: +0x11:1:ESCAPE: +0x12:0:ESCAPE: +0x12:1:ESCAPE: +0x13:0:ESCAPE: +0x13:1:ESCAPE: +0x14:0:ESCAPE: +0x14:1:ESCAPE: +0x15:0:ESCAPE: +0x15:1:ESCAPE: +0x16:0:ESCAPE: +0x16:1:ESCAPE: +0x17:0:ESCAPE: +0x17:1:ESCAPE: +0x18:0:ESCAPE: +0x18:1:ESCAPE: +0x19:0:ESCAPE: +0x19:1:ESCAPE: +0x1a:0:ESCAPE: +0x1a:1:ESCAPE: +0x1b:0:ESCAPE: +0x1b:1:ESCAPE: +0x1c:0:ESCAPE: +0x1c:1:ESCAPE: +0x1d:0:ESCAPE: +0x1d:1:ESCAPE: +0x1e:0:ESCAPE: +0x1e:1:ESCAPE: +0x1f:0:ESCAPE: +0x1f:1:ESCAPE: + :010:a: + :100:t: + :0001:o: + :0010:s: + :00110:d: + :01100:[: + :01111:p: + :10101:b: + :11001:c: + :11010:h: + :11100:w: + :11101:i: + :11111:f: + :000000:A: + :000011:M: + :001111:e: + :011100:B: + :011101:C: + :101000:T: + :101101:S: + :101110:g: + :110000:r: + :110110:n: + :110111:l: + :111101:m: + :0000011:v: + :0000100:G: + :0000101:N: + :0011101:y: + :0110101:H: + :0110111:L: + :1010010:J: + :1010011:F: + :1011001:R: + :1011110:u: + :1100010:D: + :1100011:W: + :1111001:P: + :00000100:k: + :00000101:O: + :01101000:-: + :01101101:1: + :10110001:K: + :10111110:j: + :11110000:I: + :11110001:E: + :001110010:q: + :001110011:U: + :011010010:V: + :011011000:Y: + :011011001: : + :101100001:2: + :101111110:STOP: + :0011100000:3: + :0011100001:8: + :0011100010:6: + :0110100111:5: + :1011000000:(: + :1011111110:7: + :00111000110:0: + :01101001100:': + :01101001101:9: + :10110000010:Z: + :10111111110:4: + :10111111111:Q: + :001110001111:X: + :1011000001100:ESCAPE: + :1011000001101:.: + :1011000001110:&: + :00111000111000:\: + :00111000111010:@: + :00111000111011:`: + :10110000011110:": + :10110000011111:z: + :001110001110011:$: + :0011100011100100:+: + :00111000111001011:x: + :001110001110010101:]: + :0011100011100101000:/: + :0011100011100101001:?: +!:1: : +!:01:STOP: +!:001:.: +!:0000:0x3a: +!:00011:[: +!:0001001:": +!:0001010:/: +!:0001011:!: +!:00010000:): +!:000100010:': +!:0001000111:?: +!:00010001100:ESCAPE: +!:00010001101:]: +":11: : +":001:.: +":0000:p: +":0101:B: +":0111:T: +":1000:i: +":00010:f: +":00011:W: +":01000:S: +":01100:t: +":01101:C: +":10100:STOP: +":10111:,: +":010010:J: +":100100:m: +":101010:n: +":101011:I: +":0100110:E: +":0100111:D: +":1001010:w: +":1001011:g: +":1001100:b: +":1001101:L: +":1001110:-: +":1011000:c: +":1011001:H: +":10011110:P: +":10110100:r: +":10110111:K: +":100111111:l: +":101101010:Y: +":101101011:Q: +":101101100:G: +":101101101:A: +":1001111100:ESCAPE: +":1001111101:a: +#:0:ESCAPE: +#:1:ESCAPE: +$:0:1: +$:11:3: +$:100:4: +$:1011:2: +$:10101:7: +$:101001:5: +$:1010000:ESCAPE: +$:1010001:9: +%:1: : +%:00:ESCAPE: +%:01:,: +&:1: : +&:01:w: +&:001:B: +&:0000:E: +&:000100:2: +&:000110:A: +&:000111:R: +&:00010100:O: +&:00010101:4: +&:00010111:J: +&:000101100:ESCAPE: +&:000101101:P: +':1:s: +':001:t: +':010: : +':0000:l: +':01101:r: +':000100:n: +':000101:.: +':000110:C: +':011000:B: +':011101:A: +':0111000:d: +':0111100:v: +':00011100:S: +':00011111:p: +':01100101:D: +':01111011:i: +':01111100:c: +':01111101:m: +':01111111:,: +':000111010:f: +':000111011:g: +':011001000:F: +':011001001:h: +':011001101:H: +':011001110:N: +':011100101:R: +':011100110:STOP: +':011100111:T: +':011110101:G: +':011111101:L: +':0001111000:o: +':0001111001:K: +':0001111011:a: +':0110011001:u: +':0110011111:O: +':0111001001:I: +':0111101000:w: +':0111101001:b: +':0111111001:e: +':00011110101:?: +':01100110000:E: +':01100110001:7: +':01110010000:P: +':000111101001:W: +':011001111001:0x3a: +':011001111010:!: +':011100100011:J: +':011111100001:q: +':011111100011:M: +':0001111010001:V: +':0110011110001:9: +':0110011110111:y: +':0111001000100:8: +':0111001000101:5: +':0111111000000:6: +':0111111000101:k: +':00011110100000:2: +':00011110100001:0: +':01100111100001:Y: +':01100111101100:): +':01111110000010:j: +':01111110000011:Q: +':011001111000000:-: +':011001111000001:': +':011001111011011:z: +':011111100010000:X: +':011111100010001:U: +':011111100010010:4: +':011111100010011:3: +':0110011110110100:ESCAPE: +':0110011110110101:1: +(:01:1: +(:000:P: +(:101:t: +(:1000:2: +(:1101:5: +(:1110:N: +(:00111:T: +(:10010:p: +(:11111:c: +(:001001:a: +(:001010:S: +(:001100:R: +(:100111:e: +(:111100:J: +(:111101:A: +(:0010110:D: +(:0011011:K: +(:1001100:v: +(:1001101:s: +(:1100000:b: +(:1100010:G: +(:1100011:8: +(:1100100:M: +(:1100101:H: +(:1100110:C: +(:00100000:m: +(:00100010:o: +(:00100011:E: +(:00101110:W: +(:11000011:g: +(:11001110:L: +(:001000010:d: +(:001011111:U: +(:001101000:F: +(:001101010:f: +(:110000100:w: +(:110000101:B: +(:110011111:n: +(:0010000110:l: +(:0010000111:9: +(:0010111100:4: +(:0010111101:I: +(:0011010010:3: +(:0011010111:h: +(:1100111101:i: +(:00110100110:Z: +(:00110100111:V: +(:00110101100: : +(:11001111000:k: +(:001101011011:O: +(:110011110010:': +(:0011010110100:ESCAPE: +(:0011010110101:u: +(:1100111100110:X: +(:1100111100111:7: +):0: : +):11:.: +):101:STOP: +):1001:,: +):10000:0x3a: +):100011:;: +):1000101:!: +):10001001:(: +):1000100000:ESCAPE: +):1000100001:o: +):1000100010:?: +):1000100011:): +*:0:*: +*:100:s: +*:101: : +*:1100:m: +*:1110:t: +*:11010:g: +*:11011:k: +*:11111:d: +*:111101:y: +*:1111001:e: +*:11110000:i: +*:111100010:ESCAPE: +*:111100011:n: ++:1:n: ++:00:ESCAPE: ++:01: : +,:1: : +,:01:S: +,:001:0: +,:0001:A: +,:00000:5: +,:0000110:b: +,:0000111:3: +,:00001000:2: +,:00001001:": +,:00001011:1: +,:0000101000:Q: +,:0000101010:': +,:00001010111:4: +,:000010100100:T: +,:000010100101:B: +,:000010100110:7: +,:000010100111:6: +,:000010101100:STOP: +,:0000101011010:ESCAPE: +,:0000101011011:i: +-:00: : +-:0100:t: +-:0101:b: +-:0110:w: +-:0111:u: +-:1001:o: +-:1010:s: +-:1011:f: +-:10000:c: +-:11011:l: +-:11101:d: +-:100010:9: +-:110000:h: +-:110010:1: +-:110011:y: +-:110101:r: +-:111000:a: +-:111100:m: +-:111110:p: +-:1000110:S: +-:1101000:e: +-:1101001:i: +-:1111011:n: +-:10001110:C: +-:11000101:W: +-:11000111:g: +-:11100101:J: +-:11100110:D: +-:11110101:2: +-:11111100:7: +-:11111110:G: +-:11111111:O: +-:100011111:H: +-:110001000:A: +-:110001100:6: +-:110001101:B: +-:111001111:M: +-:111101000:E: +-:111101001:L: +-:111111010:U: +-:111111011:k: +-:1000111100:F: +-:1100010010:j: +-:1100010011:P: +-:1110010001:q: +-:1110010010:5: +-:1110010011:T: +-:1110011101:I: +-:10001111011:K: +-:11100100000:v: +-:11100100001:Z: +-:11100111001:N: +-:100011110101:R: +-:111001110001:Y: +-:1000111101001:0: +-:10001111010000:4: +-:10001111010001:z: +-:11100111000001:V: +-:11100111000010:3: +-:11100111000011:8: +-:111001110000001:Q: +-:1110011100000000:': +-:11100111000000010:ESCAPE: +-:11100111000000011:x: +.:1: : +.:01:STOP: +.:0011:.: +.:00010:i: +.:00100:0: +.:00101:c: +.:000001:u: +.:0000000:a: +.:0000001:[: +.:0001101:3: +.:00001000:4: +.:00001110:H: +.:00011000:S: +.:00011001:W: +.:00011100:o: +.:00011110:1: +.:000010100:5: +.:000010101:L: +.:000010111:p: +.:000011000:T: +.:000011001:A: +.:000011010:M: +.:000011110:C: +.:000011111:2: +.:000111011:D: +.:000111110:B: +.:0000100100:N: +.:0000100110:t: +.:0000100111:J: +.:0000101101:R: +.:0000110111:P: +.:0001110101:s: +.:0001111111:I: +.:00001011000:r: +.:00001101100:V: +.:00011101000:w: +.:00011101001:F: +.:00011111101:G: +.:000010010100:E: +.:000010010101:0x3a: +.:000010110010:h: +.:000011011010:,: +.:000111111000:': +.:0000100101101:b: +.:0000100101110:K: +.:0000100101111:Y: +.:0000101100111:O: +.:0000110110110:-: +.:0001111110010:f: +.:0001111110011:(: +.:00001011001100:": +.:00001101101110:y: +.:000010010110000:?: +.:000010010110001:m: +.:000010010110010:Q: +.:000011011011110:*: +.:000011011011111:&: +.:0000100101100110:U: +.:0000100101100111:;: +.:0000101100110100:8: +.:0000101100110101:6: +.:0000101100110111:k: +.:00001011001101100:d: +.:000010110011011010:ESCAPE: +.:000010110011011011:n: +/:01:c: +/:110:1: +/:111:e: +/:0000:5: +/:0010:8: +/:00010:T: +/:00011:f: +/:00110:B: +/:00111:2: +/:10001:3: +/:10010:7: +/:10100:6: +/:10110:a: +/:101111:4: +/:1000000:F: +/:1000010:s: +/:1000011:M: +/:1001100:H: +/:1001110:D: +/:1001111:A: +/:1010101:S: +/:10000011:m: +/:10011010:W: +/:10101000:G: +/:10101001:U: +/:10101100:d: +/:10101101:O: +/:10101110:N: +/:10111001:C: +/:10111011:P: +/:100110110:L: +/:101011110: : +/:101011111:I: +/:101110000:E: +/:101110001:R: +/:101110100:K: +/:101110101:t: +/:1000001001:J: +/:1000001011:9: +/:10000010000:v: +/:10000010001:p: +/:10000010100:h: +/:10011011101:o: +/:10011011110:Q: +/:10011011111:0: +/:100000101010:l: +/:100000101011:i: +/:100110111000:V: +/:1001101110011:y: +/:10011011100100:ESCAPE: +/:10011011100101:g: +0:0:0: +0:111: : +0:1001:a: +0:1011:p: +0:10001:s: +0:11000:.: +0:11001:8: +0:11011:,: +0:100000:4: +0:100001:t: +0:101001:5: +0:110100:6: +0:1010000:3: +0:1010001:7: +0:1010101:]: +0:1010110:-: +0:1010111:1: +0:10101000:): +0:10101001:/: +0:11010100:STOP: +0:11010101:9: +0:11010111:2: +0:110101100:%: +0:1101011010:0x3a: +0:110101101101:f: +0:110101101111:m: +0:1101011011100:y: +0:11010110110001:l: +0:11010110110010:;: +0:11010110110011:': +0:11010110111010:k: +0:11010110111011:!: +0:110101101100000:C: +0:1101011011000010:ESCAPE: +0:1101011011000011:J: +1:00:9: +1:100:1: +1:111:0: +1:0101: : +1:0111:2: +1:1011:.: +1:1100:5: +1:01000:6: +1:01001:8: +1:01101:/: +1:10100:]: +1:11010:3: +1:011001:7: +1:110110:4: +1:0110000:STOP: +1:0110001:-: +1:1010100:): +1:1010110:0x3a: +1:1010111:s: +1:1101110:,: +1:1101111:x: +1:10101010:': +1:101010110:X: +1:10101011110:t: +1:10101011111:R: +1:101010111011:;: +1:1010101110000:p: +1:1010101110001:m: +1:1010101110010:!: +1:1010101110101:&: +1:10101011100110:e: +1:101010111001110:b: +1:101010111001111:a: +1:101010111010000:D: +1:101010111010001:C: +1:101010111010010:%: +1:1010101110100110:ESCAPE: +1:1010101110100111:o: +2:11:0: +2:000: : +2:010:.: +2:100:5: +2:0011:/: +2:1011:,: +2:00100:]: +2:00101:p: +2:01101:1: +2:10101:4: +2:011000:6: +2:011001:2: +2:011100:0x3a: +2:011101:-: +2:011111:): +2:1010000:STOP: +2:1010010:8: +2:1010011:9: +2:01111000:D: +2:01111001:3: +2:01111010:t: +2:01111011:7: +2:10100010:n: +2:101000110:a: +2:1010001110:': +2:10100011111:;: +2:101000111100:s: +2:1010001111010:": +2:101000111101100:ESCAPE: +2:101000111101101:i: +2:101000111101110:W: +2:101000111101111:L: +3:00: : +3:10:0: +3:110:.: +3:1110:/: +3:01000:2: +3:01001:1: +3:01010:): +3:01100:0x3a: +3:01110:-: +3:11111:]: +3:010110:D: +3:011010:4: +3:011011:STOP: +3:011111:5: +3:111100:,: +3:0101110:7: +3:0101111:3: +3:0111101:6: +3:1111011:t: +3:01111001:B: +3:11110100:8: +3:111101010:9: +3:0111100001:;: +3:1111010110:r: +3:1111010111:s: +3:01111000000:n: +3:01111000101:b: +3:01111000110:': +3:01111000111:A: +3:011110000010:p: +3:011110000011:e: +3:0111100010000:a: +3:0111100010001:&: +3:0111100010010:%: +3:01111000100110:ESCAPE: +3:01111000100111:k: +4:01: : +4:000:4: +4:100:.: +4:110:0: +4:0010:/: +4:1010:5: +4:1011:-: +4:00110:1: +4:11101:]: +4:11110:,: +4:001110:2: +4:111001:8: +4:111110:): +4:0011110:0x3a: +4:0011111:': +4:1110000:t: +4:1110001:3: +4:1111111:STOP: +4:11111101:6: +4:1111110000:9: +4:1111110010:7: +4:11111100011:C: +4:11111100110:;: +4:111111000101:x: +4:1111110011101:m: +4:1111110011110:I: +4:11111100010000:f: +4:11111100010001:e: +4:11111100010010:b: +4:11111100010011:L: +4:11111100111000:%: +4:11111100111110:p: +4:11111100111111:c: +4:111111001110010:ESCAPE: +4:111111001110011:i: +5:00:0: +5:10: : +5:010:.: +5:0111:p: +5:1100:5: +5:01100:/: +5:11010:a: +5:11011:-: +5:11101:6: +5:011010:3: +5:111100:2: +5:111110:8: +5:111111:]: +5:0110110:0x3a: +5:1110000:): +5:1110001:s: +5:1110011:,: +5:1111010:7: +5:1111011:9: +5:01101110:4: +5:11100100:STOP: +5:11100101:t: +5:0110111110:c: +5:0110111111:1: +5:01101111001:;: +5:01101111011:m: +5:011011110000:e: +5:011011110001:': +5:011011110101:k: +5:0110111101001:l: +5:01101111010000:ESCAPE: +5:01101111010001:f: +6:00: : +6:10:.: +6:111:0: +6:0101:]: +6:01001:1: +6:01100:7: +6:01110:): +6:11000:,: +6:11001:0x3a: +6:11010:/: +6:010001:-: +6:011010:5: +6:011011:4: +6:011111:8: +6:110111:t: +6:0100000:6: +6:0111100:3: +6:0111101:2: +6:1101101:9: +6:01000010:STOP: +6:01000011:+: +6:11011000:': +6:1101100101:a: +6:1101100110:?: +6:11011001000:m: +6:11011001001:e: +6:11011001110:;: +6:1101100111100:f: +6:1101100111101:b: +6:1101100111110:M: +6:11011001111110:": +6:110110011111110:ESCAPE: +6:110110011111111:i: +7:11:.: +7:001: : +7:011:0: +7:101:-: +7:0000:8: +7:0100:7: +7:1001:]: +7:01010:/: +7:000101:6: +7:000110:2: +7:000111:1: +7:010111:t: +7:100000:9: +7:100010:): +7:100011:5: +7:0001001:3: +7:0101101:,: +7:1000010:a: +7:1000011:4: +7:00010000:STOP: +7:01011000:0x3a: +7:01011001:p: +7:0001000101:R: +7:0001000110:;: +7:00010001000:': +7:00010001111:m: +7:000100010011:f: +7:000100011100:A: +7:000100011101:?: +7:0001000100100:ESCAPE: +7:0001000100101:s: +8:01: : +8:000:4: +8:110:.: +8:0011:0: +8:1000:9: +8:1001:7: +8:1011:8: +8:1110:1: +8:00100:/: +8:10100:3: +8:11110:5: +8:101010:): +8:111110:6: +8:111111:]: +8:0010100:0x3a: +8:0010101:,: +8:1010111:t: +8:00101100:p: +8:00101101:-: +8:00101111:a: +8:10101100:c: +8:10101101:2: +8:001011101:STOP: +8:0010111001:;: +8:001011100000:l: +8:001011100001:': +8:0010111000100:f: +8:0010111000101:D: +8:0010111000110:A: +8:00101110001110:ESCAPE: +8:00101110001111:i: +9:000:5: +9:001:]: +9:111:9: +9:0101:0: +9:0110:.: +9:0111:-: +9:1000:4: +9:1001:8: +9:1011:6: +9:1100: : +9:1101:7: +9:01000:2: +9:10100:3: +9:010010:1: +9:010011:/: +9:101010:t: +9:1010111:): +9:10101100:0x3a: +9:101011010:,: +9:10101101100:p: +9:10101101101:;: +9:10101101111:STOP: +9:1010110111000:n: +9:1010110111001:m: +9:1010110111010:a: +9:10101101110111:e: +9:101011011101100:ESCAPE: +9:101011011101101:k: +0x3a:1: : +0x3a:01:0: +0x3a:001:3: +0x3a:00001:1: +0x3a:00010:T: +0x3a:00011:C: +0x3a:000001:4: +0x3a:0000000:ESCAPE: +0x3a:0000001:5: +;:0:ESCAPE: +;:1: : +<:0:ESCAPE: +<:1:ESCAPE: +=:0:ESCAPE: +=:1:ESCAPE: +>:0:ESCAPE: +>:1:ESCAPE: +?:1: : +?:01:STOP: +?:000:0x3a: +?:00100:!: +?:00110:[: +?:00111:.: +?:001010:;: +?:0010110:': +?:00101111:,: +?:001011101:/: +?:0010111000:ESCAPE: +?:0010111001:Q: +@:0:k: +@:10: : +@:111:T: +@:1101:b: +@:11000:ESCAPE: +@:11001:H: +A:01: : +A:110:D: +A:111:n: +A:0000:s: +A:0001:m: +A:0010:d: +A:1000:r: +A:1011:l: +A:00110:c: +A:10010:u: +A:10100:g: +A:001111:b: +A:100111:t: +A:101011:f: +A:1010100:w: +A:1010101:i: +A:10011001:v: +A:10011011:p: +A:001110010:h: +A:001110100:.: +A:001110111:B: +A:100110100:q: +A:0011100000:C: +A:0011100010:,: +A:0011100110:y: +A:0011101010:S: +A:0011101100:k: +A:0011101101:T: +A:1001100001:R: +A:1001100010:F: +A:1001100011:z: +A:1001101011:a: +A:00111000010:P: +A:00111000110:-: +A:00111010110:A: +A:00111010111:I: +A:10011000001:e: +A:10011010100:N: +A:10011010101:x: +A:001110000110:X: +A:001110000111:K: +A:001110001110:3: +A:001110001111:&: +A:001110011101:M: +A:001110011111:Y: +A:0011100111000:L: +A:0011100111001:W: +A:0011100111100:*: +A:1001100000000:o: +A:1001100000001:1: +A:1001100000010:': +A:1001100000011:0x3a: +A:00111001111010:j: +A:001110011110110:G: +A:0011100111101110:O: +A:00111001111011110:4: +A:001110011110111110:ESCAPE: +A:001110011110111111:E: +B:00:C: +B:010:a: +B:101:r: +B:110:e: +B:111:B: +B:0111:i: +B:1000:u: +B:1001:o: +B:01101:l: +B:01100000:T: +B:01100001:.: +B:01100011:y: +B:01100100:I: +B:01100110:h: +B:01100111: : +B:011000100:A: +B:0110001010:O: +B:01100010110:0x3a: +B:01100101000:&: +B:01100101001:3: +B:01100101010:j: +B:01100101011:M: +B:01100101110:D: +B:011000101111:W: +B:011001011000:*: +B:011001011010:,: +B:011001011011:1: +B:011001011110:ESCAPE: +B:011001011111:P: +B:0110001011100:E: +B:0110010110011:R: +B:01100010111011:w: +B:011000101110100:-: +B:011001011001001:U: +B:011001011001010:S: +B:011001011001011:F: +B:0110001011101010:X: +B:0110001011101011:V: +B:0110010110010000:Q: +B:0110010110010001:4: +C:00:h: +C:011:B: +C:100:a: +C:110:o: +C:0101:r: +C:1010:.: +C:1110: : +C:1111:l: +C:01000:': +C:10111:i: +C:010011:e: +C:101101:u: +C:0100101:y: +C:1011001:,: +C:01001001:I: +C:010010000:A: +C:1011000000:C: +C:1011000001:D: +C:1011000011:STOP: +C:1011000100:S: +C:1011000101:T: +C:1011000111:G: +C:01001000100:*: +C:01001000111:w: +C:10110001101:J: +C:010010001010:R: +C:010010001100:2: +C:010010001101:U: +C:101100001000:?: +C:101100001010:O: +C:101100001011:H: +C:101100011000:E: +C:0100100010110:z: +C:1011000010011:-: +C:1011000110011:s: +C:01001000101111:1: +C:10110000100101:!: +C:10110001100100:P: +C:010010001011101:n: +C:101100001001000:K: +C:101100001001001:7: +C:101100011001011:4: +C:0100100010111000:0x3a: +C:1011000110010100:F: +C:1011000110010101:): +C:01001000101110010:ESCAPE: +C:01001000101110011:b: +D:00:a: +D:01:,: +D:100:r: +D:101:o: +D:110:e: +D:1110:i: +D:111111:u: +D:1111001: : +D:1111011:': +D:11110000:.: +D:11110001:]: +D:11111010:y: +D:111101010:w: +D:111101011:W: +D:111110001:N: +D:111110010:C: +D:111110111:J: +D:1111010010:h: +D:1111100000:t: +D:1111100111:I: +D:1111101101:0x3a: +D:11110100001:M: +D:11110100010:&: +D:11110100011:V: +D:11111000010:-: +D:11111000011:G: +D:11111001100:O: +D:11111001101:A: +D:11111011001:S: +D:111101000000:F: +D:111101001100:*: +D:111101001101:s: +D:111101001111:d: +D:111110110000:v: +D:1111010011100:m: +D:1111010011101:j: +D:1111101100010:ESCAPE: +D:1111101100011:T: +D:11110100000110:9: +D:111101000001000:): +D:111101000001011:E: +D:111101000001110:8: +D:111101000001111:7: +D:1111010000010010:U: +D:1111010000010011:R: +D:1111010000010100:B: +D:1111010000010101:4: +E:000:p: +E:010:a: +E:011:n: +E:110:l: +E:1001:m: +E:1010:x: +E:1110:v: +E:1111:d: +E:00100:s: +E:00110:r: +E:00111:u: +E:10000:E: +E:10001: : +E:001010:.: +E:001011:i: +E:101101:0x3a: +E:1011000:y: +E:1011001:t: +E:1011100:g: +E:1011110:4: +E:101110110:w: +E:101111100:c: +E:101111110:b: +E:1011101010:R: +E:1011101011:F: +E:1011101111:C: +E:10111010001:k: +E:10111010010:f: +E:10111010011:o: +E:10111011100:U: +E:10111011101:L: +E:10111110101:e: +E:10111110110:N: +E:10111111100:h: +E:10111111101:I: +E:10111111111:D: +E:101111101000:M: +E:101111101111:': +E:101111111100:2: +E:101111111101:-: +E:1011101000011:q: +E:1011111010010:O: +E:1011111010011:A: +E:1011111011101:Z: +E:10111010000000:W: +E:10111010000001:S: +E:10111010000010:H: +E:10111010000011:9: +E:10111010000100:): +E:10111110111000:T: +E:10111110111001:,: +E:101110100001010:P: +E:1011101000010110:ESCAPE: +E:1011101000010111:z: +F:00:o: +F:10:r: +F:010:e: +F:110:i: +F:111:a: +F:0110:l: +F:01110:u: +F:0111100: : +F:0111101:O: +F:01111101:A: +F:01111111:B: +F:011111100:f: +F:0111110000:.: +F:0111110011:L: +F:01111100010:M: +F:01111100011:E: +F:01111100101:T: +F:01111110101:C: +F:01111110110:W: +F:011111001000:0x3a: +F:011111101000:U: +F:011111101001:': +F:011111101111:1: +F:0111110010010:y: +F:0111110010011:,: +F:01111110111000:-: +F:01111110111010:I: +F:011111101110011:h: +F:0111111011100100:*: +F:0111111011100101:K: +F:0111111011101100:F: +F:0111111011101101:ESCAPE: +F:01111110111011100:X: +F:01111110111011101:R: +F:01111110111011110:;: +F:01111110111011111:4: +G:00:r: +G:01:a: +G:101:o: +G:110:e: +G:1001:u: +G:1111:i: +G:10001:n: +G:11101:l: +G:100000:X: +G:1110000:y: +G:1110001: : +G:1110011:w: +G:10000101:4: +G:10000111:P: +G:11100101:h: +G:100001000:-: +G:100001100:C: +G:111001001:M: +G:1000011010:B: +G:1110010000:.: +G:1110010001:I: +G:10000100100:;: +G:10000100101:,: +G:10000100110:A: +G:10000100111:N: +G:10000110111:0x3a: +G:1000011011000:O: +G:1000011011001:L: +G:10000110110110:b: +G:100001101101000:K: +G:100001101101001:2: +G:100001101101010:1: +G:100001101101011:': +G:1000011011011100:ESCAPE: +G:1000011011011101:m: +G:1000011011011110:T: +G:1000011011011111:S: +H:00:e: +H:01:a: +H:10:o: +H:110:i: +H:1111:u: +H:11100:R: +H:1110100:P: +H:1110110:y: +H:11101011:I: +H:111011100:Q: +H:111011101:M: +H:111011110:A: +H:111011111: : +H:1110101000:S: +H:1110101001:.: +H:11101010101:G: +H:11101010110:): +H:111010101001:E: +H:1110101011100:O: +H:1110101011101:L: +H:11101010100000:1: +H:11101010100001:&: +H:11101010111100:H: +H:11101010111101:w: +H:11101010111110:v: +H:111010101000100:X: +H:111010101000101:W: +H:111010101000110:D: +H:111010101111110:s: +H:111010101111111:F: +H:1110101010001110:ESCAPE: +H:1110101010001111:r: +I:0:n: +I:110:t: +I:1001:s: +I:1111:r: +I:10000:T: +I:10101:a: +I:11100: : +I:100010:c: +I:101001:m: +I:101100:z: +I:101101:.: +I:101111:d: +I:111011:I: +I:1000111:': +I:1011101:l: +I:10100000:A: +I:10100001:v: +I:10111001:V: +I:11101001:f: +I:11101011:o: +I:100011001:C: +I:100011010:P: +I:101000100:w: +I:101000110:0x3a: +I:101110000:p: +I:111010000:R: +I:111010001:,: +I:111010101:Y: +I:1000110000:E: +I:1000110001:6: +I:1000110111:q: +I:1010001011:y: +I:1010001110:M: +I:1110101000:g: +I:1110101001:D: +I:10001101100:e: +I:10001101101:5: +I:10100010100:S: +I:10100010101:9: +I:10100011111:F: +I:10111000100:b: +I:10111000110:-: +I:10111000111:L: +I:101000111100:B: +I:101000111101:): +I:1011100010100:N: +I:1011100010101:Q: +I:1011100010110:k: +I:10111000101111:O: +I:101110001011101:?: +I:1011100010111000:ESCAPE: +I:1011100010111001:h: +J:00:e: +J:10:a: +J:11:o: +J:011:u: +J:0101:i: +J:01000: : +J:0100110:D: +J:0100111:.: +J:01001001:r: +J:010010110:s: +J:0100100000:M: +J:0100100010:J: +J:0100100011:,: +J:0100101000:B: +J:0100101001:-: +J:0100101010:V: +J:0100101110:K: +J:0100101111:T: +J:01001000010:C: +J:01001010110:n: +J:010010000110:!: +J:0100100001110:w: +J:0100100001111:R: +J:0100101011100:F: +J:0100101011110:7: +J:0100101011111:': +J:01001010111010:G: +J:010010101110110:ESCAPE: +J:010010101110111:L: +K:00:i: +K:01:a: +K:10:e: +K:1111:y: +K:11000:n: +K:11001:o: +K:11011:r: +K:11101: : +K:110100:': +K:111000:u: +K:1101011:.: +K:1110011:l: +K:11100101:h: +K:110101000:T: +K:110101011:G: +K:111001001:,: +K:1101010100:w: +K:11010100100:5: +K:11010100101:4: +K:11010100110:A: +K:11010101010:3: +K:11100100000:2: +K:11100100011:M: +K:110101001110:-: +K:110101010110:0x3a: +K:110101010111:!: +K:111001000010:): +K:111001000101:S: +K:1101010011110:V: +K:1110010000110:6: +K:1110010000111:1: +K:11010100111111:L: +K:11100100010000:I: +K:11100100010001:?: +K:110101001111100:ESCAPE: +K:110101001111101:v: +K:111001000100100:k: +K:111001000100101:Y: +K:111001000100110:N: +K:111001000100111:E: +L:00:i: +L:10:o: +L:011:]: +L:110:e: +L:111:a: +L:0100:u: +L:010100:l: +L:010101:A: +L:010111:y: +L:01011011: : +L:010110000:I: +L:010110001:R: +L:010110101:,: +L:0101100100:O: +L:0101100101:': +L:01011001101:.: +L:01011001110:C: +L:01011001111:Y: +L:01011010001:F: +L:01011010010:L: +L:010110011001:t: +L:010110100001:G: +L:010110100111:S: +L:0101100110001:h: +L:0101101000001:W: +L:0101101001100:J: +L:01011001100000:E: +L:01011010000001:": +L:01011010011011:STOP: +L:010110011000010:T: +L:010110011000011:P: +L:010110100000000:D: +L:010110100000001:7: +L:010110100110101:j: +L:0101101001101000:ESCAPE: +L:0101101001101001:U: +M:00:o: +M:11:a: +M:011:e: +M:101:i: +M:0101:c: +M:1001:u: +M:01001:y: +M:10001:r: +M:100000:S: +M:100001:P: +M:0100001: : +M:01000001:C: +M:01000110:F: +M:010000000:1: +M:010001000:h: +M:010001010:I: +M:010001110:T: +M:010001111:X: +M:0100000010:A: +M:0100010010:z: +M:01000100110:f: +M:01000101110:.: +M:010000001100:Z: +M:010000001101:K: +M:010000001110:B: +M:010001001111:s: +M:010001011000:R: +M:010001011001:W: +M:010001011010:O: +M:0100000011110:,: +M:0100000011111:': +M:0100010110111:D: +M:0100010111100:4: +M:0100010111110:E: +M:01000100111000:m: +M:01000100111001:J: +M:01000100111010:ESCAPE: +M:01000101111010:l: +M:01000101111011:-: +M:01000101111110:): +M:01000101111111:w: +M:010001001110110:t: +M:010001001110111:V: +M:010001011011000:Q: +M:010001011011001:N: +M:010001011011010:6: +M:010001011011011:2: +N:00:a: +N:10:o: +N:11:e: +N:011:i: +N:01010:u: +N:01011:E: +N:010010:A: +N:0100010:y: +N:0100110:g: +N:01000001:B: +N:01000010:I: +N:01000110:F: +N:01000111: : +N:010000000:): +N:010000001:': +N:010000111:Y: +N:010011100:L: +N:010011101:H: +N:0100001100:C: +N:0100111100:W: +N:0100111110:N: +N:0100111111:T: +N:010000110101:M: +N:010000110111:O: +N:010011110100:,: +N:010011110101:J: +N:010011110111:h: +N:0100001101000:D: +N:0100001101001:.: +N:0100111101100:X: +N:0100111101101:ESCAPE: +N:01000011011000:k: +N:01000011011001:Z: +N:01000011011010:Q: +N:01000011011011:G: +O:111:n: +O:0000:s: +O:0001:N: +O:0011:z: +O:0100:r: +O:1000:u: +O:1010:p: +O:1011:l: +O:1101:': +O:00101:U: +O:01011:h: +O:01110:f: +O:01111:w: +O:10010:.: +O:11000: : +O:001000:o: +O:001001:J: +O:010100:b: +O:010101:m: +O:011001:H: +O:011010:O: +O:011011:v: +O:100111:c: +O:110011:x: +O:1001101:d: +O:1100100:a: +O:01100001:t: +O:01100010:k: +O:10011000:g: +O:11001010:R: +O:011000000:K: +O:100110010:i: +O:110010111:V: +O:0110000011:2: +O:0110001101:S: +O:0110001110:B: +O:1001100110:W: +O:1001100111:-: +O:01100000100:,: +O:01100011000:j: +O:01100011001:L: +O:01100011111:I: +O:11001011001:A: +O:11001011011:C: +O:011000001010:0x3a: +O:011000111100:e: +O:110010110000:y: +O:110010110001:/: +O:110010110100:M: +O:0110000010110:!: +O:0110001111011:P: +O:1100101101011:F: +O:01100000101110:E: +O:01100000101111:D: +O:01100011110100:8: +O:01100011110101:4: +O:11001011010101:T: +O:110010110101000:ESCAPE: +O:110010110101001:q: +P:11:a: +P:000:i: +P:010:e: +P:011:l: +P:100:o: +P:101:r: +P:0010:h: +P:001111:u: +P:0011010:C: +P:0011100:.: +P:0011101: : +P:00110000:B: +P:00110010:D: +P:00110111:s: +P:001100011:O: +P:001100111:,: +P:0011000101:y: +P:0011001100:M: +P:0011011000:E: +P:0011011001:': +P:0011011011:3: +P:00110001001:T: +P:001100010000:L: +P:001100010001:G: +P:001100110100:*: +P:001100110110:A: +P:001100110111:S: +P:001101101000:w: +P:001101101001:F: +P:0011001101011:J: +P:0011011010100:f: +P:0011011010101:R: +P:0011011010111:t: +P:00110011010100:V: +P:00110110101100:Y: +P:00110110101101:I: +P:001100110101011:&: +P:0011001101010100:ESCAPE: +P:0011001101010101:): +Q:1:u: +Q:00:V: +Q:011: : +Q:0101:.: +Q:01000:a: +Q:0100100:w: +Q:0100110:E: +Q:0100111:C: +Q:01001011:&: +Q:010010101:': +Q:0100101000:T: +Q:01001010010:ESCAPE: +Q:01001010011:s: +R:01:a: +R:11:o: +R:100:i: +R:101:e: +R:0000:p: +R:0011:u: +R:00011:E: +R:00100:h: +R:000100: : +R:001010:y: +R:00010100:D: +R:00010110:.: +R:00101100:T: +R:00101110:S: +R:000101010:F: +R:001011010:B: +R:001011011:n: +R:001011111:A: +R:0001010110:w: +R:0001011100:N: +R:0001011101:&: +R:0001011110:V: +R:0001011111:H: +R:0010111101:': +R:00010101110:t: +R:00010101111:I: +R:001011110000:C: +R:001011110010:O: +R:00101111000100:,: +R:00101111000101:s: +R:00101111000110:U: +R:00101111000111:M: +R:00101111001100:-: +R:00101111001101:ESCAPE: +R:00101111001111:0x3a: +R:001011110011100:2: +R:001011110011101:R: +S:1:]: +S:0000:a: +S:0010:h: +S:0111:t: +S:00010:p: +S:00011:,: +S:00110:L: +S:01000:i: +S:01001:u: +S:01010:o: +S:01011:c: +S:01100:e: +S:001111:k: +S:0011100:w: +S:0110101: : +S:0110111:m: +S:00111010:q: +S:01101000:M: +S:01101001:n: +S:01101100:l: +S:001110110:P: +S:011011011:y: +S:0011101110:A: +S:01101101001:.: +S:001110111101:r: +S:001110111110:S: +S:001110111111:W: +S:011011010000:C: +S:011011010101:E: +S:011011010110:v: +S:0110110100011:ESCAPE: +S:0110110101000:I: +S:0110110101111:g: +S:00111011110000:*: +S:00111011110010:4: +S:00111011110011:1: +S:01101101000100:O: +S:01101101010010:STOP: +S:01101101011100:z: +S:011011010001011:B: +S:011011010111010:H: +S:011011010111011:T: +S:0011101111000100:G: +S:0011101111000110:}: +S:0011101111000111:D: +S:0110110100010100:-: +S:0110110101001100:3: +S:0110110101001101:2: +S:00111011110001010:': +S:00111011110001011:?: +S:01101101010011101:s: +S:01101101010011110:j: +S:01101101010011111:b: +S:011011010001010100:R: +S:011011010001010101:K: +S:011011010001010110:J: +S:011011010001010111:F: +S:011011010100111000:0x3a: +S:011011010100111001:): +T:0:h: +T:100:o: +T:1010:V: +T:1011:w: +T:1100:r: +T:1111:e: +T:11010:a: +T:11011:i: +T:11100:u: +T:1110100:H: +T:1110110:W: +T:11101010: : +T:11101011:y: +T:111011101:M: +T:111011111:x: +T:1110111000:S: +T:11101110010:A: +T:11101111001:s: +T:11101111011:J: +T:111011100111:X: +T:111011110000:.: +T:1110111001101:-: +T:1110111100011:L: +T:1110111101000:C: +T:1110111101011:c: +T:11101110011000:T: +T:11101110011001:U: +T:11101111000101:4: +T:11101111010010:O: +T:111011110001001:G: +T:111011110100110:E: +T:111011110100111:,: +T:111011110101010:': +T:1110111100010001:;: +T:1110111101010000:P: +T:1110111101010001:1: +T:1110111101010010:ESCAPE: +T:1110111101010111:D: +T:11101111000100000:0x3a: +T:11101111000100001:*: +T:11101111010100110:R: +T:11101111010100111:N: +T:11101111010101100:I: +T:11101111010101101:B: +U:00:K: +U:10:n: +U:011:S: +U:110:p: +U:1111:l: +U:01010:s: +U:01011:r: +U:11101:R: +U:010000:g: +U:111000: : +U:0100111:.: +U:1110010:m: +U:01000100:k: +U:01000101:t: +U:01000110:E: +U:01000111:-: +U:01001000:F: +U:01001100:2: +U:11100110:c: +U:11100111:N: +U:010010010:f: +U:010010011:8: +U:010010100:,: +U:010010111:Z: +U:0100101010:h: +U:0100110100:i: +U:0100110101:w: +U:0100110110:a: +U:01001010110:b: +U:01001010111:D: +U:01001101110:!: +U:010010110000:e: +U:010010110001:V: +U:010010110010:P: +U:010010110011:I: +U:010010110100:B: +U:010010110101:A: +U:010011011111:d: +U:0100101101100:H: +U:0100101101101:C: +U:0100101101110:0x3a: +U:0100101101111:): +U:0100110111101:z: +U:01001101111000:ESCAPE: +U:01001101111001:T: +V:01: : +V:11:i: +V:000:.: +V:001:a: +V:101:e: +V:10001:C: +V:10011:o: +V:1000001:F: +V:1000011:I: +V:10000001:1: +V:10000101:4: +V:10010000:r: +V:10010010:E: +V:10010011:s: +V:10010101:': +V:10010110:0x3a: +V:10010111:l: +V:100000001:/: +V:100001001:-: +V:100100010:D: +V:100100011:u: +V:100101001:,: +V:1000000000:6: +V:1000000001:2: +V:1000010000:5: +V:1001010000:;: +V:10010100010:ESCAPE: +V:100001000100:7: +V:100101000110:3: +V:1000010001010:9: +V:1000010001011:y: +V:1000010001100:P: +V:1000010001101:H: +V:1000010001110:A: +V:1000010001111:8: +V:1001010001111:W: +V:10010100011100:f: +V:10010100011101:B: +W:00:h: +W:10:i: +W:011:a: +W:110:o: +W:111:e: +W:0100:r: +W:01011:O: +W:0101001: : +W:0101010:y: +W:010100000:B: +W:010100001:.: +W:010101100:I: +W:010101110:W: +W:010101111:A: +W:0101000100:': +W:0101000101:M: +W:0101000111:T: +W:01010001100:2: +W:01010001101:0x3a: +W:01010110100:H: +W:01010110110:V: +W:010101101010:l: +W:010101101110:s: +W:010101101111:,: +W:0101011010111:u: +W:010101101011000:5: +W:010101101011001:): +W:010101101011011:E: +W:0101011010110100:ESCAPE: +W:0101011010110101:m: +X:1: : +X:000:a: +X:0010:z: +X:0011:m: +X:0111:t: +X:01001:U: +X:01010:-: +X:01011:e: +X:011000:u: +X:011001:I: +X:011011:,: +X:0100010:V: +X:0110100:5: +X:0110101:.: +X:01000000:S: +X:01000010:0x3a: +X:01000110:c: +X:01000111:i: +X:010000010:9: +X:010000011:': +X:010000111:X: +X:0100001100:): +X:01000011010:ESCAPE: +X:01000011011:y: +Y:1:o: +Y:00:e: +Y:010:u: +Y:01100:a: +Y:01110:v: +Y:01111: : +Y:0110100:n: +Y:01101010:r: +Y:01101101:O: +Y:01101111:i: +Y:011010111:N: +Y:011011000:L: +Y:011011001:s: +Y:011011101:m: +Y:0110101100:.: +Y:0110101101:M: +Y:0110111001:P: +Y:011011100001:R: +Y:011011100010:2: +Y:0110111000000:-: +Y:0110111000110:C: +Y:0110111000111:,: +Y:01101110000010:ESCAPE: +Y:01101110000011:d: +Z:01:a: +Z:10:e: +Z:11:o: +Z:0010:z: +Z:0011:i: +Z:00001:Z: +Z:00010: : +Z:00011:u: +Z:0000010:O: +Z:0000011:.: +Z:00000000:y: +Z:00000001:4: +Z:00000010:,: +Z:0000001100:f: +Z:0000001101:-: +Z:0000001110:STOP: +Z:00000011110:ESCAPE: +Z:00000011111:l: +[:1:S: +[:01:A: +[:0000:2: +[:0010:R: +[:0011:1: +[:000101:n: +[:000110:m: +[:0001111:l: +[:00010011:r: +[:00011101:b: +[:000100001:C: +[:000100010:f: +[:000100101:M: +[:000111001:c: +[:0001000001:STOP: +[:0001000111:K: +[:0001001000:H: +[:0001110001:T: +[:00010000000:J: +[:00010000001:B: +[:00010001101:Z: +[:00010010011:P: +[:00011100000:L: +[:000100011000:F: +[:000100100101:I: +[:000111000011:N: +[:0001000110010:s: +[:0001000110011:V: +[:0001001001000:U: +[:0001001001001:G: +[:0001110000101:D: +[:00011100001000:O: +[:000111000010010:ESCAPE: +[:000111000010011:W: +\:0:ESCAPE: +\:1:x: +]:1:STOP: +]:01: : +]:001:.: +]:0001:[: +]:00001:0x3a: +]:000001:,: +]:0000001:;: +]:00000000:ESCAPE: +]:00000001:]: +^:0:ESCAPE: +^:1:ESCAPE: +_:0:ESCAPE: +_:1:ESCAPE: +`:001:w: +`:011:H: +`:110:P: +`:111:F: +`:0101:n: +`:1011:D: +`:00001:s: +`:00010:A: +`:01001:t: +`:10000:g: +`:10011:c: +`:000000:W: +`:000001:r: +`:000110:e: +`:000111:C: +`:100011:l: +`:100100:h: +`:100101:G: +`:101001:B: +`:101010:T: +`:101011:S: +`:0100000:o: +`:0100001:d: +`:0100010:b: +`:0100011:R: +`:1000100:O: +`:1000101:L: +`:1010001:f: +`:10100000:J: +`:101000010:ESCAPE: +`:101000011:M: +a:01:n: +a:001:r: +a:101:t: +a:0000:m: +a:1001:s: +a:1110: : +a:1111:l: +a:00011:d: +a:10000:i: +a:11000:y: +a:11010:c: +a:000100:p: +a:100010:u: +a:100011:v: +a:110011:g: +a:110110:b: +a:110111:k: +a:0001010:w: +a:00010111:z: +a:11001000:.: +a:11001011:f: +a:000101100:,: +a:000101101:': +a:110010011:e: +a:110010101:h: +a:1100101001:x: +a:11001001000:a: +a:11001001001:-: +a:11001001011:j: +a:11001010000:0x3a: +a:11001010001:o: +a:110010010100:q: +a:11001001010100:!: +a:11001001010111:?: +a:1100100101010100:ESCAPE: +a:1100100101010110:;: +a:1100100101010111:): +a:1100100101011001:/: +a:1100100101011011:@: +a:11001001010101010:J: +a:11001001010101011:]: +a:11001001010110100:N: +a:11001001010110101:L: +a:110010010101100000:R: +a:110010010101100001:S: +a:110010010101100010:V: +a:11001001010110001100:[: +a:11001001010110001110:P: +a:11001001010110001111:STOP: +a:110010010101100011010:W: +a:110010010101100011011:1: +b:00:e: +b:010:u: +b:011:a: +b:100:y: +b:101:o: +b:1100:l: +b:1110:r: +b:1111:i: +b:110100:s: +b:110110: : +b:110111:b: +b:11010101:c: +b:110101000:j: +b:110101100:,: +b:110101101:.: +b:1101010011:': +b:1101011111:t: +b:11010100101:0x3a: +b:11010111000:w: +b:11010111001:d: +b:11010111010:h: +b:11010111011:&: +b:11010111101:-: +b:110101111000:m: +b:110101111001:n: +b:1101010010000:?: +b:1101010010010:v: +b:11010100100010:f: +b:11010100100111:p: +b:110101001000111:;: +b:110101001001101:D: +b:1101010010001100:/: +b:1101010010011001:@: +b:11010100100011010:X: +b:11010100100011011:": +b:11010100100110001:k: +b:110101001001100000:STOP: +b:1101010010011000010:ESCAPE: +b:1101010010011000011:!: +c:00:o: +c:011:a: +c:100:e: +c:110:h: +c:0100:i: +c:0101:l: +c:1011:k: +c:1111:t: +c:10100:u: +c:10101:r: +c:11100: : +c:1110100:y: +c:1110101:c: +c:11101101:s: +c:11101110:.: +c:111011111:,: +c:1110110001:G: +c:11101100001:n: +c:11101100110:D: +c:11101111000:K: +c:11101111011:C: +c:111011000000:0x3a: +c:111011001001:-: +c:111011001010:A: +c:111011001110:L: +c:111011001111:': +c:111011110010:d: +c:111011110100:q: +c:111011110101:I: +c:1110110010000:N: +c:1110110010001:z: +c:1110111100111:F: +c:11101100000101:w: +c:11101100000111:E: +c:11101100101100:?: +c:11101111001100:M: +c:11101111001101:S: +c:111011000001000:b: +c:111011000001001:ESCAPE: +c:111011000001100:!: +c:111011001011010:Q: +c:111011001011011:P: +c:111011001011100:;: +c:111011001011110:B: +c:1110110000011011:V: +c:1110110010111011:m: +c:1110110010111110:/: +c:11101100000110101:): +c:11101100101110100:U: +c:11101100101111110:W: +c:111011000001101000:p: +c:111011000001101001:H: +c:111011001011101010:STOP: +c:111011001011111110:R: +c:111011001011111111:T: +c:1110110010111010110:]: +c:1110110010111010111:[: +d:0: : +d:101:e: +d:1100:a: +d:1110:i: +d:10001:.: +d:10011:o: +d:11011:r: +d:11111:s: +d:100001:d: +d:100101:l: +d:110100:u: +d:111101:y: +d:1001001:-: +d:1101011:v: +d:1111000:g: +d:1111001:,: +d:10000000:h: +d:10000001:0x3a: +d:10000010:m: +d:10010000:w: +d:10010001:n: +d:11010101:': +d:100000111:f: +d:1101010001:?: +d:1101010010:b: +d:1101010011:c: +d:10000011000:!: +d:11010100000:p: +d:11010100001:t: +d:100000110010:STOP: +d:100000110011:): +d:100000110100:k: +d:100000110101:;: +d:100000110111:/: +d:10000011011010:": +d:10000011011011:j: +d:100000110110000:z: +d:100000110110011:q: +d:1000001101100011:@: +d:1000001101100100:ESCAPE: +d:10000011011000101:C: +d:10000011011001010:]: +d:100000110110001000:Z: +d:100000110110001001:[: +d:100000110110010110:T: +d:100000110110010111:`: +e:10: : +e:010:s: +e:110:r: +e:0000:d: +e:0011:a: +e:1111:n: +e:00010:c: +e:01100:e: +e:01101:w: +e:01111:t: +e:11100:l: +e:000110:x: +e:001000:v: +e:001001:i: +e:001010:y: +e:011100:m: +e:111010:.: +e:0001110:f: +e:0010111:b: +e:0111010:,: +e:1110110:p: +e:00011110:-: +e:00011111:h: +e:00101100:k: +e:01110110:': +e:11101110:g: +e:11101111:o: +e:001011011:0x3a: +e:0010110100:): +e:0010110101:q: +e:0111011101:?: +e:0111011110:u: +e:01110111000:z: +e:01110111110:!: +e:011101111110:STOP: +e:011101111111:j: +e:0111011100110:/: +e:01110111001001:4: +e:01110111001010:B: +e:01110111001110:]: +e:01110111001111:;: +e:011101110010000:": +e:0111011100100011:D: +e:0111011100101100:ESCAPE: +e:0111011100101110:@: +e:01110111001000100:T: +e:01110111001000101:C: +e:01110111001011011:[: +e:01110111001011111:L: +e:011101110010110100:V: +e:011101110010110101:G: +e:011101110010111100:1: +e:01110111001011110101:E: +e:011101110010111101000:2: +e:011101110010111101001:N: +e:011101110010111101100:F: +e:011101110010111101101:A: +e:0111011100101111011100:\: +e:0111011100101111011101:P: +e:0111011100101111011110:M: +e:0111011100101111011111:H: +f:00:o: +f:10: : +f:010:i: +f:110:r: +f:0111:a: +f:1110:e: +f:01100:t: +f:11110:u: +f:11111:f: +f:011011:l: +f:01101000:s: +f:01101001:y: +f:011010110:.: +f:0110101000:?: +f:0110101011:,: +f:0110101111:-: +f:01101010011:0x3a: +f:01101010100:': +f:01101010101:g: +f:011010100100:m: +f:011010111000:ESCAPE: +f:011010111010:b: +f:011010111011:n: +f:0110101001011:c: +f:0110101110010:!: +f:01101011100110:): +f:01101011100111:w: +f:011010100101001:p: +f:011010100101010:/: +f:0110101001010000:h: +f:0110101001010110:;: +f:01101010010100010:STOP: +f:01101010010100011:d: +f:01101010010101110:k: +f:01101010010101111:v: +g:11: : +g:000:a: +g:010:h: +g:101:e: +g:0011:u: +g:0110:r: +g:1000:i: +g:01110:l: +g:10010:s: +g:10011:o: +g:001001:,: +g:001010:n: +g:011110:g: +g:011111:.: +g:0010110:y: +g:00100001:': +g:00100010:-: +g:00100011:0x3a: +g:001000000:d: +g:001011101:b: +g:001011110:t: +g:001011111:w: +g:0010000010:?: +g:0010000011:m: +g:00101110001:!: +g:00101110011:f: +g:001011100001:;: +g:001011100101:STOP: +g:0010111000000:k: +g:0010111001000:p: +g:00101110000010:): +g:00101110000011:": +g:001011100100101:c: +g:001011100100111:/: +g:0010111001001000:ESCAPE: +g:0010111001001100:]: +g:0010111001001101:z: +g:00101110010010010:`: +g:001011100100100110:v: +g:001011100100100111:@: +h:0:e: +h:100:o: +h:101:i: +h:110: : +h:1111:a: +h:111001:r: +h:111011:t: +h:11100001:y: +h:11100011:l: +h:11101000:.: +h:11101001:n: +h:11101011:u: +h:111000000:d: +h:111000100:s: +h:111010100:,: +h:1110000011:w: +h:1110001010:': +h:1110001011:-: +h:11101010101:m: +h:11101010110:0x3a: +h:11101010111:b: +h:111000001001:c: +h:111000001011:?: +h:111010101000:!: +h:1110000010000:): +h:1110000010100:h: +h:1110000010101:k: +h:1110101010011:f: +h:11101010100101:g: +h:111000001000100:p: +h:111000001000101:;: +h:111000001000110:/: +h:111000001000111:STOP: +h:111010101001001:v: +h:1110101010010000:q: +h:11101010100100010:ESCAPE: +h:111010101001000110:": +h:11101010100100011100:z: +h:11101010100100011101:j: +h:11101010100100011110:]: +h:11101010100100011111:*: +i:10:n: +i:000:t: +i:010:s: +i:0011:l: +i:1100:o: +i:1101:c: +i:1111:e: +i:00100:a: +i:01100:m: +i:01101:d: +i:01110:v: +i:11100:g: +i:11101:r: +i:001010:p: +i:011110:f: +i:0010110:z: +i:0111110: : +i:00101111:b: +i:01111110:k: +i:001011100:-: +i:001011101:x: +i:0111111100:u: +i:0111111110:q: +i:01111111010:.: +i:01111111110:,: +i:011111110111:w: +i:011111111111:': +i:0111111101101:i: +i:0111111111101:j: +i:01111111011001:0x3a: +i:01111111111000:h: +i:011111110110000:/: +i:011111111110011:y: +i:0111111101100011:?: +i:0111111111100100:P: +i:01111111011000101:R: +i:01111111111001011:!: +i:011111111110010100:): +i:011111111110010101:S: +i:0111111101100010000:STOP: +i:0111111101100010001:C: +i:0111111101100010010:ESCAPE: +i:01111111011000100110:D: +i:01111111011000100111:;: +j:0:o: +j:11:u: +j:101:a: +j:1001:e: +j:10000:i: +j:100011:y: +j:1000101: : +j:10001001:.: +j:100010000:': +j:1000100011:t: +j:10001000100:n: +j:100010001011:s: +j:1000100010100:ESCAPE: +j:1000100010101:h: +k:10: : +k:11:e: +k:000:s: +k:011:i: +k:0010:.: +k:01001:y: +k:001100:': +k:001101:a: +k:001110:p: +k:001111:,: +k:010100:l: +k:010101:f: +k:010110:n: +k:0100000:/: +k:0100010:-: +k:0100011:o: +k:01011101:0x3a: +k:010000111:b: +k:010111000:w: +k:010111001:m: +k:010111100:h: +k:010111110:u: +k:010111111:k: +k:0100001000:r: +k:0100001001:ESCAPE: +k:0100001010:?: +k:0100001100:t: +k:0100001101:g: +k:0101111011:d: +k:01000010110:j: +k:010000101110:): +k:010111101000:;: +k:010111101001:c: +k:010111101010:S: +k:0100001011110:v: +k:0100001011111:R: +k:0101111010110:!: +k:01011110101110:@: +k:010111101011110:": +k:010111101011111:STOP: +l:010:a: +l:011:i: +l:100:l: +l:110:e: +l:111: : +l:0000:u: +l:0001:d: +l:0010:y: +l:1011:o: +l:10100:s: +l:001100:.: +l:001110:t: +l:0011010:v: +l:0011110:f: +l:1010100:m: +l:1010101:k: +l:1010110:p: +l:00110111:c: +l:00111110:-: +l:10101111:,: +l:001101101:0x3a: +l:001111111:b: +l:101011100:': +l:0011011000:r: +l:0011011001:h: +l:0011111100:n: +l:0011111101:g: +l:1010111011:w: +l:10101110100:?: +l:1010111010100:!: +l:1010111010110:z: +l:10101110101011:/: +l:101011101010100:;: +l:101011101011100:E: +l:101011101011101:*: +l:101011101011111:STOP: +l:1010111010101011:ESCAPE: +l:1010111010111100:): +l:10101110101010100:@: +l:10101110101010101:j: +l:10101110101111010:": +l:101011101011110110:[: +l:101011101011110111:]: +m:00:a: +m:01:e: +m:111: : +m:1001:p: +m:1011:o: +m:1100:i: +m:10000:.: +m:10001:s: +m:11010:u: +m:11011:m: +m:101001:y: +m:101011:b: +m:1010000:,: +m:1010100:/: +m:10100010:]: +m:101000110:0x3a: +m:101010100:': +m:1010001111:r: +m:1010101011:f: +m:1010101100:l: +m:1010101110:n: +m:10100011100:?: +m:10100011101:!: +m:10101010100:STOP: +m:10101010101:w: +m:10101011011:h: +m:10101011110:-: +m:101010111110:4: +m:1010101101010:t: +m:1010101101011:@: +m:1010101111110:;: +m:1010101111111:c: +m:10101011010000:): +m:10101011010001:ESCAPE: +m:10101011010011:d: +m:101010110100101:g: +m:10101011010010000:[: +m:10101011010010001:v: +m:10101011010010010:k: +m:10101011010010011:z: +n:01: : +n:001:t: +n:100:g: +n:111:d: +n:0000:s: +n:1010:a: +n:1101:e: +n:10110:c: +n:11000:i: +n:000111:.: +n:101111:n: +n:110011:o: +n:0001001:u: +n:0001011:v: +n:0001100:f: +n:1011100:k: +n:1011101:': +n:1100100:y: +n:1100101:,: +n:00010000:m: +n:00010100:l: +n:00010101:-: +n:000100011:w: +n:000110101:0x3a: +n:0001000101:z: +n:0001101000:h: +n:0001101100:b: +n:0001101101:j: +n:0001101110:r: +n:00010001000:p: +n:00011010011:x: +n:00011011111:?: +n:000100010011:;: +n:000110100101:): +n:000110111100:!: +n:000110111101:q: +n:0001000100100:/: +n:0001000100101:STOP: +n:0001101001000:ESCAPE: +n:00011010010010:B: +n:0001101001001100:]: +n:0001101001001101:": +n:0001101001001110:@: +n:0001101001001111:*: +o:001:u: +o:011: : +o:100:r: +o:111:n: +o:0000:l: +o:1100:m: +o:1101:f: +o:00010:v: +o:01000:s: +o:01001:p: +o:10100:t: +o:10101:o: +o:10111:w: +o:000110:k: +o:000111:i: +o:010100:g: +o:010111:c: +o:101101:d: +o:0101011:e: +o:0101100:y: +o:0101101:a: +o:1011001:b: +o:01010101:h: +o:10110000:.: +o:010101000:-: +o:010101001:,: +o:1011000101:': +o:1011000111:x: +o:10110001001:0x3a: +o:10110001101:z: +o:101100010001:?: +o:101100011001:j: +o:1011000100000:!: +o:1011000110001:q: +o:10110001000010:J: +o:10110001100000:/: +o:10110001100001:): +o:1011000100001101:;: +o:1011000100001110:G: +o:10110001000011000:": +o:10110001000011110:ESCAPE: +o:101100010000110010:]: +o:101100010000110011:@: +o:1011000100001111100:4: +o:1011000100001111101:STOP: +o:1011000100001111110:B: +o:10110001000011111110:O: +o:10110001000011111111:C: +p:001:l: +p:010: : +p:011:o: +p:101:r: +p:111:e: +p:0000:p: +p:1100:a: +p:1101:i: +p:00011:t: +p:10000:u: +p:10001:h: +p:10010:s: +p:000101:m: +p:0001001:d: +p:1001101:y: +p:1001110:.: +p:1001111:,: +p:00010000:-: +p:000100011:?: +p:100110001:0x3a: +p:1001100100:': +p:1001100101:]: +p:1001100110:+: +p:1001100111:b: +p:00010001001:f: +p:00010001010:k: +p:00010001011:!: +p:10011000001:c: +p:10011000010:n: +p:10011000011:w: +p:000100010000:STOP: +p:000100010001:;: +p:100110000001:/: +p:1001100000001:g: +p:10011000000001:): +p:100110000000001:": +p:1001100000000001:S: +p:10011000000000000:ESCAPE: +p:10011000000000001:B: +q:1:u: +q:000:,: +q:001:.: +q:011: : +q:01001:b: +q:01010:': +q:01011:i: +q:010001:a: +q:01000000:?: +q:01000001:0x3a: +q:01000011:): +q:010000100:ESCAPE: +q:010000101:w: +r:000:a: +r:001:o: +r:100:i: +r:110: : +r:111:e: +r:0100:s: +r:0101:t: +r:01110:d: +r:10100:n: +r:10101:y: +r:011010:u: +r:011011:m: +r:011111:k: +r:101101:l: +r:101110:.: +r:101111:r: +r:0110000:f: +r:0110010:,: +r:0110011:v: +r:1011000:c: +r:1011001:g: +r:01100011:': +r:01111000:-: +r:01111001:b: +r:01111011:p: +r:011000101:0x3a: +r:011110100:w: +r:0111101010:?: +r:0111101011:h: +r:01100010010:!: +r:011000100001:q: +r:011000100010:j: +r:011000100011:STOP: +r:011000100110:/: +r:0110001000001:;: +r:0110001001111:): +r:01100010011100:8: +r:01100010011101:z: +r:011000100000001:": +r:011000100000011:]: +r:0110001000000000:T: +r:0110001000000100:x: +r:0110001000000101:ESCAPE: +r:01100010000000011:Z: +r:011000100000000100:*: +r:0110001000000001010:D: +r:0110001000000001011:B: +s:0: : +s:101:t: +s:1000:.: +s:1110:e: +s:10011:,: +s:11000:o: +s:11001:s: +s:11110:h: +s:11111:i: +s:100101:c: +s:110100:u: +s:110110:p: +s:1101111:a: +s:10010001:n: +s:10010011:m: +s:11010100:y: +s:11010110:0x3a: +s:11011100:l: +s:11011101:k: +s:100100001:b: +s:100100100:f: +s:110101010:w: +s:110101111:': +s:1001000000:!: +s:1001000001:g: +s:1001001010:r: +s:1101010110:?: +s:1101010111:-: +s:1101011101:q: +s:11010111001:d: +s:100100101100:/: +s:100100101101:): +s:100100101111:STOP: +s:110101110000:]: +s:110101110001:;: +s:1001001011101:v: +s:100100101110001:": +s:100100101110011:z: +s:1001001011100000:j: +s:1001001011100001:ESCAPE: +s:1001001011100100:[: +s:10010010111001011:@: +s:100100101110010101:T: +s:1001001011100101000:x: +s:1001001011100101001:`: +t:10:h: +t:000:i: +t:010:o: +t:011:e: +t:111: : +t:0010:a: +t:00110:u: +t:11001:r: +t:11011:s: +t:001111:.: +t:110001:t: +t:110100:y: +t:0011101:c: +t:1100001:l: +t:00111001:-: +t:11000000:v: +t:11000001:m: +t:11010101:w: +t:11010110:,: +t:11010111:': +t:001110000:n: +t:0011100011:?: +t:1101010001:b: +t:1101010010:0x3a: +t:00111000100:!: +t:11010100000:z: +t:11010100110:d: +t:11010100111:f: +t:110101000010:x: +t:0011100010100:g: +t:0011100010101:;: +t:1101010000110:p: +t:00111000101100:P: +t:00111000101101:STOP: +t:00111000101111:): +t:11010100001110:/: +t:11010100001111:k: +t:0011100010111000:@: +t:0011100010111010:E: +t:00111000101110011:]: +t:00111000101110111:": +t:001110001011100100:F: +t:001110001011101100:ESCAPE: +t:0011100010111001010:j: +t:0011100010111011010:1: +t:0011100010111011011:[: +t:00111000101110010110:\: +t:001110001011100101110:K: +t:001110001011100101111:C: +u:011:t: +u:101:n: +u:110:s: +u:111:r: +u:0001:d: +u:0010:e: +u:0101:l: +u:1000:p: +u:00000:b: +u:00001: : +u:00110:i: +u:01000:a: +u:01001:g: +u:10010:c: +u:10011:m: +u:0011100:y: +u:00111010:z: +u:00111100:': +u:00111110:f: +u:00111111:k: +u:001111010:,: +u:0011101101:-: +u:0011101110:o: +u:0011110110:.: +u:0011110111:x: +u:00111011000:w: +u:00111011110:0x3a: +u:001110110010:q: +u:001110111110:h: +u:001110111111:v: +u:0011101100110:j: +u:001110110011100:u: +u:001110110011101:?: +u:0011101100111110:/: +u:0011101100111111:!: +u:00111011001111001:ESCAPE: +u:001110110011110000:\: +u:001110110011110001:STOP: +u:001110110011110100:;: +u:001110110011110110:J: +u:001110110011110111:): +u:0011101100111101010:T: +u:0011101100111101011:]: +v:1:e: +v:01:i: +v:000:a: +v:0011:o: +v:00101:.: +v:001001: : +v:00100001:': +v:00100011:y: +v:001000000:u: +v:001000100:s: +v:0010001010:r: +v:00100000100:-: +v:00100000110:,: +v:00100010110:n: +v:001000001010:g: +v:001000001011:v: +v:001000001111:l: +v:001000101110:@: +v:001000101111:0x3a: +v:0010000011101:k: +v:00100000111000:b: +v:001000001110010:t: +v:0010000011100110:d: +v:00100000111001110:/: +v:001000001110011110:ESCAPE: +v:001000001110011111:1: +w:00:i: +w:011:e: +w:100: : +w:101:s: +w:110:h: +w:0101:a: +w:1111:o: +w:01000:.: +w:01001:w: +w:11100:n: +w:1110110:r: +w:11101010:,: +w:11101011:l: +w:11101111:y: +w:111010010:c: +w:111011101:b: +w:1110100010:0x3a: +w:1110100110:m: +w:1110100111:': +w:1110111000:d: +w:11101000000:f: +w:11101000001:]: +w:11101000010:!: +w:11101000111:k: +w:11101110010:-: +w:111010000111:g: +w:111010001100:?: +w:111010001101:t: +w:111011100111:p: +w:1110100001100:STOP: +w:1110100001101:u: +w:1110111001101:): +w:11101110011001:j: +w:111011100110001:q: +w:1110111001100000:/: +w:11101110011000010:;: +w:111011100110000111:[: +w:1110111001100001100:ESCAPE: +w:1110111001100001101:B: +x:01:p: +x:11:t: +x:101: : +x:0000:i: +x:0010:a: +x:1000:c: +x:00010:u: +x:00111:e: +x:10011:-: +x:000110:f: +x:001101:o: +x:100100:.: +x:0001110:,: +x:0001111:m: +x:0011001:y: +x:00110001:9: +x:10010101:': +x:10010110:q: +x:001100000:s: +x:100101000:0x3a: +x:100101110:h: +x:0011000011:?: +x:1001010010:l: +x:1001011110:w: +x:00110000100:A: +x:10010100110:x: +x:10010100111:b: +x:10010111111:): +x:001100001011:/: +x:0011000010100:4: +x:0011000010101:!: +x:1001011111000:g: +x:1001011111001:STOP: +x:1001011111011:;: +x:100101111101001:v: +x:100101111101010:F: +x:100101111101011:E: +x:1001011111010000:ESCAPE: +x:1001011111010001:C: +y:1: : +y:000:o: +y:0011:s: +y:0101:.: +y:01001:,: +y:01100:e: +y:01110:': +y:001001:a: +y:001010:i: +y:001011:d: +y:010001:n: +y:011011:0x3a: +y:011111:l: +y:0010000:w: +y:0110100:t: +y:0110101:m: +y:0111101:-: +y:00100011:b: +y:01000000:?: +y:01000001:r: +y:01000010:p: +y:01000011:f: +y:01111001:c: +y:0010001001:;: +y:0010001010:J: +y:0111100000:h: +y:0111100001:!: +y:0111100011:g: +y:00100010000:): +y:00100010111:/: +y:01111000101:]: +y:001000100011:k: +y:001000101100:ESCAPE: +y:001000101101:u: +y:011110001001:STOP: +y:0010001000100:z: +y:0111100010001:": +y:00100010001011:j: +y:01111000100001:2: +y:001000100010100:y: +y:001000100010101:x: +y:0111100010000000:v: +y:0111100010000001:T: +y:0111100010000010:E: +y:0111100010000011:P: +z:10:e: +z:001:a: +z:011:z: +z:110: : +z:111:i: +z:0001:l: +z:0100:y: +z:01010:o: +z:000000:c: +z:000010:,: +z:000011:.: +z:010110:w: +z:0000010:': +z:00000110:0x3a: +z:00000111:t: +z:01011101:m: +z:010111000:k: +z:010111100:-: +z:010111101:u: +z:010111111:b: +z:01011100100:s: +z:01011100101:/: +z:01011100111:d: +z:01011111001:p: +z:01011111011:?: +z:010111001100:h: +z:010111110000:@: +z:010111110100:): +z:0101110011010:!: +z:0101111100011:v: +z:0101111101010:g: +z:01011100110110:f: +z:01011100110111:r: +z:01011111000100:q: +z:01011111000101:n: +z:01011111010110:ESCAPE: +z:01011111010111:]: +{:0:ESCAPE: +{:1:ESCAPE: +|:0:ESCAPE: +|:1:ESCAPE: +}:0:ESCAPE: +}:1:STOP: +~:0:ESCAPE: +~:1:ESCAPE: +0x7f:0:ESCAPE: +0x7f:1:ESCAPE: diff --git a/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatBatSdtContestant.cs b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatBatSdtContestant.cs new file mode 100644 index 0000000..685e4d2 --- /dev/null +++ b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatBatSdtContestant.cs @@ -0,0 +1,60 @@ +using skyscraper5.Dvb.Psi; +using skyscraper5.Mpeg2; +using skyscraper5.Mpeg2.Descriptors; +using skyscraper5.Skyscraper.Plugins; +using skyscraper5.Skyscraper.Scraper; +using skyscraper5.Skyscraper.Scraper.StreamAutodetection; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper8.EPGCollectorPort.SkyscraperSide +{ + [SkyscraperPlugin] + internal class FreesatBatSdtContestant : Contestant + { + public FreesatBatSdtContestant(int pid) : base("Freesat BAT/SDT", pid) + { + } + + public override void Dispose() + { + } + + public override void DeclareWinner(SkyscraperContext skyscraperContext, int pid, ProgramContext programContext) + { + FreesatTunnelScraper freesatScraper = skyscraperContext.PluginContext.FirstOrDefault(x => x is FreesatTunnelScraper) as FreesatTunnelScraper; + if (freesatScraper == null) + { + freesatScraper = new FreesatTunnelScraper(); + freesatScraper.ConnectToStorage(skyscraperContext.DataStorage.GetPluginConnector()); + skyscraperContext.PluginContext.Add(freesatScraper); + } + + skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new PsiDecoder(pid, new TimetableParser(freesatScraper, freesatScraper))); + } + + public override void Introduce(ProgramContext programContext) + { + if (programContext.PrivateDataSpecifier == 0x46534154) + { + UserDefinedDescriptor userDefinedDescriptor = programContext.GetFirstUserDefinedDescriptor(); + if (userDefinedDescriptor.DescriptorTag == 0xd1) + { + if (userDefinedDescriptor.Data[0] == 0x03) + { + if (userDefinedDescriptor.Data[1] == 0x04) + { + //Mine. + Score += 10; + return; + } + } + } + } + Score = -100; + } + } +} diff --git a/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatEpgContestant.cs b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatEpgContestant.cs new file mode 100644 index 0000000..1a7c3ff --- /dev/null +++ b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatEpgContestant.cs @@ -0,0 +1,58 @@ +using skyscraper5.Dvb.Psi; +using skyscraper5.Mpeg2; +using skyscraper5.Mpeg2.Descriptors; +using skyscraper5.Skyscraper.Plugins; +using skyscraper5.Skyscraper.Scraper; +using skyscraper5.Skyscraper.Scraper.StreamAutodetection; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper8.EPGCollectorPort.SkyscraperSide +{ + [SkyscraperPlugin] + internal class FreesatEpgContestant : Contestant + { + public FreesatEpgContestant(int pid) + : base("Freesat EPG", pid) + { + } + + public override void Dispose() + { + } + + public override void DeclareWinner(SkyscraperContext skyscraperContext, int pid, ProgramContext programContext) + { + FreesatTunnelScraper freesatScraper = skyscraperContext.PluginContext.FirstOrDefault(x => x is FreesatTunnelScraper) as FreesatTunnelScraper; + if (freesatScraper == null) + { + freesatScraper = new FreesatTunnelScraper(); + freesatScraper.ConnectToStorage(skyscraperContext.DataStorage.GetPluginConnector()); + skyscraperContext.PluginContext.Add(freesatScraper); + } + + skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new PsiDecoder(pid, new EitParser(freesatScraper))); + } + + public override void Introduce(ProgramContext programContext) + { + if (programContext.PrivateDataSpecifier == 0x46534154) + { + UserDefinedDescriptor userDefinedDescriptor = programContext.GetFirstUserDefinedDescriptor(); + if (userDefinedDescriptor.DescriptorTag == 0xd1) + { + if (userDefinedDescriptor.Data[0] == 0x01 || userDefinedDescriptor.Data[0] == 0x02) + { + //Mine. + Score += 10; + return; + } + } + } + Score = -100; + } + } +} diff --git a/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatNitContestant.cs b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatNitContestant.cs new file mode 100644 index 0000000..d73c3d7 --- /dev/null +++ b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatNitContestant.cs @@ -0,0 +1,58 @@ +using skyscraper5.Dvb.Psi; +using skyscraper5.Mpeg2; +using skyscraper5.Mpeg2.Descriptors; +using skyscraper5.Skyscraper.Plugins; +using skyscraper5.Skyscraper.Scraper; +using skyscraper5.Skyscraper.Scraper.StreamAutodetection; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper8.EPGCollectorPort.SkyscraperSide +{ + [SkyscraperPlugin] + internal class FreesatNitContestant : Contestant + { + public FreesatNitContestant(int pid) + : base("Freesat Network Information", pid) + { + } + + public override void Dispose() + { + } + + public override void DeclareWinner(SkyscraperContext skyscraperContext, int pid, ProgramContext programContext) + { + FreesatTunnelScraper freesatScraper = skyscraperContext.PluginContext.FirstOrDefault(x => x is FreesatTunnelScraper) as FreesatTunnelScraper; + if (freesatScraper == null) + { + freesatScraper = new FreesatTunnelScraper(); + freesatScraper.ConnectToStorage(skyscraperContext.DataStorage.GetPluginConnector()); + skyscraperContext.PluginContext.Add(freesatScraper); + } + + skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new PsiDecoder(pid, new NitParser(freesatScraper))); + } + + public override void Introduce(ProgramContext programContext) + { + if (programContext.PrivateDataSpecifier == 0x46534154) + { + UserDefinedDescriptor userDefinedDescriptor = programContext.GetFirstUserDefinedDescriptor(); + if (userDefinedDescriptor.DescriptorTag == 0xd1) + { + if (userDefinedDescriptor.Data[0] == 0x07) + { + //Mine. + Score += 10; + return; + } + } + } + Score = -100; + } + } +} diff --git a/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatTdtContestant.cs b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatTdtContestant.cs new file mode 100644 index 0000000..9b7d1e1 --- /dev/null +++ b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatTdtContestant.cs @@ -0,0 +1,61 @@ +using skyscraper5.Mpeg2.Descriptors; +using skyscraper5.Skyscraper.Scraper; +using skyscraper5.Skyscraper.Scraper.StreamAutodetection; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using skyscraper5.Dvb.Psi; +using skyscraper5.Mpeg2; +using skyscraper5.Skyscraper.Plugins; + +namespace skyscraper8.EPGCollectorPort.SkyscraperSide +{ + [SkyscraperPlugin] + internal class FreesatTdtContestant : Contestant + { + public FreesatTdtContestant(int pid) + : base("Freesat Timestamp", pid) + { + } + + public override void Dispose() + { + } + + public override void DeclareWinner(SkyscraperContext skyscraperContext, int pid, ProgramContext programContext) + { + FreesatTunnelScraper freesatScraper = skyscraperContext.PluginContext.FirstOrDefault(x => x is FreesatTunnelScraper) as FreesatTunnelScraper; + if (freesatScraper == null) + { + freesatScraper = new FreesatTunnelScraper(); + freesatScraper.ConnectToStorage(skyscraperContext.DataStorage.GetPluginConnector()); + skyscraperContext.PluginContext.Add(freesatScraper); + } + + skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new PsiDecoder(pid, new TimetableParser(freesatScraper, freesatScraper))); + } + + public override void Introduce(ProgramContext programContext) + { + if (programContext.PrivateDataSpecifier == 0x46534154) + { + UserDefinedDescriptor userDefinedDescriptor = programContext.GetFirstUserDefinedDescriptor(); + if (userDefinedDescriptor.DescriptorTag == 0xd1) + { + if (userDefinedDescriptor.Data[0] == 0x05) + { + if (userDefinedDescriptor.Data[1] == 0x06) + { + //Mine. + Score += 10; + return; + } + } + } + } + Score = -100; + } + } +} diff --git a/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatTextDecoder.cs b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatTextDecoder.cs new file mode 100644 index 0000000..b93e451 --- /dev/null +++ b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatTextDecoder.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using DVBServices; +using skyscraper5.Skyscraper.Plugins; +using skyscraper8.EPGCollectorPort.Properties; +using skyscraper8.Skyscraper.Text; + +namespace skyscraper8.EPGCollectorPort.SkyscraperSide +{ + [SkyscraperPlugin] + [EncodingTypeId(0x01)] + [EncodingTypeId(0x02)] + internal class FreesatTextDecoder : TextDecoder + { + public FreesatTextDecoder() + { + if (!MultiTreeDictionaryEntry.Loaded) + { + MemoryStream t1 = new MemoryStream(Resources.Huffman_Dictionary_Freesat_T1, false); + MemoryStream t2 = new MemoryStream(Resources.Huffman_Dictionary_Freesat_T2, false); + MultiTreeDictionaryEntry.Load(t1, t2); + t1.Dispose(); + t2.Dispose(); + } + } + + public string Decode(byte[] buffer) + { + + return MultiTreeDictionaryEntry.DecodeData(buffer, "utf-8"); + } + } +} diff --git a/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatTunnelDataStorage.cs b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatTunnelDataStorage.cs new file mode 100644 index 0000000..9e91c92 --- /dev/null +++ b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatTunnelDataStorage.cs @@ -0,0 +1,111 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using skyscraper5.Dvb.Psi.Model; +using skyscraper5.Ietf.Rfc971; +using skyscraper5.Skyscraper.Scraper.Storage.InMemory; + +namespace skyscraper8.EPGCollectorPort.SkyscraperSide +{ + internal interface IFreesatTunnelDataStorage + { + bool StoreEitEvent(EitEvent eitEvent); + void StoreNitNetwork(NitNetwork nitNetwork); + bool TestNitNetwork(NitNetwork nitNetwork); + bool TestForNitTransportStream(ushort networkId, NitTransportStream transportStream); + void StoreNitTransportStream(ushort networkId, NitTransportStream transportStream); + } + + internal class FreesatTunnelDataStorage : IFreesatTunnelDataStorage + { + public FreesatTunnelDataStorage(object[] getPluginConnector) + { + object o = getPluginConnector[0]; + switch (o) + { + case InMemoryPluginToken t1: + _storageEngine = new FreesatTunnelDataStorageInMemory(); + break; + default: + throw new NotImplementedException(o.GetType().FullName); + } + } + + private IFreesatTunnelDataStorage _storageEngine; + + public bool StoreEitEvent(EitEvent eitEvent) + { + return _storageEngine.StoreEitEvent(eitEvent); + } + + public void StoreNitNetwork(NitNetwork nitNetwork) + { + _storageEngine.StoreNitNetwork(nitNetwork); + } + + public bool TestNitNetwork(NitNetwork nitNetwork) + { + return _storageEngine.TestNitNetwork(nitNetwork); + } + + public bool TestForNitTransportStream(ushort networkId, NitTransportStream transportStream) + { + return _storageEngine.TestForNitTransportStream(networkId, transportStream); + } + + public void StoreNitTransportStream(ushort networkId, NitTransportStream transportStream) + { + _storageEngine.StoreNitTransportStream(networkId, transportStream); + } + } + + internal class FreesatTunnelDataStorageInMemory : IFreesatTunnelDataStorage + { + private HashSet _eitEvents; + public bool StoreEitEvent(EitEvent eitEvent) + { + if (_eitEvents == null) + _eitEvents = new HashSet(); + + return _eitEvents.Add(eitEvent); + } + + private NitNetwork[] _nitNetworks; + public void StoreNitNetwork(NitNetwork nitNetwork) + { + if (_nitNetworks == null) + _nitNetworks = new NitNetwork[ushort.MaxValue]; + + _nitNetworks[nitNetwork.NetworkId] = nitNetwork; + } + + public bool TestNitNetwork(NitNetwork nitNetwork) + { + if (_nitNetworks == null) + return false; + + return _nitNetworks[nitNetwork.NetworkId] != null; + } + + private NitTransportStream[][] _nitTransportStreams; + public bool TestForNitTransportStream(ushort networkId, NitTransportStream transportStream) + { + if (_nitTransportStreams == null) + return false; + if (_nitTransportStreams[networkId] == null) + return false; + + return _nitTransportStreams[networkId][transportStream.TransportStreamId] != null; + } + + public void StoreNitTransportStream(ushort networkId, NitTransportStream transportStream) + { + if (_nitTransportStreams == null) + _nitTransportStreams = new NitTransportStream[ushort.MaxValue][]; + if (_nitTransportStreams[networkId] == null) + _nitTransportStreams[networkId] = new NitTransportStream[ushort.MaxValue]; + } + } +} diff --git a/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatTunnelScraper.cs b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatTunnelScraper.cs new file mode 100644 index 0000000..145eccc --- /dev/null +++ b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/SkyscraperSide/FreesatTunnelScraper.cs @@ -0,0 +1,115 @@ +using skyscraper5.Dvb.Descriptors; +using skyscraper5.Dvb.Psi; +using skyscraper5.Dvb.Psi.Model; +using skyscraper8.EPGCollectorPort.SkyscraperSide; +using skyscraper8.Skyscraper.Scraper.Storage; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using skyscraper8.Skyscraper.Plugins; + +namespace skyscraper5.Skyscraper.Scraper +{ + internal class FreesatTunnelScraper : IBatEventHandler, ISdtEventHandler, ITdtEventHandler, ITotEventHandler, IEitEventHandler, INitEventHandler + { + public void OnBatBouquet(BatBouquet batBouquet) + { + throw new NotImplementedException(); + } + + public void OnBatTransportStream(BatBouquet batBouquet, BatTransportStream child) + { + throw new NotImplementedException(); + } + + public void OnSdtService(ushort transportStreamId, ushort originalNetworkId, SdtService sdtService) + { + throw new NotImplementedException(); + } + + public void OnTdtTime(DateTime utcTime) + { + if (!networkId.HasValue) + return; + if (!transportStreamId.HasValue) + return; + + throw new NotImplementedException(); + } + + public void OnTotTime(DateTime utcTime, LocalTimeOffsetDescriptor ltod) + { + if (!networkId.HasValue) + return; + if (!transportStreamId.HasValue) + return; + + throw new NotImplementedException(); + } + + private ushort? networkId; + public void SetNetworkId(ushort networkId) + { + throw new NotImplementedException(); + } + + private ushort? transportStreamId; + public void SetTransportStreamId(ushort transportStreamId) + { + throw new NotImplementedException(); + } + + public void SetNetworkId(ushort networkId, bool forceOverwrite = false) + { + throw new NotImplementedException(); + } + + public void OnNitTransportStream(ushort networkId, NitTransportStream transportStream) + { + if (!_dataStorage.TestForNitTransportStream(networkId, transportStream)) + { + _logger.Log(PluginLogLevel.Info, "NIT Network {0} Transport Stream {1}", networkId, transportStream.TransportStreamId); + _dataStorage.StoreNitTransportStream(networkId, transportStream); + } + } + + public void OnNitNetwork(NitNetwork nitNetwork) + { + if (!_dataStorage.TestNitNetwork(nitNetwork)) + { + _logger.Log(PluginLogLevel.Info, "NIT Network {0}", nitNetwork.NetworkId); + _dataStorage.StoreNitNetwork(nitNetwork); + } + } + + private EitEvent[] runningEvents; + public void OnEitEvent(EitEvent eitEvent) + { + if (_dataStorage.StoreEitEvent(eitEvent)) + { + _logger.Log(PluginLogLevel.Info, "EIT Event: {0}", eitEvent.EventName); + } + + if (eitEvent.RunningStatus == RunningStatus.Running) + { + if (runningEvents == null) + runningEvents = new EitEvent[UInt16.MaxValue]; + runningEvents[eitEvent.ServiceId] = eitEvent; + } + } + + private PluginLogger _logger; + private IFreesatTunnelDataStorage _dataStorage; + public void ConnectToStorage(object[] getPluginConnector) + { + if (_dataStorage == null) + { + _dataStorage = new FreesatTunnelDataStorage(getPluginConnector); + } + + _logger = PluginLogManager.GetLogger(this.GetType()); + } + } +} diff --git a/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/skyscraper8.EPGCollectorPort.csproj b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/skyscraper8.EPGCollectorPort.csproj new file mode 100644 index 0000000..12072fa --- /dev/null +++ b/PrivateDataSpecifiers/skyscraper8.EPGCollectorPort/skyscraper8.EPGCollectorPort.csproj @@ -0,0 +1,28 @@ + + + + net8.0 + enable + enable + + + + + + + + + True + True + Resources.resx + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + diff --git a/skyscraper8.sln b/skyscraper8.sln index 01fc13c..a3c1471 100644 --- a/skyscraper8.sln +++ b/skyscraper8.sln @@ -59,6 +59,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "skyscraper5.UI.WindowsForms EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "skyscraper8.UI.ImGui", "GUIs\skyscraper8.UI.ImGui\skyscraper8.UI.ImGui.csproj", "{BDBDB7A9-D0A4-9B89-0801-2935B2066551}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "skyscraper8.EPGCollectorPort", "PrivateDataSpecifiers\skyscraper8.EPGCollectorPort\skyscraper8.EPGCollectorPort.csproj", "{CF21D250-9804-4191-89F5-95821E3AF39D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -145,6 +147,10 @@ Global {BDBDB7A9-D0A4-9B89-0801-2935B2066551}.Debug|Any CPU.Build.0 = Debug|Any CPU {BDBDB7A9-D0A4-9B89-0801-2935B2066551}.Release|Any CPU.ActiveCfg = Release|Any CPU {BDBDB7A9-D0A4-9B89-0801-2935B2066551}.Release|Any CPU.Build.0 = Release|Any CPU + {CF21D250-9804-4191-89F5-95821E3AF39D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CF21D250-9804-4191-89F5-95821E3AF39D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CF21D250-9804-4191-89F5-95821E3AF39D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CF21D250-9804-4191-89F5-95821E3AF39D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -168,6 +174,7 @@ Global {8F17668C-623C-F9B3-EAD4-2922E5414B75} = {E00647B6-4509-4A1C-A7CB-D0C72325D23E} {46CACA1C-F9B2-2FE0-2068-716F381325E9} = {E23457C5-3A34-48EE-8107-C91E2C174B2D} {BDBDB7A9-D0A4-9B89-0801-2935B2066551} = {E23457C5-3A34-48EE-8107-C91E2C174B2D} + {CF21D250-9804-4191-89F5-95821E3AF39D} = {56729C39-B90E-4DF3-A557-DB93436FB5FF} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {5147EFA3-3D4E-4FDE-8A36-5840E8F1B80E} diff --git a/skyscraper8/Dvb/Psi/BatEventHandler.cs b/skyscraper8/Dvb/Psi/BatEventHandler.cs index 8aaa399..1632c53 100644 --- a/skyscraper8/Dvb/Psi/BatEventHandler.cs +++ b/skyscraper8/Dvb/Psi/BatEventHandler.cs @@ -7,7 +7,7 @@ using skyscraper5.Dvb.Psi.Model; namespace skyscraper5.Dvb.Psi { - interface IBatEventHandler + public interface IBatEventHandler { void OnBatBouquet(BatBouquet batBouquet); void OnBatTransportStream(BatBouquet batBouquet, BatTransportStream child); diff --git a/skyscraper8/Dvb/Psi/EitEventHandler.cs b/skyscraper8/Dvb/Psi/EitEventHandler.cs index ab1a807..faad52a 100644 --- a/skyscraper8/Dvb/Psi/EitEventHandler.cs +++ b/skyscraper8/Dvb/Psi/EitEventHandler.cs @@ -2,7 +2,7 @@ namespace skyscraper5.Dvb.Psi { - interface IEitEventHandler + public interface IEitEventHandler { void SetTransportStreamId(ushort transportStreamId); void SetNetworkId(ushort networkId, bool forceOverwrite = false); diff --git a/skyscraper8/Dvb/Psi/EitParser.cs b/skyscraper8/Dvb/Psi/EitParser.cs index b5a74a0..6752843 100644 --- a/skyscraper8/Dvb/Psi/EitParser.cs +++ b/skyscraper8/Dvb/Psi/EitParser.cs @@ -12,7 +12,7 @@ using skyscraper5.Skyscraper.Plugins; namespace skyscraper5.Dvb.Psi { - class EitParser : IPsiProcessor + public class EitParser : IPsiProcessor { public EitParser(IEitEventHandler eventHandler) { diff --git a/skyscraper8/Dvb/Psi/NitEventHandler.cs b/skyscraper8/Dvb/Psi/NitEventHandler.cs index 7a52203..fbfb60b 100644 --- a/skyscraper8/Dvb/Psi/NitEventHandler.cs +++ b/skyscraper8/Dvb/Psi/NitEventHandler.cs @@ -7,7 +7,7 @@ using skyscraper5.Dvb.Psi.Model; namespace skyscraper5.Dvb.Psi { - interface INitEventHandler + public interface INitEventHandler { void SetNetworkId(ushort networkId, bool forceOverrite = false); void OnNitTransportStream(ushort networkId, NitTransportStream transportStream); diff --git a/skyscraper8/Dvb/Psi/NitParser.cs b/skyscraper8/Dvb/Psi/NitParser.cs index 0619eb4..6cfd7e9 100644 --- a/skyscraper8/Dvb/Psi/NitParser.cs +++ b/skyscraper8/Dvb/Psi/NitParser.cs @@ -12,7 +12,7 @@ using skyscraper5.Skyscraper.Plugins; namespace skyscraper5.Dvb.Psi { - class NitParser : IPsiProcessor + public class NitParser : IPsiProcessor { public INitEventHandler EventHandler { get; } diff --git a/skyscraper8/Dvb/Psi/SdtEventHandler.cs b/skyscraper8/Dvb/Psi/SdtEventHandler.cs index 8fb0ab0..bfb93c0 100644 --- a/skyscraper8/Dvb/Psi/SdtEventHandler.cs +++ b/skyscraper8/Dvb/Psi/SdtEventHandler.cs @@ -7,7 +7,7 @@ using skyscraper5.Dvb.Psi.Model; namespace skyscraper5.Dvb.Psi { - interface ISdtEventHandler + public interface ISdtEventHandler { void OnSdtService(ushort transportStreamId, ushort originalNetworkId, SdtService sdtService); void SetNetworkId(ushort networkId); diff --git a/skyscraper8/Dvb/Psi/TdtParserHandler.cs b/skyscraper8/Dvb/Psi/TdtParserHandler.cs index 0d303df..e192905 100644 --- a/skyscraper8/Dvb/Psi/TdtParserHandler.cs +++ b/skyscraper8/Dvb/Psi/TdtParserHandler.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace skyscraper5.Dvb.Psi { - interface ITdtEventHandler + public interface ITdtEventHandler { void OnTdtTime(DateTime utcTime); } diff --git a/skyscraper8/Dvb/Psi/TimetableParser.cs b/skyscraper8/Dvb/Psi/TimetableParser.cs index 50ddae0..028aa9a 100644 --- a/skyscraper8/Dvb/Psi/TimetableParser.cs +++ b/skyscraper8/Dvb/Psi/TimetableParser.cs @@ -10,7 +10,7 @@ using skyscraper5.Skyscraper.IO; namespace skyscraper5.Dvb.Psi { - class TimetableParser : IPsiProcessor + public class TimetableParser : IPsiProcessor { public ITdtEventHandler TdtEventHandler { get; } public ITotEventHandler TotEventHandler { get; } diff --git a/skyscraper8/Dvb/Psi/TotEventHandler.cs b/skyscraper8/Dvb/Psi/TotEventHandler.cs index 24732fe..26bd69f 100644 --- a/skyscraper8/Dvb/Psi/TotEventHandler.cs +++ b/skyscraper8/Dvb/Psi/TotEventHandler.cs @@ -7,7 +7,7 @@ using skyscraper5.Dvb.Descriptors; namespace skyscraper5.Dvb.Psi { - interface ITotEventHandler + public interface ITotEventHandler { void OnTotTime(DateTime utcTime, LocalTimeOffsetDescriptor ltod); } diff --git a/skyscraper8/Properties/launchSettings.json b/skyscraper8/Properties/launchSettings.json index 21e5d76..0124982 100644 --- a/skyscraper8/Properties/launchSettings.json +++ b/skyscraper8/Properties/launchSettings.json @@ -2,6 +2,7 @@ "profiles": { "skyscraper8": { "commandName": "Project", + "commandLineArgs": "\"Z:\\Freebies\\Datasets\\SkyscraperLibrarian\\DVB-S August 2024\\Astra28\\skyscraper_20240829_0651_0283E_10714_H_21999.ts\"", "remoteDebugEnabled": false }, "Container (Dockerfile)": { diff --git a/skyscraper8/Ses/SgtCandidate.cs b/skyscraper8/Ses/SgtCandidate.cs index f530edc..0eb03bf 100644 --- a/skyscraper8/Ses/SgtCandidate.cs +++ b/skyscraper8/Ses/SgtCandidate.cs @@ -25,6 +25,11 @@ namespace skyscraper8.Ses skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new PsiDecoder(pid, new SgtParser(skyscraperContext))); } + public override void Introduce(ProgramContext programContext) + { + + } + public override void Dispose() { } diff --git a/skyscraper8/Skyscraper/Plugins/PluginLogger.cs b/skyscraper8/Skyscraper/Plugins/PluginLogger.cs index f96eacf..20de0b7 100644 --- a/skyscraper8/Skyscraper/Plugins/PluginLogger.cs +++ b/skyscraper8/Skyscraper/Plugins/PluginLogger.cs @@ -41,7 +41,7 @@ namespace skyscraper8.Skyscraper.Plugins Logger.DebugFormat(message, a); break; case PluginLogLevel.All: - Console.WriteLine(message, a); + //Console.WriteLine(message, a); break; default: throw new NotImplementedException(level.ToString()); diff --git a/skyscraper8/Skyscraper/Plugins/PluginManager.cs b/skyscraper8/Skyscraper/Plugins/PluginManager.cs index 79658db..e76bfed 100644 --- a/skyscraper8/Skyscraper/Plugins/PluginManager.cs +++ b/skyscraper8/Skyscraper/Plugins/PluginManager.cs @@ -18,6 +18,7 @@ using System.IO; using System.Linq; using System.Reflection; using skyscraper8.Skyscraper.Scraper.Storage; +using skyscraper8.Skyscraper.Text; namespace skyscraper5.Skyscraper.Plugins { @@ -157,6 +158,7 @@ namespace skyscraper5.Skyscraper.Plugins private Type gpsReceiverFactoryType = typeof(IGpsReceiverFactory); private Type streamTypeAutodetectionContestantType = typeof(Contestant); private Type filesystemProcessorType = typeof(FilesystemProcessorPlugin); + private Type textDecoderType = typeof(TextDecoder); private PluginPrioritySorter sorter = new PluginPrioritySorter(); private List _dnsParsers; @@ -172,6 +174,7 @@ namespace skyscraper5.Skyscraper.Plugins private Tuple[] _extensionDescriptors; private ConstructorInfo[] _dsmCcMessages; private ConstructorInfo[] _mpeg2ExtensionDescriptors; + private TextDecoder[] _textDecoders; private void ScanAssembly(Assembly assembly) { @@ -272,13 +275,39 @@ namespace skyscraper5.Skyscraper.Plugins HandleFilesystemProcessor(type); continue; } + else if (type.IsAssignableTo(textDecoderType)) + { + HandleTextDecoder(type); + continue; + } - throw new NotImplementedException(); + throw new NotImplementedException(); } _mpePlugins.Sort(sorter); } + private void HandleTextDecoder(Type type) + { + List idAttributes = type.GetCustomAttributes().ToList(); + if (idAttributes == null || idAttributes.Count == 0) + { + logger.ErrorFormat("{0} does not have any {1}", type.Name, nameof(EncodingTypeIdAttribute)); + return; + } + + if (_textDecoders == null) + _textDecoders = new TextDecoder[byte.MaxValue]; + + object instance = Activator.CreateInstance(type); + TextDecoder textDecoder = (TextDecoder)instance; + foreach (EncodingTypeIdAttribute attribute in idAttributes) + { + logger.DebugFormat("Text Decoder 0x{0:X2} is {1}", attribute.Id, type.Name); + _textDecoders[attribute.Id] = textDecoder; + } + } + #region Scraper Storages private Dictionary _dataStorages; @@ -668,5 +697,12 @@ namespace skyscraper5.Skyscraper.Plugins propertyInfo.SetValue(targetObject, toSet); } } + + public TextDecoder[] GetTextDecoders() + { + object clone = _textDecoders.Clone(); + TextDecoder[] saneClone = (TextDecoder[])clone; + return saneClone; + } } } diff --git a/skyscraper8/Skyscraper/Scraper/FreesatTunnelScraper.cs b/skyscraper8/Skyscraper/Scraper/FreesatTunnelScraper.cs deleted file mode 100644 index d696e6d..0000000 --- a/skyscraper8/Skyscraper/Scraper/FreesatTunnelScraper.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using skyscraper5.Dvb.Descriptors; -using skyscraper5.Dvb.Psi; -using skyscraper5.Dvb.Psi.Model; - -namespace skyscraper5.Skyscraper.Scraper -{ - internal class FreesatTunnelScraper : IBatEventHandler, ISdtEventHandler, ITdtEventHandler, ITotEventHandler - { - - private ushort? networkId; - private DateTime? currentDateTime; - - public void OnBatBouquet(BatBouquet batBouquet) - { - } - - public void OnBatTransportStream(BatBouquet batBouquet, BatTransportStream child) - { - } - - public void OnSdtService(ushort transportStreamId, ushort originalNetworkId, SdtService sdtService) - { - } - - public void OnTdtTime(DateTime utcTime) - { - this.currentDateTime = utcTime; - } - - public void OnTotTime(DateTime utcTime, LocalTimeOffsetDescriptor ltod) - { - this.currentDateTime = utcTime; - } - - public void SetNetworkId(ushort networkId) - { - this.networkId = networkId; - } - - public void SetTransportStreamId(ushort transportStreamId) - { - } - } -} diff --git a/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs b/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs index 987cfdf..9e51ef1 100644 --- a/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs +++ b/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs @@ -609,7 +609,11 @@ namespace skyscraper5.Skyscraper.Scraper StreamTypeAutodetection sta = new StreamTypeAutodetection(mappingStream.ElementaryPid, this); sta.ProgramContext.Program = result; sta.ProgramContext.Stream = mappingStream; - DvbContext.RegisterPacketProcessor(mappingStream.ElementaryPid, sta); + sta.IntroduceStreamToContestants(); + if (!sta.IsWinnerDetermined) + { + DvbContext.RegisterPacketProcessor(mappingStream.ElementaryPid, sta); + } break; case StreamType.IpMacNotification: IntParser intParser = new IntParser(this); @@ -1633,8 +1637,7 @@ namespace skyscraper5.Skyscraper.Scraper LogEvent(SkyscraperContextEvent.StationIdentification, stationIdentification); } } - - private FreesatTunnelScraper freesatTunnel; + public void AutodetectionSucessful(int pid, Contestant contestant, ProgramContext programContext) { UiJunction?.NotifyStreamTypeDetection(contestant.Tag, pid); @@ -2036,6 +2039,17 @@ namespace skyscraper5.Skyscraper.Scraper } } + if (_pluginContexts != null) + { + foreach (object plugin in _pluginContexts) + { + IDisposable disposable = plugin as IDisposable; + if (disposable != null) + disposable.Dispose(); + } + _pluginContexts.Clear(); + } + DataStorage.WaitForCompletion(); } @@ -2671,5 +2685,18 @@ namespace skyscraper5.Skyscraper.Scraper } } } - } + + private List _pluginContexts; + + public List PluginContext + { + get + { + if (_pluginContexts == null) + _pluginContexts = new List(); + + return _pluginContexts; + } + } + } } diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestant.cs index 6fc0013..e5052a9 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestant.cs @@ -35,5 +35,7 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection } public abstract void DeclareWinner(SkyscraperContext skyscraperContext, int pid, ProgramContext programContext); + + public abstract void Introduce(ProgramContext programContext); } } diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/AitContestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/AitContestant.cs index 30d2b1e..a23122a 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/AitContestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/AitContestant.cs @@ -33,5 +33,10 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants { skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new PsiDecoder(pid, new AitParser(skyscraperContext, programContext.ProgramNumber))); } + + public override void Introduce(ProgramContext programContext) + { + + } } } diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/BatContestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/BatContestant.cs index 823a9b2..f47f1b6 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/BatContestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/BatContestant.cs @@ -1,19 +1,23 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using log4net; using skyscraper5.Dvb.Psi; using skyscraper5.Dvb.Psi.Model; using skyscraper5.Mpeg2; using skyscraper5.Skyscraper.Plugins; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using skyscraper5.Skyscraper.Scraper.Utils; namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants { [SkyscraperPlugin] class BatContestant : Contestant, IBatEventHandler, IDisposable { - public BatContestant(int pid) : base("BAT", pid) + private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); + + public BatContestant(int pid) : base("BAT", pid) { PacketProcessor = new PsiDecoder(pid, new BatParser(this)); } @@ -35,7 +39,13 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants public override void DeclareWinner(SkyscraperContext skyscraperContext, int pid, ProgramContext programContext) { - throw new NotImplementedException(); + logger.ErrorFormat("{0} {1} not yet implemented", nameof(BatContestant), nameof(DeclareWinner)); + skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new PacketDiscarder()); + } + + public override void Introduce(ProgramContext programContext) + { + } } } diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/CatContestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/CatContestant.cs index 9714fc4..81f8061 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/CatContestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/CatContestant.cs @@ -32,5 +32,9 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants { throw new NotImplementedException(); } + + public override void Introduce(ProgramContext programContext) + { + } } } diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/DataCarouselContestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/DataCarouselContestant.cs index 50e57d5..097aef1 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/DataCarouselContestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/DataCarouselContestant.cs @@ -107,7 +107,12 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new PsiDecoder(pid, new DataCarouselDecoder(programContext.Stream, programContext.Program, DataCarouselIntention.NoIntention, skyscraperContext))); } - public void ProcessVirtualFilesystem(IFilesystem vfs, ProgramMappingStream pmtPid) + public override void Introduce(ProgramContext programContext) + { + + } + + public void ProcessVirtualFilesystem(IFilesystem vfs, ProgramMappingStream pmtPid) { } } diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/DisqualifiedContestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/DisqualifiedContestant.cs index 8fc1b27..1c698a3 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/DisqualifiedContestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/DisqualifiedContestant.cs @@ -25,5 +25,10 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants { throw new NotImplementedException(); } + + public override void Introduce(ProgramContext programContext) + { + + } } } diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/EitContestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/EitContestant.cs index 4dc77a7..9b7140f 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/EitContestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/EitContestant.cs @@ -51,5 +51,10 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants { skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new PsiDecoder(pid, new EitParser(skyscraperContext))); } + + public override void Introduce(ProgramContext programContext) + { + + } } } diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/Id3Contestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/Id3Contestant.cs index f3d449a..249163e 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/Id3Contestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/Id3Contestant.cs @@ -25,6 +25,11 @@ namespace skyscraper5.src.Skyscraper.Scraper.StreamAutodetection.Contestants throw new NotImplementedException(); } + public override void Introduce(ProgramContext programContext) + { + + } + public override void Dispose() { } diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/IntContestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/IntContestant.cs index cd4ce0d..6ec1d6b 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/IntContestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/IntContestant.cs @@ -28,6 +28,11 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants throw new NotImplementedException(); } + public override void Introduce(ProgramContext programContext) + { + + } + public void OnIpMacNotification(int sourcePid, Platform platform, Target target, Operational operational) { Score++; diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/InteractionChannelContestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/InteractionChannelContestant.cs index 520ae64..14f6737 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/InteractionChannelContestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/InteractionChannelContestant.cs @@ -30,6 +30,11 @@ namespace skyscraper5.src.Skyscraper.Scraper.StreamAutodetection.Contestants throw new NotImplementedException(); } + public override void Introduce(ProgramContext programContext) + { + + } + public override void Dispose() { diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/MpeContestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/MpeContestant.cs index 29f065a..f2f9330 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/MpeContestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/MpeContestant.cs @@ -30,6 +30,11 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new PsiDecoder(pid, new MultiprotocolEncapsulationDecoder(skyscraperContext))); } + public override void Introduce(ProgramContext programContext) + { + + } + public void OnIpv4PacketArrival(InternetHeader internetHeader, byte[] ipv4Packet) { Score++; diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/NitContestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/NitContestant.cs index 469b4cc..1263939 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/NitContestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/NitContestant.cs @@ -42,5 +42,10 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants { skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new PsiDecoder(pid, new NitParser(skyscraperContext))); } + + public override void Introduce(ProgramContext programContext) + { + + } } } diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/PatContestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/PatContestant.cs index 0e7a960..9ca7e70 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/PatContestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/PatContestant.cs @@ -41,5 +41,10 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants { throw new NotImplementedException(); } + + public override void Introduce(ProgramContext programContext) + { + + } } } diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/Pid0x11Contestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/Pid0x11Contestant.cs index 2ba181a..3ff9c32 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/Pid0x11Contestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/Pid0x11Contestant.cs @@ -1,12 +1,14 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using log4net; using skyscraper5.Dvb.Psi; using skyscraper5.Dvb.Psi.Model; using skyscraper5.Mpeg2; using skyscraper5.Skyscraper.Plugins; +using skyscraper5.Skyscraper.Scraper.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants { @@ -41,13 +43,21 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants } - public override void DeclareWinner(SkyscraperContext skyscraperContext, int pid, ProgramContext programContext) + private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); + public override void DeclareWinner(SkyscraperContext skyscraperContext, int pid, ProgramContext programContext) { - FreesatTunnelScraper fts = new FreesatTunnelScraper(); - skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new PsiDecoder(pid, new Pid0x11Decoder(fts, fts))); + //FreesatTunnelScraper fts = new FreesatTunnelScraper(); + //skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new PsiDecoder(pid, new Pid0x11Decoder(fts, fts))); + logger.ErrorFormat("{0} {1} not yet implemented", nameof(Pid0x11Contestant), nameof(DeclareWinner)); + skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new PacketDiscarder()); } - public void SetNetworkId(ushort networkId) + public override void Introduce(ProgramContext programContext) + { + + } + + public void SetNetworkId(ushort networkId) { } diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/PmtContestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/PmtContestant.cs index 61c6831..3c58743 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/PmtContestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/PmtContestant.cs @@ -32,5 +32,10 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants { skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new PsiDecoder(pid, new PmtParser(skyscraperContext))); } + + public override void Introduce(ProgramContext programContext) + { + + } } } diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/RdsContestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/RdsContestant.cs index fc392e9..45fc062 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/RdsContestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/RdsContestant.cs @@ -57,5 +57,10 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants { throw new NotImplementedException(); } + + public override void Introduce(ProgramContext programContext) + { + + } } } diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/Scte35Contestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/Scte35Contestant.cs index 34b316b..b0281b4 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/Scte35Contestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/Scte35Contestant.cs @@ -38,5 +38,10 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants { skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new PsiDecoder(pid, new Scte35SiDecoder(programContext.ProgramNumber, skyscraperContext))); } + + public override void Introduce(ProgramContext programContext) + { + + } } } diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/SdtContestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/SdtContestant.cs index 39717f9..0f951c9 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/SdtContestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/SdtContestant.cs @@ -33,6 +33,11 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new PsiDecoder(pid, new SdtParser(skyscraperContext))); } + public override void Introduce(ProgramContext programContext) + { + + } + public void SetNetworkId(ushort networkId) { } diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/SubtitleContestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/SubtitleContestant.cs index ef2092a..599f5c7 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/SubtitleContestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/SubtitleContestant.cs @@ -34,5 +34,10 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants pesDecoder.Tag = "subs"; skyscraperContext.DvbContext.RegisterPacketProcessor(pid, pesDecoder); } + + public override void Introduce(ProgramContext programContext) + { + + } } } diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/T2MiContestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/T2MiContestant.cs index a1b2673..f163ab8 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/T2MiContestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/T2MiContestant.cs @@ -28,6 +28,11 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new T2MIDecoder(pid, skyscraperContext)); } + public override void Introduce(ProgramContext programContext) + { + + } + public void OnT2MiPacketLoss(int pid, byte expectedPacket, T2MIHeader header) { if (Score > 0) diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/TeletextContestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/TeletextContestant.cs index 865c79a..bb078ac 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/TeletextContestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/TeletextContestant.cs @@ -54,7 +54,12 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new PesDecoder(ttp)); } - public void OnMonochromeData(int networkId, int transportStreamId, ushort programNumber, MonochromeDataField result) + public override void Introduce(ProgramContext programContext) + { + + } + + public void OnMonochromeData(int networkId, int transportStreamId, ushort programNumber, MonochromeDataField result) { Score++; } diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/TimeContestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/TimeContestant.cs index 84c1927..7d2a279 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/TimeContestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/TimeContestant.cs @@ -3,10 +3,12 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using log4net; using skyscraper5.Dvb.Descriptors; using skyscraper5.Dvb.Psi; using skyscraper5.Mpeg2; using skyscraper5.Skyscraper.Plugins; +using skyscraper5.Skyscraper.Scraper.Utils; namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants { @@ -33,10 +35,16 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants } + private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); public override void DeclareWinner(SkyscraperContext skyscraperContext, int pid, ProgramContext programContext) { - FreesatTunnelScraper fts = new FreesatTunnelScraper(); - skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new PsiDecoder(pid, new Pid0x11Decoder(fts, fts))); - } + logger.ErrorFormat("{0} {1} not yet implemented", nameof(TimeContestant), nameof(DeclareWinner)); + skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new PacketDiscarder()); + } + + public override void Introduce(ProgramContext programContext) + { + + } } } diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/TsdtContestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/TsdtContestant.cs index ac6b224..799a88b 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/TsdtContestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/TsdtContestant.cs @@ -37,5 +37,10 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants { skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new PsiDecoder(pid, new TsdtParser(skyscraperContext))); } + + public override void Introduce(ProgramContext programContext) + { + + } } } diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/UntContestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/UntContestant.cs index 4309d36..3f38315 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/UntContestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/UntContestant.cs @@ -34,5 +34,10 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants { throw new NotImplementedException(); } + + public override void Introduce(ProgramContext programContext) + { + + } } } diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/ProgramContext.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/ProgramContext.cs index bf2194c..9024384 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/ProgramContext.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/ProgramContext.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using skyscraper5.Mpeg2.Descriptors; using skyscraper5.Mpeg2.Psi.Model; namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection @@ -25,5 +26,16 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection return null; } } + + public UserDefinedDescriptor GetFirstUserDefinedDescriptor() + { + if (Stream == null) + return null; + if (Stream.UnknownUserDefines == null) + return null; + if (Stream.UnknownUserDefines.Count == 0) + return null; + return Stream.UnknownUserDefines[0]; + } } } diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/StreamTypeAutodetection.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/StreamTypeAutodetection.cs index 4ecbcbb..b4524fb 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/StreamTypeAutodetection.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/StreamTypeAutodetection.cs @@ -1,17 +1,18 @@ -using System; +using skyscraper5.Mpeg2; +using skyscraper5.Mpeg2.Psi; +using skyscraper5.Skyscraper.IO; +using skyscraper5.Skyscraper.Plugins; +using skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants; +using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.Linq; +using System.Net.Sockets; using System.Reflection; using System.Text; using System.Threading.Tasks; -using skyscraper5.Mpeg2; -using skyscraper5.Mpeg2.Psi; -using skyscraper5.Skyscraper.IO; -using skyscraper5.Skyscraper.Plugins; -using skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants; namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection { @@ -71,21 +72,30 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection } } - if (SomethingHappened()) - { - Array.Sort(Scoreboard, (x, y) => y.Score.CompareTo(x.Score)); - Contestant leader = Scoreboard[0]; - Contestant runnerUp = Scoreboard[1]; - long scoreDifference = leader.Score - runnerUp.Score; - if (scoreDifference > 5) - { - EventHandler.AutodetectionSucessful(Pid, leader, ProgramContext); - winnerDetermined = true; - Dispose(); - } - } + CheckWinner(); } - + + private bool CheckWinner() + { + bool result = false; + if (SomethingHappened()) + { + Array.Sort(Scoreboard, (x, y) => y.Score.CompareTo(x.Score)); + Contestant leader = Scoreboard[0]; + Contestant runnerUp = Scoreboard[1]; + long scoreDifference = leader.Score - runnerUp.Score; + if (scoreDifference > 5) + { + EventHandler.AutodetectionSucessful(Pid, leader, ProgramContext); + winnerDetermined = true; + Dispose(); + result = true; + } + } + + return result; + } + private bool SomethingHappened() { foreach (Contestant contestant in Scoreboard) @@ -140,5 +150,36 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection payloadUnitDecoder.PacketLoss(); } } + + public void IntroduceStreamToContestants() + { + foreach (Contestant contestant in Scoreboard) + { + contestant.Introduce(ProgramContext); + } + bool hasWinners = CheckWinner(); + + if (!hasWinners) + { + //No winners? How about losers? + for (int i = 0; i < Scoreboard.Length; i++) + { + if (Scoreboard[i].Score <= -10) + { + //Console.WriteLine("PID 0x{0:X4} is probably not for {1}", Pid, Scoreboard[i].GetType().Name); + EventHandler.AutodetectionRuleOut(Pid, Scoreboard[i], ProgramContext); + Scoreboard[i] = new DisqualifiedContestant(Scoreboard[i].Pid); + } + } + } + } + + public bool IsWinnerDetermined + { + get + { + return winnerDetermined; + } + } } } diff --git a/skyscraper8/Skyscraper/Text/En300468TextDecoder.cs b/skyscraper8/Skyscraper/Text/En300468TextDecoder.cs index e11adfc..c0c1950 100644 --- a/skyscraper8/Skyscraper/Text/En300468TextDecoder.cs +++ b/skyscraper8/Skyscraper/Text/En300468TextDecoder.cs @@ -1,6 +1,8 @@ using System; using System.Text; using skyscraper5.Dvb; +using skyscraper5.Skyscraper.Plugins; +using skyscraper8.Skyscraper.Text; namespace skyscraper5.Skyscraper.Text { @@ -50,6 +52,7 @@ namespace skyscraper5.Skyscraper.Text private static En300468AnnexATextDecoder _instance; private static Encoding[] tables; private static Encoding[] iso8859Mapping; + private static TextDecoder[] _textDecoders; public static En300468AnnexATextDecoder GetInstance() { @@ -104,14 +107,14 @@ namespace skyscraper5.Skyscraper.Text else if (buffer[0] == 0x1f) { //It shall be coded according to ETSI TS 101 162 - switch (buffer[1]) + if (_textDecoders == null) + _textDecoders = PluginManager.GetInstance().GetTextDecoders(); + TextDecoder matchingTextDecoder = _textDecoders[buffer[1]]; + if (matchingTextDecoder == null) { - case 0x01: //BBC, undocumented - but their Freesat Patch might help: https://www.rst38.org.uk/vdr/ - case 0x02: - return null; - default: - throw new NotImplementedException(String.Format("Encoding type ID 0x{0:X2}", buffer[1])); + throw new TextException(String.Format("No decoder for Encoding type ID 0x{0:X2}", buffer[1])); } + return matchingTextDecoder.Decode(buffer); } else if (buffer[0] >= 0x16 && buffer[0] <= 0x1e) { diff --git a/skyscraper8/Skyscraper/Text/EncodingTypeId.cs b/skyscraper8/Skyscraper/Text/EncodingTypeId.cs new file mode 100644 index 0000000..e4b076f --- /dev/null +++ b/skyscraper8/Skyscraper/Text/EncodingTypeId.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper8.Skyscraper.Text +{ + [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)] + public sealed class EncodingTypeIdAttribute : Attribute + { + public byte Id { get; } + + public EncodingTypeIdAttribute(byte id) + { + Id = id; + } + } +} diff --git a/skyscraper8/Skyscraper/Text/TextDecoder.cs b/skyscraper8/Skyscraper/Text/TextDecoder.cs new file mode 100644 index 0000000..0d48ca9 --- /dev/null +++ b/skyscraper8/Skyscraper/Text/TextDecoder.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper8.Skyscraper.Text +{ + + public interface TextDecoder + { + string Decode(byte[] buffer); + } +} diff --git a/skyscraper8/Skyscraper/Text/TextException.cs b/skyscraper8/Skyscraper/Text/TextException.cs new file mode 100644 index 0000000..9b05829 --- /dev/null +++ b/skyscraper8/Skyscraper/Text/TextException.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper8.Skyscraper.Text +{ + public class TextException : SkyscraperCoreException + { + public TextException() + { + } + + public TextException(string message) : base(message) + { + } + + public TextException(string message, Exception inner) : base(message, inner) + { + } + } +}