Browse Source

Add translated QSP Analyzer to QSP Tools folder (with source)

Marou 7 years ago
parent
commit
e139949dc1
57 changed files with 7565 additions and 0 deletions
  1. BIN
      QSP/qsp-analyser/QSP_Analyser.exe
  2. 32 0
      QSP/qsp-analyser/QSP_Analyser.sln
  3. 1519 0
      QSP/qsp-analyser/QSP_Analyser/Common.cs
  4. 667 0
      QSP/qsp-analyser/QSP_Analyser/List.txt
  5. 609 0
      QSP/qsp-analyser/QSP_Analyser/MainForm.Designer.cs
  6. 556 0
      QSP/qsp-analyser/QSP_Analyser/MainForm.cs
  7. 123 0
      QSP/qsp-analyser/QSP_Analyser/MainForm.resx
  8. 20 0
      QSP/qsp-analyser/QSP_Analyser/Program.cs
  9. 36 0
      QSP/qsp-analyser/QSP_Analyser/Properties/AssemblyInfo.cs
  10. 63 0
      QSP/qsp-analyser/QSP_Analyser/Properties/Resources.Designer.cs
  11. 117 0
      QSP/qsp-analyser/QSP_Analyser/Properties/Resources.resx
  12. 281 0
      QSP/qsp-analyser/QSP_Analyser/Properties/Settings.Designer.cs
  13. 172 0
      QSP/qsp-analyser/QSP_Analyser/Properties/Settings.settings
  14. 26 0
      QSP/qsp-analyser/QSP_Analyser/Properties/app.manifest
  15. 2233 0
      QSP/qsp-analyser/QSP_Analyser/QSPGameCode.cs
  16. 141 0
      QSP/qsp-analyser/QSP_Analyser/QSP_Analyser.csproj
  17. 16 0
      QSP/qsp-analyser/QSP_Analyser/QSP_Analyser.csproj.user
  18. 28 0
      QSP/qsp-analyser/QSP_Analyser/Settings.cs
  19. 178 0
      QSP/qsp-analyser/QSP_Analyser/app.config
  20. 18 0
      QSP/qsp-analyser/QSP_Analyser/bin/Debug/QSP_Analyser.application
  21. BIN
      QSP/qsp-analyser/QSP_Analyser/bin/Debug/QSP_Analyser.exe
  22. 178 0
      QSP/qsp-analyser/QSP_Analyser/bin/Debug/QSP_Analyser.exe.config
  23. 64 0
      QSP/qsp-analyser/QSP_Analyser/bin/Debug/QSP_Analyser.exe.manifest
  24. BIN
      QSP/qsp-analyser/QSP_Analyser/bin/Debug/QSP_Analyser.pdb
  25. BIN
      QSP/qsp-analyser/QSP_Analyser/bin/Debug/app.publish/QSP_Analyser.exe
  26. 18 0
      QSP/qsp-analyser/QSP_Analyser/bin/Release/QSP_Analyser.application
  27. BIN
      QSP/qsp-analyser/QSP_Analyser/bin/Release/QSP_Analyser.exe
  28. 178 0
      QSP/qsp-analyser/QSP_Analyser/bin/Release/QSP_Analyser.exe.config
  29. 64 0
      QSP/qsp-analyser/QSP_Analyser/bin/Release/QSP_Analyser.exe.manifest
  30. BIN
      QSP/qsp-analyser/QSP_Analyser/bin/Release/QSP_Analyser.pdb
  31. BIN
      QSP/qsp-analyser/QSP_Analyser/bin/Release/app.publish/QSP_Analyser.exe
  32. BIN
      QSP/qsp-analyser/QSP_Analyser/obj/Debug/Analyser.MainForm.resources
  33. BIN
      QSP/qsp-analyser/QSP_Analyser/obj/Debug/Analyser.Properties.Resources.resources
  34. 1 0
      QSP/qsp-analyser/QSP_Analyser/obj/Debug/CoreCompileInputs.cache
  35. BIN
      QSP/qsp-analyser/QSP_Analyser/obj/Debug/DesignTimeResolveAssemblyReferences.cache
  36. BIN
      QSP/qsp-analyser/QSP_Analyser/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache
  37. 11 0
      QSP/qsp-analyser/QSP_Analyser/obj/Debug/QSP_Analyser.TrustInfo.xml
  38. 18 0
      QSP/qsp-analyser/QSP_Analyser/obj/Debug/QSP_Analyser.application
  39. 27 0
      QSP/qsp-analyser/QSP_Analyser/obj/Debug/QSP_Analyser.csproj.FileListAbsolute.txt
  40. BIN
      QSP/qsp-analyser/QSP_Analyser/obj/Debug/QSP_Analyser.csproj.GenerateResource.Cache
  41. BIN
      QSP/qsp-analyser/QSP_Analyser/obj/Debug/QSP_Analyser.csprojResolveAssemblyReference.cache
  42. BIN
      QSP/qsp-analyser/QSP_Analyser/obj/Debug/QSP_Analyser.exe
  43. 64 0
      QSP/qsp-analyser/QSP_Analyser/obj/Debug/QSP_Analyser.exe.manifest
  44. BIN
      QSP/qsp-analyser/QSP_Analyser/obj/Debug/QSP_Analyser.pdb
  45. BIN
      QSP/qsp-analyser/QSP_Analyser/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll
  46. BIN
      QSP/qsp-analyser/QSP_Analyser/obj/Release/Analyser.MainForm.resources
  47. BIN
      QSP/qsp-analyser/QSP_Analyser/obj/Release/Analyser.Properties.Resources.resources
  48. 1 0
      QSP/qsp-analyser/QSP_Analyser/obj/Release/CoreCompileInputs.cache
  49. BIN
      QSP/qsp-analyser/QSP_Analyser/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache
  50. 11 0
      QSP/qsp-analyser/QSP_Analyser/obj/Release/QSP_Analyser.TrustInfo.xml
  51. 18 0
      QSP/qsp-analyser/QSP_Analyser/obj/Release/QSP_Analyser.application
  52. 13 0
      QSP/qsp-analyser/QSP_Analyser/obj/Release/QSP_Analyser.csproj.FileListAbsolute.txt
  53. BIN
      QSP/qsp-analyser/QSP_Analyser/obj/Release/QSP_Analyser.csproj.GenerateResource.Cache
  54. BIN
      QSP/qsp-analyser/QSP_Analyser/obj/Release/QSP_Analyser.exe
  55. 64 0
      QSP/qsp-analyser/QSP_Analyser/obj/Release/QSP_Analyser.exe.manifest
  56. BIN
      QSP/qsp-analyser/QSP_Analyser/obj/Release/QSP_Analyser.pdb
  57. BIN
      QSP/qsp-analyser/QSP_Analyser/obj/Release/TempPE/Properties.Resources.Designer.cs.dll

BIN
QSP/qsp-analyser/QSP_Analyser.exe


+ 32 - 0
QSP/qsp-analyser/QSP_Analyser.sln

@@ -0,0 +1,32 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26430.16
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QSP_Analyser", "QSP_Analyser\QSP_Analyser.csproj", "{0EB1C8F9-E5A2-4C13-8ED2-C1897332F197}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Debug|Mixed Platforms = Debug|Mixed Platforms
+		Debug|Win32 = Debug|Win32
+		Release|Any CPU = Release|Any CPU
+		Release|Mixed Platforms = Release|Mixed Platforms
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{0EB1C8F9-E5A2-4C13-8ED2-C1897332F197}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{0EB1C8F9-E5A2-4C13-8ED2-C1897332F197}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{0EB1C8F9-E5A2-4C13-8ED2-C1897332F197}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{0EB1C8F9-E5A2-4C13-8ED2-C1897332F197}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+		{0EB1C8F9-E5A2-4C13-8ED2-C1897332F197}.Debug|Win32.ActiveCfg = Debug|Any CPU
+		{0EB1C8F9-E5A2-4C13-8ED2-C1897332F197}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{0EB1C8F9-E5A2-4C13-8ED2-C1897332F197}.Release|Any CPU.Build.0 = Release|Any CPU
+		{0EB1C8F9-E5A2-4C13-8ED2-C1897332F197}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{0EB1C8F9-E5A2-4C13-8ED2-C1897332F197}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+		{0EB1C8F9-E5A2-4C13-8ED2-C1897332F197}.Release|Win32.ActiveCfg = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

+ 1519 - 0
QSP/qsp-analyser/QSP_Analyser/Common.cs

@@ -0,0 +1,1519 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace Analyser
+{
+    public class Common
+    {
+        const int QSP_MAXSTATSNAMES = 100;
+        const int QSP_STATSLEVELS = 3;
+        const int QSP_STATMAXARGS = 10;
+	    const int QSP_OPSLEVELS = 2;
+	    const int QSP_MAXOPSNAMES = 100;
+        const int QSP_OPMAXARGS = 10;
+	    public const int QSP_STACKSIZE = 30;
+        public const int QSP_MAXITEMS = 100;
+
+        public const int INVALID_INDEX = -1;
+        static public char[] WhiteSpace = {' ', '\t', '\r', '\n'};
+        //Разделители - " \t&'\"()[]=!<>+-/*:,{}"
+        static public char[] Delimiters = " \t&'\"()[]=!<>+-/*:,{}".ToCharArray();
+        static public char[] Digits = "0123456789".ToCharArray();
+        static public char[] LatinLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqsrtuvwxyz".ToCharArray();
+        static public char[] RussianLetters = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъьэюя".ToCharArray();
+        public struct QspStatement
+        {
+            public int ExtArg;
+            public int MinArgsCount;
+            public int MaxArgsCount;
+            public int[] ArgsTypes;
+        }
+        public struct QspStatementName
+        {
+            public string Name;
+            public int NameLen;
+            public int Code;
+        }
+        public enum QspStatementType
+        {
+            Unknown,
+            Label,
+            Comment,
+            Act,
+            For,
+            Local,
+            If,
+            ElseIf,
+            Else,
+            End,
+            AddObj,
+            ClA,
+            Clear,
+            CloseAll,
+            Close,
+            ClS,
+            CmdClear,
+            CopyArr,
+            DelAct,
+            DelObj,
+            Dynamic,
+            Exec,
+            Exit,
+            FreeLib,
+            GoSub,
+            GoTo,
+            IncLib,
+            Jump,
+            KillAll,
+            KillObj,
+            KillVar,
+            MClear,
+            Menu,
+            MNL,
+            MPL,
+            MP,
+            Msg,
+            NL,
+            OpenGame,
+            OpenQst,
+            Play,
+            PL,
+            P,
+            RefInt,
+            SaveGame,
+            SetTimer,
+            Set,
+            ShowActs,
+            ShowInput,
+            ShowObjs,
+            ShowVars,
+            UnSelect,
+            View,
+            Wait,
+            XGoTo,
+
+            Last_Statement
+        };
+
+        public struct QspFunction
+        {
+		    public int Priority;
+		    public int ResType;
+		    public int MinArgsCount;
+		    public int MaxArgsCount;
+		    public int[] ArgsTypes;
+        }
+        public struct QspFunctionName
+        {
+            public string Name;
+            public int NameLen;
+            public int Code;
+        }
+        public enum QspFunctionType
+        {
+            Unknown,
+            Start,
+            End,
+            Value,
+            OpenBracket,
+            Minus,
+            Comma,
+            CloseBracket,
+            Mul,
+            Div,
+            Add,
+            Sub,
+            Mod,
+            Ne,
+            Leq,
+            Geq,
+            Eq,
+            Lt,
+            Gt,
+            And,
+            Or,
+            Append,
+
+            First_Function,
+            Not = First_Function,
+            Loc,
+            Obj,
+            Min,
+            Max,
+            Rand,
+            IIf,
+            RGB,
+            Len,
+            IsNum,
+            LCase,
+            UCase,
+            Input,
+            Str,
+            Val,
+            ArrSize,
+            IsPlay,
+            Desc,
+            Trim,
+            GetObj,
+            StrComp,
+            StrFind,
+            StrPos,
+            Mid,
+            ArrPos,
+            ArrComp,
+            Instr,
+            Replace,
+            Func,
+            DynEval,
+            Rnd,
+            CountObj,
+            MsecsCount,
+            QSPVer,
+            UserText,
+            CurLoc,
+            SelObj,
+            SelAct,
+            MainText,
+            StatText,
+            CurActs,
+
+            Last_Operation
+        };
+
+        static public QspStatement[] qspStats;
+        static QspStatementName[,] qspStatsNames;
+        static int[] qspStatsNamesCounts;
+        static int qspStatMaxLen;
+        static public QspFunction[] qspOps;
+        static QspFunctionName[,] qspOpsNames;
+        static int[] qspOpsNamesCounts;
+        static int qspOpMaxLen;
+        static bool inited = false;
+
+        public class QspVariable
+        {
+            public bool IsString;
+            public string Name;
+            public bool Assigned;
+            public bool Used;
+            public QspVariable(string name, bool assigned, bool used)
+            {
+                IsString = name.IndexOf('$') == 0;
+                Name = name;
+                Assigned = assigned;
+                Used = used;
+            }
+        }
+        public class QspLocationLink
+        {
+            public string LocationName;
+            public bool LocationExists;
+            public bool LocationCalled;
+            public QspLocationLink(string name, bool exists, bool called)
+            {
+                LocationName = name;
+                LocationExists = exists;
+                LocationCalled = called;
+            }
+        }
+        public class QspObj
+        {
+            public string Name;
+            public bool Added;
+            public bool Removed;
+            public QspObj(string name, bool added, bool removed)
+            {
+                Name = name;
+                Added = added;
+                Removed = removed;
+            }
+        }
+        public class QspAct
+        {
+            public string Name;
+            public bool Added;
+            public bool Removed;
+            public QspAct(string name, bool added, bool removed)
+            {
+                Name = name;
+                Added = added;
+                Removed = removed;
+            }
+        }
+        static public List<QspVariable> vars;
+        static public List<QspLocationLink> locationLinks;
+        static public List<QspObj> objects;
+        static public List<QspAct> acts;
+
+        static public List<string> callerVariables;
+        static public List<string> systemVariables;
+        static public bool curlyParsing;
+
+        static public string currentLocation;
+
+        public enum QuoteType
+        {
+            None,
+            Single,
+            Double
+        }
+
+        public struct QspError
+        {
+            public string locationName; //Локация, на которой встретилась ошибка
+            public string text;         //Текст сообщения об ошибке
+            public int line;            //Номер строки в локации
+            public bool isError;        //Тип ошибки, если "true" - ошибка синтаксиса, если "false" - предупреждение
+        }
+        static List<QspError> m_errors;
+        static int m_errorCounter;
+        public static int GetErrorsCount()
+        {
+            return m_errorCounter;
+        }
+        static int m_warningCounter;
+        public static int GetWarningsCount()
+        {
+            return m_warningCounter;
+        }
+
+        public Common()
+        {
+            if (!inited)
+            {
+                inited = true;
+                qspStats = new QspStatement[(int)QspStatementType.Last_Statement];
+                qspStatsNames = new QspStatementName[QSP_STATSLEVELS, QSP_MAXSTATSNAMES];
+                qspStatsNamesCounts = new int[QSP_STATSLEVELS];
+                qspOps = new QspFunction[(int)QspFunctionType.Last_Operation];
+                qspOpsNames = new QspFunctionName[QSP_OPSLEVELS, QSP_MAXOPSNAMES];
+                qspOpsNamesCounts = new int[QSP_OPSLEVELS];
+
+                m_errors = new List<QspError>();
+                InitQsp();
+                ClearErrors();
+            }
+        }
+
+        static public void ClearErrors()
+        {
+            m_errors.Clear();
+            m_errorCounter = 0;
+            m_warningCounter = 0;
+        }
+
+        static public void ClearNonGameErrors()
+        {
+            for (int index = 0; index < m_errors.Count; ++index)
+            {
+                if (m_errors[index].isError && (m_errors[index].line == INVALID_INDEX))
+                {
+
+                    m_errors.RemoveAt(index);
+                    --index;
+                    m_errorCounter--;
+                }
+            }
+        }
+
+        static public void SubmitError(string text, int line)
+        {
+            QspError e;
+            e.locationName = currentLocation;
+            e.text = text;
+            e.line = line;
+            e.isError = true;
+            m_errors.Add(e);
+            m_errorCounter++;
+        }
+
+        static public void SubmitWarning(string text, int line)
+        {
+            QspError w;
+            w.locationName = currentLocation;
+            w.text = text;
+            w.line = line;
+            w.isError = false;
+            m_errors.Add(w);
+            m_warningCounter++;
+        }
+
+        static public List<QspError> GetErrors()
+        {
+            return m_errors;
+        }
+
+        static public bool StartOfMultiWordOperator(string op)
+        {
+            return op.ToUpper().Equals("ADD") || op.ToUpper().Equals("DEL");
+        }
+
+        static public void qspAddStatement(int statCode, int extArg, /*QSP_STATEMENT func,*/ int minArgs, int maxArgs, params int[] marker)
+        {
+            int i;
+            qspStats[statCode].ExtArg = extArg;
+            //qspStats[statCode].Func = func;
+            qspStats[statCode].MinArgsCount = minArgs;
+            qspStats[statCode].MaxArgsCount = maxArgs;
+            qspStats[statCode].ArgsTypes = new int[QSP_STATMAXARGS];
+            if (maxArgs > 0)
+            {
+                for (i = 0; i < maxArgs; ++i)
+                    qspStats[statCode].ArgsTypes[i] = marker[i];
+            }
+        }
+
+        static public void qspAddStatName(int statCode, string statName, int level)
+        {
+            int len = statName.Length;
+            int count = qspStatsNamesCounts[level];
+            qspStatsNames[level, count].Name = statName;
+            qspStatsNames[level, count].NameLen = len;
+            qspStatsNames[level, count].Code = statCode;
+            qspStatsNamesCounts[level] = count + 1;
+            /* Max length */
+            if (len > qspStatMaxLen) qspStatMaxLen = len;
+        }
+
+        static public void qspAddOperation(int opCode, int priority, /*QSP_FUNCTION func,*/ int resType, int minArgs, int maxArgs, params int[] marker)
+        {
+	        int i;
+	        qspOps[opCode].Priority = priority;
+	        //qspOps[opCode].Func = func;
+	        qspOps[opCode].ResType = resType;
+	        qspOps[opCode].MinArgsCount = minArgs;
+	        qspOps[opCode].MaxArgsCount = maxArgs;
+            qspOps[opCode].ArgsTypes = new int[QSP_OPMAXARGS];
+            if (maxArgs > 0)
+	        {
+		        for (i = 0; i < maxArgs; ++i)
+			        qspOps[opCode].ArgsTypes[i] = marker[i];
+	        }
+        }
+
+        static public void qspAddOpName(int opCode, string opName, int level)
+        {
+            int len = opName.Length;
+	        int count = qspOpsNamesCounts[level];
+	        qspOpsNames[level, count].Name = opName;
+	        qspOpsNames[level, count].NameLen = len;
+	        qspOpsNames[level, count].Code = opCode;
+	        qspOpsNamesCounts[level] = count + 1;
+	        /* Max length */
+	        if (len > qspOpMaxLen) qspOpMaxLen = len;
+        }
+
+
+        static public void InitQsp()
+        {
+            qspStatMaxLen = 0;
+            // код оператора, ExtArg, минимальное кол-во аргументов, максимальное кол-во аргументов, типы аргументов
+            //                                                                                       0 - авто
+            //                                                                                       1 - строка
+            //                                                                                       2 - числовой
+            qspAddStatement((int)QspStatementType.Else, 0, 0, 0);
+            qspAddStatement((int)QspStatementType.ElseIf, 0, 1, 1, 2);
+            qspAddStatement((int)QspStatementType.End, 0, 0, 0);
+            qspAddStatement((int)QspStatementType.Local, 0, 0, 0);
+            qspAddStatement((int)QspStatementType.Set, 0, 0, 0);
+            qspAddStatement((int)QspStatementType.If, 0, 1, 1, 2);
+            qspAddStatement((int)QspStatementType.Act, 0, 1, 2, 1, 1);
+            qspAddStatement((int)QspStatementType.For, 0, 0, 0);
+            qspAddStatement((int)QspStatementType.AddObj, 0, 1, 3, 1, 1, 2);
+            qspAddStatement((int)QspStatementType.ClA, 3, 0, 0);
+            qspAddStatement((int)QspStatementType.CloseAll, 1, 0, 0);
+            qspAddStatement((int)QspStatementType.Close, 0, 0, 1, 1);
+            qspAddStatement((int)QspStatementType.ClS, 4, 0, 0);
+            qspAddStatement((int)QspStatementType.CmdClear, 2, 0, 0);
+            qspAddStatement((int)QspStatementType.CopyArr, 0, 2, 4, 1, 1, 2, 2);
+            qspAddStatement((int)QspStatementType.DelAct, 0, 1, 1, 1);
+            qspAddStatement((int)QspStatementType.DelObj, 0, 1, 1, 1);
+            qspAddStatement((int)QspStatementType.Dynamic, 0, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+            qspAddStatement((int)QspStatementType.Exec, 0, 1, 1, 1);
+            qspAddStatement((int)QspStatementType.Exit, 0, 0, 0);
+            qspAddStatement((int)QspStatementType.FreeLib, 6, 0, 0);
+            qspAddStatement((int)QspStatementType.GoSub, 0, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+            qspAddStatement((int)QspStatementType.GoTo, 1, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+            qspAddStatement((int)QspStatementType.IncLib, 1, 1, 1, 1);
+            qspAddStatement((int)QspStatementType.Jump, 0, 1, 1, 1);
+            qspAddStatement((int)QspStatementType.KillAll, 5, 0, 0);
+            qspAddStatement((int)QspStatementType.KillObj, 1, 0, 1, 2);
+            qspAddStatement((int)QspStatementType.KillVar, 0, 0, 2, 1, 2);
+            qspAddStatement((int)QspStatementType.Menu, 0, 1, 3, 1, 2, 2);
+            qspAddStatement((int)QspStatementType.MClear, 1, 0, 0);
+            qspAddStatement((int)QspStatementType.MNL, 5, 0, 1, 1);
+            qspAddStatement((int)QspStatementType.MPL, 3, 0, 1, 1);
+            qspAddStatement((int)QspStatementType.MP, 1, 1, 1, 1);
+            qspAddStatement((int)QspStatementType.Clear, 0, 0, 0);
+            qspAddStatement((int)QspStatementType.NL, 4, 0, 1, 1);
+            qspAddStatement((int)QspStatementType.PL, 2, 0, 1, 1);
+            qspAddStatement((int)QspStatementType.P, 0, 1, 1, 1);
+            qspAddStatement((int)QspStatementType.Msg, 0, 1, 1, 1);
+            qspAddStatement((int)QspStatementType.OpenGame, 0, 0, 1, 1);
+            qspAddStatement((int)QspStatementType.OpenQst, 0, 1, 1, 1);
+            qspAddStatement((int)QspStatementType.Play, 0, 1, 2, 1, 2);
+            qspAddStatement((int)QspStatementType.RefInt, 0, 0, 0);
+            qspAddStatement((int)QspStatementType.SaveGame, 0, 0, 1, 1);
+            qspAddStatement((int)QspStatementType.SetTimer, 0, 1, 1, 2);
+            qspAddStatement((int)QspStatementType.ShowActs, 0, 1, 1, 2);
+            qspAddStatement((int)QspStatementType.ShowInput, 3, 1, 1, 2);
+            qspAddStatement((int)QspStatementType.ShowObjs, 1, 1, 1, 2);
+            qspAddStatement((int)QspStatementType.ShowVars, 2, 1, 1, 2);
+            qspAddStatement((int)QspStatementType.UnSelect, 0, 0, 0);
+            qspAddStatement((int)QspStatementType.View, 0, 0, 1, 1);
+            qspAddStatement((int)QspStatementType.Wait, 0, 1, 1, 2);
+            qspAddStatement((int)QspStatementType.XGoTo, 0, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+            /* Names */
+            qspAddStatName((int)QspStatementType.Else, "ELSE", 2);
+            qspAddStatName((int)QspStatementType.ElseIf, "ELSEIF", 1);
+            qspAddStatName((int)QspStatementType.End, "END", 2);
+            qspAddStatName((int)QspStatementType.Local, "LOCAL", 2);
+            qspAddStatName((int)QspStatementType.Set, "SET", 2);
+            qspAddStatName((int)QspStatementType.Set, "LET", 2);
+            qspAddStatName((int)QspStatementType.If, "IF", 2);
+            qspAddStatName((int)QspStatementType.Act, "ACT", 2);
+            qspAddStatName((int)QspStatementType.For, "FOR", 2);
+            qspAddStatName((int)QspStatementType.AddObj, "ADDOBJ", 2);
+            qspAddStatName((int)QspStatementType.AddObj, "ADD OBJ", 2);
+            qspAddStatName((int)QspStatementType.ClA, "CLA", 2);
+            qspAddStatName((int)QspStatementType.CloseAll, "CLOSE ALL", 1);
+            qspAddStatName((int)QspStatementType.Close, "CLOSE", 2);
+            qspAddStatName((int)QspStatementType.ClS, "CLS", 2);
+            qspAddStatName((int)QspStatementType.CmdClear, "CMDCLEAR", 2);
+            qspAddStatName((int)QspStatementType.CmdClear, "CMDCLR", 2);
+            qspAddStatName((int)QspStatementType.CopyArr, "COPYARR", 2);
+            qspAddStatName((int)QspStatementType.DelAct, "DELACT", 2);
+            qspAddStatName((int)QspStatementType.DelAct, "DEL ACT", 2);
+            qspAddStatName((int)QspStatementType.DelObj, "DELOBJ", 2);
+            qspAddStatName((int)QspStatementType.DelObj, "DEL OBJ", 2);
+            qspAddStatName((int)QspStatementType.Dynamic, "DYNAMIC", 2);
+            qspAddStatName((int)QspStatementType.Exec, "EXEC", 2);
+            qspAddStatName((int)QspStatementType.Exit, "EXIT", 2);
+            qspAddStatName((int)QspStatementType.FreeLib, "FREELIB", 2);
+            qspAddStatName((int)QspStatementType.GoSub, "GOSUB", 2);
+            qspAddStatName((int)QspStatementType.GoSub, "GS", 2);
+            qspAddStatName((int)QspStatementType.GoTo, "GOTO", 2);
+            qspAddStatName((int)QspStatementType.GoTo, "GT", 2);
+            qspAddStatName((int)QspStatementType.IncLib, "INCLIB", 2);
+            qspAddStatName((int)QspStatementType.Jump, "JUMP", 2);
+            qspAddStatName((int)QspStatementType.KillAll, "KILLALL", 2);
+            qspAddStatName((int)QspStatementType.KillObj, "KILLOBJ", 2);
+            qspAddStatName((int)QspStatementType.KillVar, "KILLVAR", 2);
+            qspAddStatName((int)QspStatementType.Menu, "MENU", 2);
+            qspAddStatName((int)QspStatementType.MClear, "*CLEAR", 2);
+            qspAddStatName((int)QspStatementType.MClear, "*CLR", 2);
+            qspAddStatName((int)QspStatementType.MNL, "*NL", 2);
+            qspAddStatName((int)QspStatementType.MPL, "*PL", 1);
+            qspAddStatName((int)QspStatementType.MP, "*P", 2);
+            qspAddStatName((int)QspStatementType.Clear, "CLEAR", 2);
+            qspAddStatName((int)QspStatementType.Clear, "CLR", 2);
+            qspAddStatName((int)QspStatementType.NL, "NL", 2);
+            qspAddStatName((int)QspStatementType.PL, "PL", 1);
+            qspAddStatName((int)QspStatementType.P, "P", 2);
+            qspAddStatName((int)QspStatementType.Msg, "MSG", 2);
+            qspAddStatName((int)QspStatementType.OpenGame, "OPENGAME", 2);
+            qspAddStatName((int)QspStatementType.OpenQst, "OPENQST", 2);
+            qspAddStatName((int)QspStatementType.Play, "PLAY", 0);
+            qspAddStatName((int)QspStatementType.RefInt, "REFINT", 2);
+            qspAddStatName((int)QspStatementType.SaveGame, "SAVEGAME", 2);
+            qspAddStatName((int)QspStatementType.SetTimer, "SETTIMER", 1);
+            qspAddStatName((int)QspStatementType.ShowActs, "SHOWACTS", 2);
+            qspAddStatName((int)QspStatementType.ShowInput, "SHOWINPUT", 2);
+            qspAddStatName((int)QspStatementType.ShowObjs, "SHOWOBJS", 2);
+            qspAddStatName((int)QspStatementType.ShowVars, "SHOWSTAT", 2);
+            qspAddStatName((int)QspStatementType.UnSelect, "UNSELECT", 1);
+            qspAddStatName((int)QspStatementType.UnSelect, "UNSEL", 2);
+            qspAddStatName((int)QspStatementType.View, "VIEW", 2);
+            qspAddStatName((int)QspStatementType.Wait, "WAIT", 2);
+            qspAddStatName((int)QspStatementType.XGoTo, "XGOTO", 2);
+            qspAddStatName((int)QspStatementType.XGoTo, "XGT", 2);
+
+            //Математические операторы и функции
+	        int i;
+	        for (i = 0; i < QSP_OPSLEVELS; ++i) qspOpsNamesCounts[i] = 0;
+	        qspOpMaxLen = 0;
+            // код оператора, приоритет, тип результата, минимальное кол-во аргументов, максимальное кол-во аргументов, типы аргументов
+            //                                                                                       0 - авто
+            //                                                                                       1 - строка
+            //                                                                                       2 - числовой
+	        qspAddOperation((int)QspFunctionType.Value, 0, 0, 0, 0);
+	        qspAddOperation((int)QspFunctionType.Start, 127, 0, 0, 0);
+	        qspAddOperation((int)QspFunctionType.End, 0, 0, 0, 0);
+	        qspAddOperation((int)QspFunctionType.OpenBracket, 127, 0, 0, 0);
+	        qspAddOperation((int)QspFunctionType.CloseBracket, 0, 0, 0, 0);
+	        qspAddOperation((int)QspFunctionType.Minus, 18, 2, 1, 1, 2);
+	        qspAddOperation((int)QspFunctionType.Add, 14, 0, 2, 2, 0, 0);
+	        qspAddOperation((int)QspFunctionType.Sub, 14, 2, 2, 2, 2, 2);
+	        qspAddOperation((int)QspFunctionType.Mul, 17, 2, 2, 2, 2, 2);
+	        qspAddOperation((int)QspFunctionType.Div, 17, 2, 2, 2, 2, 2);
+	        qspAddOperation((int)QspFunctionType.Mod, 16, 2, 2, 2, 2, 2);
+	        qspAddOperation((int)QspFunctionType.Ne, 10, 2, 2, 2, 0, 0);
+	        qspAddOperation((int)QspFunctionType.Leq, 10, 2, 2, 2, 0, 0);
+	        qspAddOperation((int)QspFunctionType.Geq, 10, 2, 2, 2, 0, 0);
+	        qspAddOperation((int)QspFunctionType.Eq, 10, 2, 2, 2, 0, 0);
+	        qspAddOperation((int)QspFunctionType.Lt, 10, 2, 2, 2, 0, 0);
+	        qspAddOperation((int)QspFunctionType.Gt, 10, 2, 2, 2, 0, 0);
+	        qspAddOperation((int)QspFunctionType.Append, 12, 1, 2, 2, 1, 1);
+	        qspAddOperation((int)QspFunctionType.Comma, 0, 1, 2, 2, 1, 1);
+	        qspAddOperation((int)QspFunctionType.And, 7, 2, 2, 2, 2, 2);
+	        qspAddOperation((int)QspFunctionType.Or, 6, 2, 2, 2, 2, 2);
+	        qspAddOperation((int)QspFunctionType.Loc, 8, 2, 1, 1, 1);
+	        qspAddOperation((int)QspFunctionType.Obj, 8, 2, 1, 1, 1);
+	        qspAddOperation((int)QspFunctionType.Not, 8, 2, 1, 1, 2);
+	        qspAddOperation((int)QspFunctionType.Min, 30, 0, 1, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	        qspAddOperation((int)QspFunctionType.Max, 30, 0, 1, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	        qspAddOperation((int)QspFunctionType.Rand, 30, 2, 1, 2, 2, 2);
+	        qspAddOperation((int)QspFunctionType.IIf, 30, 0, 3, 3, 2, 0, 0);
+	        qspAddOperation((int)QspFunctionType.RGB, 30, 2, 3, 4, 2, 2, 2, 2);
+	        qspAddOperation((int)QspFunctionType.Len, 30, 2, 1, 1, 1);
+	        qspAddOperation((int)QspFunctionType.IsNum, 30, 2, 1, 1, 0);
+	        qspAddOperation((int)QspFunctionType.LCase, 30, 1, 1, 1, 1);
+	        qspAddOperation((int)QspFunctionType.UCase, 30, 1, 1, 1, 1);
+	        qspAddOperation((int)QspFunctionType.Input, 30, 1, 1, 1, 1);
+	        qspAddOperation((int)QspFunctionType.Str, 30, 1, 1, 1, 1);
+	        qspAddOperation((int)QspFunctionType.Val, 30, 2, 1, 1, 0);
+	        qspAddOperation((int)QspFunctionType.ArrSize, 30, 2, 1, 1, 1);
+	        qspAddOperation((int)QspFunctionType.IsPlay, 30, 2, 1, 1, 1);
+	        qspAddOperation((int)QspFunctionType.Desc, 30, 1, 1, 1, 1);
+	        qspAddOperation((int)QspFunctionType.Trim, 30, 1, 1, 1, 1);
+	        qspAddOperation((int)QspFunctionType.GetObj, 30, 1, 1, 1, 2);
+	        qspAddOperation((int)QspFunctionType.StrComp, 30, 2, 2, 2, 1, 1);
+	        qspAddOperation((int)QspFunctionType.StrFind, 30, 1, 2, 3, 1, 1, 2);
+	        qspAddOperation((int)QspFunctionType.StrPos, 30, 2, 2, 3, 1, 1, 2);
+	        qspAddOperation((int)QspFunctionType.Mid, 30, 1, 2, 3, 1, 2, 2);
+	        qspAddOperation((int)QspFunctionType.ArrPos, 30, 2, 2, 3, 1, 0, 2);
+	        qspAddOperation((int)QspFunctionType.ArrComp, 30, 2, 2, 3, 1, 0, 2);
+	        qspAddOperation((int)QspFunctionType.Instr, 30, 2, 2, 3, 1, 1, 2);
+	        qspAddOperation((int)QspFunctionType.Replace, 30, 1, 2, 3, 1, 1, 1);
+	        qspAddOperation((int)QspFunctionType.Func, 30, 0, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	        qspAddOperation((int)QspFunctionType.DynEval, 30, 0, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	        qspAddOperation((int)QspFunctionType.Rnd, 30, 2, 0, 0);
+	        qspAddOperation((int)QspFunctionType.CountObj, 30, 2, 0, 0);
+	        qspAddOperation((int)QspFunctionType.MsecsCount, 30, 2, 0, 0);
+	        qspAddOperation((int)QspFunctionType.QSPVer, 30, 1, 0, 0);
+	        qspAddOperation((int)QspFunctionType.UserText, 30, 1, 0, 0);
+	        qspAddOperation((int)QspFunctionType.CurLoc, 30, 1, 0, 0);
+	        qspAddOperation((int)QspFunctionType.SelObj, 30, 1, 0, 0);
+	        qspAddOperation((int)QspFunctionType.SelAct, 30, 1, 0, 0);
+	        qspAddOperation((int)QspFunctionType.MainText, 30, 1, 0, 0);
+	        qspAddOperation((int)QspFunctionType.StatText, 30, 1, 0, 0);
+	        qspAddOperation((int)QspFunctionType.CurActs, 30, 1, 0, 0);
+	        /* Names */
+	        qspAddOpName((int)QspFunctionType.CloseBracket, ")", 1);
+	        qspAddOpName((int)QspFunctionType.Add, "+", 1);
+	        qspAddOpName((int)QspFunctionType.Sub, "-", 1);
+	        qspAddOpName((int)QspFunctionType.Mul, "*", 1);
+	        qspAddOpName((int)QspFunctionType.Div, "/", 1);
+	        qspAddOpName((int)QspFunctionType.Mod, "MOD", 1);
+	        qspAddOpName((int)QspFunctionType.Ne, "!", 1);
+	        qspAddOpName((int)QspFunctionType.Ne, "<>", 0);
+	        qspAddOpName((int)QspFunctionType.Leq, "<=", 0);
+	        qspAddOpName((int)QspFunctionType.Leq, "=<", 0);
+	        qspAddOpName((int)QspFunctionType.Geq, ">=", 0);
+	        qspAddOpName((int)QspFunctionType.Geq, "=>", 0);
+	        qspAddOpName((int)QspFunctionType.Eq, "=", 1);
+	        qspAddOpName((int)QspFunctionType.Lt, "<", 1);
+	        qspAddOpName((int)QspFunctionType.Gt, ">", 1);
+	        qspAddOpName((int)QspFunctionType.Append, "&", 1);
+	        qspAddOpName((int)QspFunctionType.Comma, ",", 1);
+	        qspAddOpName((int)QspFunctionType.And, "AND", 1);
+	        qspAddOpName((int)QspFunctionType.Or, "OR", 1);
+	        qspAddOpName((int)QspFunctionType.Loc, "LOC", 1);
+	        qspAddOpName((int)QspFunctionType.Obj, "OBJ", 1);
+	        qspAddOpName((int)QspFunctionType.Not, "NO", 1);
+	        qspAddOpName((int)QspFunctionType.Min, "MIN", 1);
+	        qspAddOpName((int)QspFunctionType.Min, "$MIN", 1);
+	        qspAddOpName((int)QspFunctionType.Max, "MAX", 1);
+	        qspAddOpName((int)QspFunctionType.Max, "$MAX", 1);
+	        qspAddOpName((int)QspFunctionType.Rand, "RAND", 1);
+	        qspAddOpName((int)QspFunctionType.IIf, "IIF", 1);
+	        qspAddOpName((int)QspFunctionType.IIf, "$IIF", 1);
+	        qspAddOpName((int)QspFunctionType.RGB, "RGB", 1);
+	        qspAddOpName((int)QspFunctionType.Len, "LEN", 1);
+	        qspAddOpName((int)QspFunctionType.IsNum, "ISNUM", 1);
+	        qspAddOpName((int)QspFunctionType.LCase, "LCASE", 1);
+	        qspAddOpName((int)QspFunctionType.LCase, "$LCASE", 1);
+	        qspAddOpName((int)QspFunctionType.UCase, "UCASE", 1);
+	        qspAddOpName((int)QspFunctionType.UCase, "$UCASE", 1);
+	        qspAddOpName((int)QspFunctionType.Input, "INPUT", 1);
+	        qspAddOpName((int)QspFunctionType.Input, "$INPUT", 1);
+	        qspAddOpName((int)QspFunctionType.Str, "STR", 1);
+	        qspAddOpName((int)QspFunctionType.Str, "$STR", 1);
+	        qspAddOpName((int)QspFunctionType.Val, "VAL", 1);
+	        qspAddOpName((int)QspFunctionType.ArrSize, "ARRSIZE", 1);
+	        qspAddOpName((int)QspFunctionType.IsPlay, "ISPLAY", 1);
+	        qspAddOpName((int)QspFunctionType.Desc, "DESC", 1);
+	        qspAddOpName((int)QspFunctionType.Desc, "$DESC", 1);
+	        qspAddOpName((int)QspFunctionType.Trim, "TRIM", 1);
+	        qspAddOpName((int)QspFunctionType.Trim, "$TRIM", 1);
+	        qspAddOpName((int)QspFunctionType.GetObj, "GETOBJ", 1);
+	        qspAddOpName((int)QspFunctionType.GetObj, "$GETOBJ", 1);
+	        qspAddOpName((int)QspFunctionType.StrComp, "STRCOMP", 1);
+	        qspAddOpName((int)QspFunctionType.StrFind, "STRFIND", 1);
+	        qspAddOpName((int)QspFunctionType.StrFind, "$STRFIND", 1);
+	        qspAddOpName((int)QspFunctionType.StrPos, "STRPOS", 1);
+	        qspAddOpName((int)QspFunctionType.Mid, "MID", 1);
+	        qspAddOpName((int)QspFunctionType.Mid, "$MID", 1);
+	        qspAddOpName((int)QspFunctionType.ArrPos, "ARRPOS", 1);
+	        qspAddOpName((int)QspFunctionType.ArrComp, "ARRCOMP", 1);
+	        qspAddOpName((int)QspFunctionType.Instr, "INSTR", 1);
+	        qspAddOpName((int)QspFunctionType.Replace, "REPLACE", 1);
+	        qspAddOpName((int)QspFunctionType.Replace, "$REPLACE", 1);
+	        qspAddOpName((int)QspFunctionType.Func, "FUNC", 1);
+	        qspAddOpName((int)QspFunctionType.Func, "$FUNC", 1);
+	        qspAddOpName((int)QspFunctionType.DynEval, "DYNEVAL", 1);
+	        qspAddOpName((int)QspFunctionType.DynEval, "$DYNEVAL", 1);
+	        qspAddOpName((int)QspFunctionType.Rnd, "RND", 1);
+	        qspAddOpName((int)QspFunctionType.CountObj, "COUNTOBJ", 1);
+	        qspAddOpName((int)QspFunctionType.MsecsCount, "MSECSCOUNT", 1);
+	        qspAddOpName((int)QspFunctionType.QSPVer, "QSPVER", 1);
+	        qspAddOpName((int)QspFunctionType.QSPVer, "$QSPVER", 1);
+	        qspAddOpName((int)QspFunctionType.UserText, "USER_TEXT", 1);
+	        qspAddOpName((int)QspFunctionType.UserText, "$USER_TEXT", 1);
+	        qspAddOpName((int)QspFunctionType.UserText, "USRTXT", 1);
+	        qspAddOpName((int)QspFunctionType.UserText, "$USRTXT", 1);
+	        qspAddOpName((int)QspFunctionType.CurLoc, "CURLOC", 1);
+	        qspAddOpName((int)QspFunctionType.CurLoc, "$CURLOC", 1);
+	        qspAddOpName((int)QspFunctionType.SelObj, "SELOBJ", 1);
+	        qspAddOpName((int)QspFunctionType.SelObj, "$SELOBJ", 1);
+	        qspAddOpName((int)QspFunctionType.SelAct, "SELACT", 1);
+	        qspAddOpName((int)QspFunctionType.SelAct, "$SELACT", 1);
+	        qspAddOpName((int)QspFunctionType.MainText, "MAINTXT", 1);
+	        qspAddOpName((int)QspFunctionType.MainText, "$MAINTXT", 1);
+	        qspAddOpName((int)QspFunctionType.StatText, "STATTXT", 1);
+	        qspAddOpName((int)QspFunctionType.StatText, "$STATTXT", 1);
+	        qspAddOpName((int)QspFunctionType.CurActs, "CURACTS", 1);
+	        qspAddOpName((int)QspFunctionType.CurActs, "$CURACTS", 1);
+        }
+
+        static public int qspGetStatCode(string s)
+        {
+            if (s.Length == 0)
+                return (int)QspStatementType.Unknown;
+            if (s[0] == ':')
+                return (int)QspStatementType.Label;
+            if (s[0] == '!')
+                return (int)QspStatementType.Comment;
+            int len;
+            if (s.Length < qspStatMaxLen)
+                len = s.Length;
+            else
+                len = qspStatMaxLen;
+            string name = s.Substring(0, len).ToUpper().Trim(WhiteSpace);
+	        for (int i = 0; i < QSP_STATSLEVELS; ++i)
+	        {
+                for (int j = 0; j < qspStatsNamesCounts[i]; j++)
+                {
+                    if (name.Equals(qspStatsNames[i,j].Name))
+                        return qspStatsNames[i,j].Code;
+                }
+	        }
+            return (int)QspStatementType.Unknown;
+        }
+
+        static public int qspGetFunctionCode(string s, bool functionsOnly)
+        {
+            if (s.Length == 0)
+                return (int)QspFunctionType.End;
+            int len;
+            if (s.Length < qspOpMaxLen)
+                len = s.Length;
+            else
+                len = qspOpMaxLen;
+            string name = s.Substring(0, len).ToUpper().Trim(WhiteSpace);
+            for (int i = 0; i < QSP_OPSLEVELS; ++i)
+            {
+                for (int j = 0; j < qspOpsNamesCounts[i]; j++)
+                {
+                    if ((name.Equals(qspOpsNames[i, j].Name)) && 
+                        (!functionsOnly || (qspOpsNames[i, j].Code >= (int)QspFunctionType.First_Function)))
+                        return qspOpsNames[i, j].Code;
+                }
+            }
+            return (int)QspFunctionType.Unknown;
+        }
+        
+        static public QspVariable GetVar(string name)
+        {
+            foreach (QspVariable var in vars)
+            {
+                if (var.Name.Equals(name, StringComparison.OrdinalIgnoreCase))
+                    return var;
+            }
+            return null;
+        }
+
+        static public void AddVar(string name, bool assigned, bool used)
+        {
+            QspVariable var = GetVar(name);
+            if (var == null)
+            {
+                var = new QspVariable(name, assigned, used);
+                vars.Add(var);
+            }
+            else
+            {
+                if (assigned)
+                    var.Assigned = assigned;
+                if (used)
+                    var.Used = used;
+            }
+        }
+
+        static public QspLocationLink GetLocationLink(string name)
+        {
+            foreach (QspLocationLink loc in locationLinks)
+            {
+                if (loc.LocationName.Equals(name, StringComparison.OrdinalIgnoreCase))
+                    return loc;
+            }
+            return null;
+        }
+
+        static public void AddLocationLink(string name, bool exists, bool called)
+        {
+            QspLocationLink loc = GetLocationLink(name);
+            if (loc == null)
+            {
+                loc = new QspLocationLink(name, exists, called);
+                locationLinks.Add(loc);
+            }
+            else
+            {
+                if (exists)
+                    loc.LocationExists = exists;
+                if (called)
+                    loc.LocationCalled = called;
+            }
+        }
+
+        static public QspObj GetObj(string name)
+        {
+            foreach (QspObj obj in objects)
+            {
+                if (obj.Name.Equals(name, StringComparison.OrdinalIgnoreCase))
+                    return obj;
+            }
+            return null;
+        }
+
+        static public void AddObj(string name, bool added, bool removed)
+        {
+            QspObj obj = GetObj(name);
+            if (obj == null)
+            {
+                obj = new QspObj(name, added, removed);
+                objects.Add(obj);
+            }
+            else
+            {
+                if (added)
+                    obj.Added = added;
+                if (removed)
+                    obj.Removed = removed;
+            }
+        }
+
+        static public QspAct GetAct(string name)
+        {
+            foreach (QspAct act in acts)
+            {
+                if (act.Name.Equals(name, StringComparison.OrdinalIgnoreCase))
+                    return act;
+            }
+            return null;
+        }
+
+        static public void AddAct(string name, bool added, bool removed)
+        {
+            QspAct act = GetAct(name);
+            if (act == null)
+            {
+                act = new QspAct(name, added, removed);
+                acts.Add(act);
+            }
+            else
+            {
+                if (added)
+                    act.Added = added;
+                if (removed)
+                    act.Removed = removed;
+            }
+        }
+
+        static public void SetConfig(List<string> callerVars, List<string> systemVars, bool EnableCurlyParsing)
+        {
+            callerVariables = callerVars;
+            systemVariables = systemVars;
+            curlyParsing = EnableCurlyParsing;
+        }
+
+        static public bool IsNumber(String s)
+        {
+            foreach (char c in s.ToCharArray())
+            {
+                if (Array.IndexOf(Digits, c) == INVALID_INDEX)
+                    return false;
+            }
+            return true;
+        }
+
+        static public bool ListContainsIgnoreCase(List<string> stringList, string value)
+        {
+            bool contains = null != stringList.Find(delegate(string str)
+            {
+                return str.Equals(value, StringComparison.OrdinalIgnoreCase);
+            });
+            return contains;
+        }
+
+        static public string GenerateCsvName(string FileName)
+        {
+            string result = FileName;
+            if (result.EndsWith(".txt"))
+                result = result.Substring(0, result.Length - 4);
+            result = result + ".csv";
+            return result;
+        }
+
+        static public bool ExportToCsv(string srcFile, string delimiter)
+        {
+            //Выгружаем исходный код в CSV
+            //4 колонки: номер+локация, оригинал, место для перевода, место для комментария
+
+            string dstFile = GenerateCsvName(srcFile);
+
+            StreamReader fi = null;
+            if (!OpenStreamForReading(ref fi, srcFile))
+            {
+                return false;
+            }
+            StreamWriter fo = null;
+            if (!OpenStreamForWriting(ref fo, dstFile))
+            {
+                fi.Close();
+                return false;
+            }
+            string line;
+            int line_counter = 0;
+            int quoted_line_counter = 0;
+            bool inside = false;
+            string locName = null;
+
+            int quote = (int)QuoteType.None;
+            string quotedText = "";
+            bool quotedTextCompleted = false;
+
+            while ((line = fi.ReadLine()) != null)
+            {
+                line_counter++;
+                line = line.Trim(WhiteSpace);
+                if ((line.Length > 0) && (line[0] == '#'))
+                {
+                    //имя локации
+                    locName = line.Substring(1).Trim(WhiteSpace);
+                    inside = true;
+                }
+                else if ((line.Length > 38) && line.StartsWith("--- ") && line.EndsWith(" ---------------------------------"))
+                {
+                    inside = false;
+                    locName = null;
+                }
+                else if (inside)
+                {
+                    //Разбираем только строки внутри локаций
+                    int pos = 0;
+
+                    //Разбор строки
+                    while (pos < line.Length)
+                    {
+                        char c = line[pos];
+                        if (c == '\'')
+                        {
+                            //Апостроф
+                            if (quote == (int)QuoteType.None)
+                            {
+                                quote = (int)QuoteType.Single;
+                                quotedText = "";
+                            }
+                            else if (quote == (int)QuoteType.Single)
+                            {
+                                if ((pos + 1 < line.Length) && (line[pos + 1] == '\''))
+                                {
+                                    //Экранированный апостроф
+                                    pos++;
+                                    quotedText += c;
+                                }
+                                else
+                                {
+                                    quote = (int)QuoteType.None;
+                                    quotedTextCompleted = true;
+                                }
+                            }
+                            else
+                            {
+                                quotedText += c;
+                            }
+                        }
+                        else if (c == '"')
+                        {
+                            //Кавычка
+                            if (quote == (int)QuoteType.None)
+                            {
+                                quote = (int)QuoteType.Double;
+                                quotedText = "";
+                            }
+                            else if (quote == (int)QuoteType.Double)
+                            {
+                                if ((pos + 1 < line.Length) && (line[pos + 1] == '"'))
+                                {
+                                    //Экранированная кавычка
+                                    pos++;
+                                    quotedText += c;
+                                }
+                                else
+                                {
+                                    quote = (int)QuoteType.None;
+                                    quotedTextCompleted = true;
+                                }
+                            }
+                            else
+                            {
+                                quotedText += c;
+                            }
+                        }
+                        else if (quote != (int)QuoteType.None)
+                        {
+                            //Строка текста внутри кавычек или апострофов
+                            quotedText += c;
+                        }
+                        else if (c == '{')
+                        {
+                            //Пропускаем содержимое фигурных скобок
+                            int curlyLevel = 1;
+                            pos++;
+                            int curlyQuote = (int)QuoteType.None;
+                            while (pos < line.Length)
+                            {
+                                char c2 = line[pos];
+
+                                if (c2 == '\'')
+                                {
+                                    //Апостроф
+                                    if (curlyQuote == (int)QuoteType.None)
+                                    {
+                                        curlyQuote = (int)QuoteType.Single;
+                                    }
+                                    else if (curlyQuote == (int)QuoteType.Single)
+                                    {
+                                        if ((pos + 1 < line.Length) && (line[pos + 1] == '\''))
+                                        {
+                                            //Экранированный апостроф
+                                            pos++;
+                                        }
+                                        else
+                                        {
+                                            curlyQuote = (int)QuoteType.None;
+                                        }
+                                    }
+                                }
+                                else if (c2 == '"')
+                                {
+                                    //Кавычка
+                                    if (curlyQuote == (int)QuoteType.None)
+                                    {
+                                        curlyQuote = (int)QuoteType.Double;
+                                    }
+                                    else if (curlyQuote == (int)QuoteType.Double)
+                                    {
+                                        if ((pos + 1 < line.Length) && (line[pos + 1] == '"'))
+                                        {
+                                            //Экранированная кавычка
+                                            pos++;
+                                        }
+                                        else
+                                        {
+                                            curlyQuote = (int)QuoteType.None;
+                                        }
+                                    }
+                                }
+                                else if (curlyQuote == (int)QuoteType.None)
+                                {
+                                    if (c2 == '{')
+                                    {
+                                        curlyLevel++;
+                                    }
+                                    else if (c2 == '}')
+                                    {
+                                        curlyLevel--;
+                                        if (curlyLevel == 0)
+                                            break;
+                                    }
+                                }
+                                pos++;
+                            }
+                        }
+
+                        if (quotedTextCompleted)
+                        {
+                            //Формируем строку для csv-файла
+                            //4 колонки: номер+локация, оригинал, место для перевода, место для комментария
+                            if (quotedText.Trim(WhiteSpace).Length > 0)
+                            {
+                                quoted_line_counter++;
+
+                                string csv_line = "";
+                                csv_line += CsvEscape(quoted_line_counter.ToString() + ":" + locName) + delimiter;
+                                csv_line += CsvEscape(quotedText) + delimiter;
+                                csv_line += CsvEscape("") + delimiter;
+                                csv_line += CsvEscape("");
+
+                                //Записываем строку в csv-файл
+                                fo.WriteLine(csv_line);
+                            }
+                            quotedTextCompleted = false;
+                        }
+                        pos++;
+                    }
+                }
+            }
+            fi.Close();
+            fo.Close();
+            return true;
+        }
+
+        static public string CsvEscape(string src)
+        {
+            //Форматируем строку для записи в csv-файл
+            string result = "\"" + src.Replace("\"", "\"\"") + "\"";
+            return result;
+        }
+
+        static public string CsvUnEscape(string src)
+        {
+            //Преобразовываем строку из csv-формата в обычный текст
+            string result = src;
+            if (src.StartsWith("\""))
+            {
+                result = result.Substring(1, result.Length - 2);
+                result = result.Replace("\"\"", "\"");
+            }
+            return result;
+        }
+
+        static public bool TranslateFromCsv(string srcFile, string suffix, bool IgnoreEmptyTranslations, string delimiter)
+        {
+            //Создаем перевод на основе загруженного файла и CSV
+            //Проверяем соответствие номера, локации, оригинального текста, в случае несовпадения выдаем ошибку и не сохраняем файл
+            //Для пустых строк заполняем текстом оригинала, либо выдаем ошибку - в зависимости от настроек.
+
+            string dstFile = srcFile;
+            if (dstFile.EndsWith(".txt"))
+                dstFile = dstFile.Substring(0, dstFile.Length - 4);
+            dstFile = dstFile + suffix + ".txt";
+
+            string csvFile = GenerateCsvName(srcFile);
+
+            StreamReader fi_src = null;
+            if (!OpenStreamForReading(ref fi_src, srcFile))
+            {
+                return false;
+            }
+            StreamReader fi_csv = null;
+            if (!OpenStreamForReading(ref fi_csv, csvFile))
+            {
+                fi_src.Close();
+                return false;
+            }
+            StreamWriter fo = null;
+            if (!OpenStreamForWriting(ref fo, dstFile))
+            {
+                fi_src.Close();
+                fi_csv.Close();
+                return false;
+            }
+            string line;
+            string line_cut;
+            int line_counter = 0;
+            int quoted_line_counter = 0;
+            bool inside = false;
+            string locName = null;
+
+            int quote = (int)QuoteType.None;
+            string quotedText = "";
+            bool quotedTextCompleted = false;
+
+            string rawText = "";
+
+            bool aborted = false;
+
+            while ((line = fi_src.ReadLine()) != null)
+            {
+                line_counter++;
+                line_cut = line.Trim(WhiteSpace);
+                if ((line_cut.Length > 0) && (line_cut[0] == '#'))
+                {
+                    //имя локации
+                    locName = line_cut.Substring(1).Trim(WhiteSpace);
+                    inside = true;
+                    fo.WriteLine(line);
+                }
+                else if ((line_cut.Length > 38) && line_cut.StartsWith("--- ") && line_cut.EndsWith(" ---------------------------------"))
+                {
+                    inside = false;
+                    locName = null;
+                    fo.WriteLine(line);
+                }
+                else if (inside)
+                {
+                    //Разбираем только строки внутри локаций
+                    int pos = 0;
+
+                    //Разбор строки
+                    while (pos < line.Length)
+                    {
+                        char c = line[pos];
+                        if (c == '\'')
+                        {
+                            //Апостроф
+                            if (quote == (int)QuoteType.None)
+                            {
+                                quote = (int)QuoteType.Single;
+                                quotedText = "";
+                                rawText += c;
+                            }
+                            else if (quote == (int)QuoteType.Single)
+                            {
+                                if ((pos + 1 < line.Length) && (line[pos + 1] == '\''))
+                                {
+                                    //Экранированный апостроф
+                                    pos++;
+                                    quotedText += c;
+                                }
+                                else
+                                {
+                                    quote = (int)QuoteType.None;
+                                    quotedTextCompleted = true;
+                                }
+                            }
+                            else
+                            {
+                                quotedText += c;
+                            }
+                        }
+                        else if (c == '"')
+                        {
+                            //Кавычка
+                            if (quote == (int)QuoteType.None)
+                            {
+                                quote = (int)QuoteType.Double;
+                                quotedText = "";
+                                rawText += c;
+                            }
+                            else if (quote == (int)QuoteType.Double)
+                            {
+                                if ((pos + 1 < line.Length) && (line[pos + 1] == '"'))
+                                {
+                                    //Экранированная кавычка
+                                    pos++;
+                                    quotedText += c;
+                                }
+                                else
+                                {
+                                    quote = (int)QuoteType.None;
+                                    quotedTextCompleted = true;
+                                }
+                            }
+                            else
+                            {
+                                quotedText += c;
+                            }
+                        }
+                        else if (quote != (int)QuoteType.None)
+                        {
+                            //Строка текста внутри кавычек или апострофов
+                            quotedText += c;
+                        }
+                        else if (c == '{')
+                        {
+                            //Пропускаем содержимое фигурных скобок
+                            int curlyLevel = 1;
+                            rawText += c;
+                            pos++;
+                            int curlyQuote = (int)QuoteType.None;
+                            while (pos < line.Length)
+                            {
+                                char c2 = line[pos];
+                                rawText += c2;
+
+                                if (c2 == '\'')
+                                {
+                                    //Апостроф
+                                    if (curlyQuote == (int)QuoteType.None)
+                                    {
+                                        curlyQuote = (int)QuoteType.Single;
+                                    }
+                                    else if (curlyQuote == (int)QuoteType.Single)
+                                    {
+                                        if ((pos + 1 < line.Length) && (line[pos + 1] == '\''))
+                                        {
+                                            //Экранированный апостроф
+                                            rawText += line[pos + 1];
+                                            pos++;
+                                        }
+                                        else
+                                        {
+                                            curlyQuote = (int)QuoteType.None;
+                                        }
+                                    }
+                                }
+                                else if (c2 == '"')
+                                {
+                                    //Кавычка
+                                    if (curlyQuote == (int)QuoteType.None)
+                                    {
+                                        curlyQuote = (int)QuoteType.Double;
+                                    }
+                                    else if (curlyQuote == (int)QuoteType.Double)
+                                    {
+                                        if ((pos + 1 < line.Length) && (line[pos + 1] == '"'))
+                                        {
+                                            //Экранированная кавычка
+                                            rawText += line[pos + 1];
+                                            pos++;
+                                        }
+                                        else
+                                        {
+                                            curlyQuote = (int)QuoteType.None;
+                                        }
+                                    }
+                                }
+                                else if (curlyQuote == (int)QuoteType.None)
+                                {
+                                    if (c2 == '{')
+                                    {
+                                        curlyLevel++;
+                                    }
+                                    else if (c2 == '}')
+                                    {
+                                        curlyLevel--;
+                                        if (curlyLevel == 0)
+                                            break;
+                                    }
+                                }
+                                pos++;
+                            }
+                        }
+                        else
+                        {
+                            rawText += c;
+                        }
+
+                        if (quotedTextCompleted)
+                        {
+                            //Читаем строку из файла перевода
+                            string translation = quotedText;
+
+                            if (quotedText.Trim(WhiteSpace).Length > 0)
+                            {
+                                translation = "";
+                                quoted_line_counter++;
+
+                                bool csvLineCompleted = false;
+                                string csv_line = null;
+                                int valuesCount = 0;
+                                string thirdValue = "";
+                                int csvQuote = (int)QuoteType.None;
+                                string csvText = "";
+                                bool csvValueCompleted = false;
+
+                                int csvLineIndex = INVALID_INDEX;
+                                string csvLocName = "";
+                                string csvOriginalLine = "";
+
+                                while (!csvLineCompleted && ((csv_line = fi_csv.ReadLine()) != null))
+                                {
+                                    int csvPos = 0;
+
+                                    //Разбор строки
+                                    while (csvPos < csv_line.Length)
+                                    {
+                                        int newValuesCount = valuesCount;
+                                        char c3 = csv_line[csvPos];
+                                        if (c3 == '"')
+                                        {
+                                            csvText += c3;
+                                            //Кавычка
+                                            if (csvQuote == (int)QuoteType.None)
+                                            {
+                                                csvQuote = (int)QuoteType.Double;
+                                            }
+                                            else if (csvQuote == (int)QuoteType.Double)
+                                            {
+                                                if ((csvPos + 1 < csv_line.Length) && (csv_line[csvPos + 1] == '"'))
+                                                {
+                                                    //Экранированная кавычка
+                                                    csvText += csv_line[csvPos + 1];
+                                                    csvPos++;
+                                                }
+                                                else
+                                                {
+                                                    csvQuote = (int)QuoteType.None;
+                                                }
+                                            }
+                                        }
+                                        else if (csvQuote != (int)QuoteType.None)
+                                        {
+                                            //Строка текста внутри кавычек
+                                            csvText += c3;
+                                        }
+                                        else if (c3.ToString() == delimiter)
+                                        {
+                                            newValuesCount++;
+                                            csvValueCompleted = true;
+                                        }
+                                        else
+                                        {
+                                            csvText += c3;
+                                        }
+
+                                        if ((csvQuote == (int)QuoteType.None) && (csvPos == csv_line.Length - 1))
+                                        {
+                                            newValuesCount++;
+                                            csvValueCompleted = true;
+                                        }
+
+                                        if (csvValueCompleted)
+                                        {
+                                            for (int iter = valuesCount + 1; iter <= newValuesCount; iter++)
+                                            {
+                                                csvText = CsvUnEscape(csvText.Trim(WhiteSpace));
+                                                if (iter == 1)   //Первая колонка - имя локации и номер строки
+                                                {
+                                                    string[] csvFirst = csvText.Split(":".ToCharArray());
+                                                    if (csvFirst.Length == 2)
+                                                    {
+                                                        csvLineIndex = Convert.ToInt32(csvFirst[0]);
+                                                        csvLocName = csvFirst[1];
+                                                    }
+                                                }
+                                                else if (iter == 2)   //Вторая колонка - оригинал
+                                                {
+                                                    csvOriginalLine = csvText;
+                                                }
+                                                else if (iter == 3)   //Третья колонка - перевод
+                                                {
+                                                    thirdValue = csvText;
+                                                }
+                                                csvText = "";
+                                            }
+                                            csvValueCompleted = false;
+                                            valuesCount = newValuesCount;
+                                        }
+                                        csvPos++;
+                                    }
+                                    if (csvQuote == (int)QuoteType.None)
+                                    {
+                                        csvLineCompleted = true;
+                                    }
+                                    else
+                                    {
+                                        csvText += Environment.NewLine;
+                                    }
+                                }
+
+                                if ((csv_line == null) || (csvLineCompleted && 
+                                    ((csvLocName != locName) || (quoted_line_counter != csvLineIndex) || (csvOriginalLine != quotedText))))
+                                {
+                                    SubmitError("CSV-file does not match the original! Generate it again.", INVALID_INDEX);
+                                    aborted = true;
+                                    break;
+                                }
+                                if (!csvLineCompleted)
+                                {
+                                    SubmitError("CSV-file damaged! Line number: " + quoted_line_counter.ToString(), INVALID_INDEX);
+                                    aborted = true;
+                                    break;
+                                }
+                                translation = thirdValue;
+
+                                if (translation.Length == 0)
+                                {
+                                    if (IgnoreEmptyTranslations)
+                                    {
+                                        translation = quotedText;
+                                    }
+                                    else
+                                    {
+                                        SubmitError("Line number " + quoted_line_counter + " is not converted!", INVALID_INDEX);
+                                        aborted = true;
+                                        break;
+                                    }
+                                }
+                            }
+                            rawText += translation;
+                            rawText += c;
+                            quotedTextCompleted = false;
+                        }
+                        pos++;
+                    }
+                    if (aborted)
+                        break;
+                    if (quote == (int)QuoteType.None)
+                    {
+                        //Записываем строку в файл перевода
+                        fo.WriteLine(rawText);
+                        rawText = "";
+                    }
+                }
+                else
+                {
+                    fo.WriteLine(line);
+                }
+            }
+            fi_src.Close();
+            fi_csv.Close();
+            fo.Close();
+            if (aborted)
+            {
+                //Убить корявый перевод
+                File.Delete(dstFile);
+            }
+            return !aborted;
+        }
+
+        static public bool OpenStreamForReading(ref StreamReader fi, string file)
+        {
+            bool result = false;
+            try
+            {
+                fi = new StreamReader(file, Encoding.Default);
+                result = true;
+            }
+            catch (Exception e)
+            {
+                SubmitError("File \"" + file + "\" cannot be opened for reading (it can be opened by another program).", INVALID_INDEX);
+                result = false;
+            }
+            return result;
+        }
+
+        static public bool OpenStreamForWriting(ref StreamWriter fo, string file)
+        {
+            bool result = false;
+            try
+            {
+                fo = new StreamWriter(file, false, Encoding.Default);
+                result = true;
+            }
+            catch (Exception e)
+            {
+                SubmitError("File \"" + file + "\" cannot be opened for writing (it can be opened by another program).", INVALID_INDEX);
+                result = false;
+            }
+            return result;
+        }
+    }
+}

+ 667 - 0
QSP/qsp-analyser/QSP_Analyser/List.txt

@@ -0,0 +1,667 @@
+Common.cs
+Line 1430:	SubmitError("CSV-файл не соответствует исходному! Сгенерируйте его заново.", INVALID_INDEX);
+			SubmitError("CSV-file does not match the original! Generate it again.", INVALID_INDEX);
+
+			
+Line 1436:	SubmitError("CSV-файл поврежден! Номер строки: " + quoted_line_counter.ToString(), INVALID_INDEX);
+			SubmitError("CSV-file damaged! Line number: " + quoted_line_counter.ToString(), INVALID_INDEX);
+
+			
+Line 1450:	SubmitError("Не переведена строка номер " + quoted_line_counter + "!", INVALID_INDEX);
+			SubmitError("Line number " + quoted_line_counter + " is not converted!", INVALID_INDEX);
+			
+
+Line 1497:	SubmitError("Файл \"" + file + "\" недоступен для чтения (возможно, он открыт другой программой).", INVALID_INDEX);
+			SubmitError("File \"" + file + "\" cannot be opened for reading (it can be opened by another program).", INVALID_INDEX);
+			
+
+Line 1513:	SubmitError("Файл \"" + file + "\" недоступен для записи (возможно, он открыт другой программой).", INVALID_INDEX);
+			SubmitError("File \"" + file + "\" cannot be opened for writing (it can be opened by another program).", INVALID_INDEX);
+			
+
+MainForm.Designer.cs
+Line 86:             this.label1.Text = "Эта утилита анализирует код игры на языке QSP в формате TXT2GAM.";
+Line 86:             this.label1.Text = "This utility analyzes the QSP game code in form TXT2GAM.";
+
+
+Line 137:             this.btnTry1.Text = "Локации";
+Line 137:             this.btnTry1.Text = "Locations";
+
+
+Line 147:             this.btnTry2.Text = "Переменные";
+Line 147:             this.btnTry2.Text = "Variables";
+
+
+Line 157:             this.btnTry3.Text = "Предметы";
+Line 157:             this.btnTry3.Text = "Items";
+
+
+Line 199:             this.tabCheck.Text = "Анализ"
+Line 199:             this.tabCheck.Text = "Analysis";
+
+
+Line 208:             this.btnTry4.Text = "Действия";
+Line 208:             this.btnTry4.Text = "Events";
+
+
+Line 218:             this.btnReload.Text = "Перечитать";
+Line 218:             this.btnReload.Text = "Reload";
+
+
+Line 242:             this.tabOptions.Text = "Настройки";
+Line 242:             this.tabOptions.Text = "Settings";
+
+
+Line 255:             this.chkCurlyParse.Text = "Интерпретировать содержимое фигурных скобок как код";
+Line 255:             this.chkCurlyParse.Text = "Content between curly brackets take as a code";
+
+
+Line 268:             this.chkActions.Text = "Действия";
+Line 268:             this.chkActions.Text = "Actions";
+
+
+Line 305:             this.lblSystemVariables.Text = "Системные переменные(исключения из списка неиспользуемых переменных)";
+Line 305:             this.lblSystemVariables.Text = "System variables (exception from the list of unused variables)";
+
+
+Line 314:             this.lblSortHeader.Text = "Сортировать при выводе:";
+Line 314:             this.lblSortHeader.Text = "Sort by output:";
+
+
+Line 322:             this.btnReset.Text = "Сбросить настройки";
+Line 322:             this.btnReset.Text = "Reset settings";
+
+
+Line 347:             this.chkSortObjects.Text = "Предметы";
+Line 347:             this.chkSortObjects.Text = "Items";
+
+
+Line 360:             this.chkSortVariables.Text = "Переменные";
+Line 360:             this.chkSortVariables.Text = "Variables";
+
+
+Line 373:             this.chkSortLocations.Text = "Локации";
+Line 373:             this.chkSortLocations.Text = "Locations";
+
+
+Line 399:             this.chkVariableCalls.Text = "Считать присваивание переменных \r\nссылкой на локацию:";
+Line 399:             this.chkVariableCalls.Text = "Consider variable assignment \r\nby link to location:";
+
+
+Line 410:             this.tabTranslate.Text = "Конвертация";
+Line 410:             this.tabTranslate.Text = "Conversion";
+
+
+Line 423:             this.chkIgnoreEmptyTranslationsCsv.Text = "Игнорировать непереведенные строки\r\n(для \"пустых\" значений перевода будет оставлен текст оригинала)";
+Line 423:             this.chkIgnoreEmptyTranslationsCsv.Text = "Ignore unconverted strings\r\n(for \"empty\" value of conversion will be used original text)";
+
+
+Line 434:             this.lblSuffixCsv.Text = "Суффикс для файла перевода:";
+Line 433:             this.lblSuffixCsv.Text = "Extension for conversion file:";
+
+
+Line 451:             this.btnTranslateFromCsv.Text = "Сделать перевод, используя CSV";
+Line 451:             this.btnTranslateFromCsv.Text = "Make conversion, use CSV";
+
+
+Line 464:             this.grpCsvDelimiter.Text = "Разделитель CSV";
+Line 464:             this.grpCsvDelimiter.Text = "Split CSV";
+
+
+Line 475:             this.radComma.Text = "Запятая - ,";
+Line 475:             this.radComma.Text = "Comma - ,";
+
+
+Line 485:             this.radSemicolon.Text = "Точка с запятой - ;";
+Line 485:             this.radSemicolon.Text = "Semicolon - ;";
+
+
+Line 494:             this.btnExportCsv.Text = "Экспорт в CSV";
+Line 494:             this.btnExportCsv.Text = "Export to CSV";
+
+
+Line 520:             this.grpTranslateCsv.Text = "Перевод";
+Line 520:             this.grpTranslateCsv.Text = "Conversion";
+
+
+Line 528:             this.btnBeautify.Text = "Отформатировать код";
+Line 528:             this.btnBeautify.Text = "Format the code";
+
+
+Line 546:             this.Text = "Анализатор кода QSP";
+Line 546:             this.Text = "QSP Code Analyzer";
+
+MainForm.cs
+
+Line 72:             Log("Ошибок: " + Common.GetErrorsCount() + ", предупреждений: " + Common.GetWarningsCount());
+Line 72:             Log("No of errors: " + Common.GetErrorsCount() + ", warnings: " + Common.GetWarningsCount());
+
+
+Line 77:                 string errorMessage = "локация \"" + error.locationName + "\", строка #" + Convert.ToString(err_line) + " : " + error.text;
+Line 77:                 string errorMessage = "Location \"" + error.locationName + "\", Line #" + Convert.ToString(err_line) + " : " + error.text;
+
+
+Line 80:                     Log("Ошибка, " + errorMessage);
+Line 80:                     Log("Error, " + errorMessage);
+
+
+Line 84:                     Log("Предупреждение, " + errorMessage);
+Line 84:                     Log("Warning, " + errorMessage);
+
+
+Line 100:                 Log("Пытаемся прочесть файл...");
+Line 100:                 Log("Trying to read the file ...");
+
+
+Line 103:                     Log("Файл успешно прочитался.");
+Line 103:                     Log("The file was read successfully");
+
+
+Line 110:                 Log("Файл не загружен.");
+Line 110:                 Log("File was not read.");
+
+
+Line 182:                         MessageBox.Show("Исходный файл не найден!");
+Line 182:                         MessageBox.Show("Input file was not found!");
+
+
+Line 188:                     MessageBox.Show("Выберите исходный файл!");
+Line 188:                     MessageBox.Show("Select input file!");
+
+
+Line 235:             Log("Обрабатываем имена локаций...");
+Line 235:             Log("We process the names of locations ...");
+
+
+Line 236:             PrintArray(txtList1, LocationsDefined, "Существующие локации");
+Line 236:             PrintArray(txtList1, LocationsDefined, "Existing locations");
+
+
+Line 237:             Log("Добавлено локаций: " + LocationsDefined.Count.ToString());
+Line 237:             Log("Added locations: " + LocationsDefined.Count.ToString());
+
+
+Line 239:             Log("Обрабатываем ссылки на локации...");
+Line 239:             Log("We process the reference to locations...");
+
+
+Line 240:             PrintArray(txtList2, LocationsReferenced, "Ссылки на локации");
+Line 240:             PrintArray(txtList2, LocationsReferenced, "References to locations");
+
+
+Line 241:             Log("Добавлено ссылок на локации: " + LocationsReferenced.Count.ToString());
+Line 241:             Log("Added reference to location: " + LocationsReferenced.Count.ToString());
+
+
+Line 243:             Log("Начинаем поиск неправильных ссылок...");
+Line 243:             Log("We begin to search for incorrect links ...");
+
+
+Line 244:             PrintArray(txtList3, LocationsUnDefined, "Неверные ссылки");
+Line 244:             PrintArray(txtList3, LocationsUnDefined, "incorrect links");
+
+
+Line 245:             Log("Найдено неправильных ссылок: " + LocationsUnDefined.Count.ToString());
+Line 245:             Log("Found incorrect links: " + LocationsUnDefined.Count.ToString());
+
+
+Line 247:             Log("Начинаем поиск потерянных локаций - тех, на которые нет ссылок...");
+Line 247:             Log("We begin to search for lost locations - those for which there are no references ...");
+
+
+Line 248:             PrintArray(txtList3, LocationsUnReferenced, "Потерянные локации");
+Line 248:             PrintArray(txtList3, LocationsUnReferenced, "Lost locations");
+
+
+Line 249:             Log("Найдено потерянных локаций: " + LocationsUnReferenced.Count.ToString());
+Line 249:             Log("Found lost locations: " + LocationsUnReferenced.Count.ToString());
+
+
+Line 266:             Log("Выполняем поиск переменных...");
+Line 266:             Log("Search for variables ...");
+
+
+Line 293:             PrintArray(txtList1, TextVars, "Текстовые переменные");
+Line 293:             PrintArray(txtList1, TextVars, "String variables");
+
+
+Line 294:             PrintArray(txtList2, NumericVars, "Числовые переменные");
+Line 294:             PrintArray(txtList2, NumericVars, "Numeric variables");
+
+
+Line 296:             Log("Добавлено переменных: " + Common.vars.Count.ToString());
+Line 296:             Log("Added variables: " + Common.vars.Count.ToString());
+
+
+Line 300:             PrintArray(txtList3, TextVars_unassigned, "Не иниц. переменные:");
+Line 300:             PrintArray(txtList3, TextVars_unassigned, "no init variables:");
+
+
+Line 301:             Log("Найдено обращений к неинициализированным текстовым переменным: " + TextVars_unassigned.Count.ToString());
+Line 301:             Log("Found using of uninitialized text variables: " + TextVars_unassigned.Count.ToString());
+
+
+Line 305:             Log("Найдено обращений к неинициализированным числовым переменным: " + NumericVars_unassigned.Count.ToString());
+Line 305:             Log("Found using of uninitialized numeric variables: " + NumericVars_unassigned.Count.ToString());
+
+
+Line 309:             PrintArray(txtList3, TextVars_unused, "Не исп. переменные:");
+Line 309:             PrintArray(txtList3, TextVars_unused, "Unused variables:");
+
+
+Line 310:             Log("Найдено неиспользуемых текстовых переменных: " + TextVars_unused.Count.ToString());
+Line 310:             Log("Found unused string variables: " + TextVars_unused.Count.ToString());
+
+
+Line 314:             Log("Найдено неиспользуемых числовых переменных: " + NumericVars_unused.Count.ToString());
+Line 314:             Log("Found unused numeric variables: " + NumericVars_unused.Count.ToString());
+
+
+Line 349:             Log("Выполняем поиск предметов...");
+Line 349:             Log("Search of items...");
+
+
+Line 350:             PrintArray(txtList1, ObjectsAdded, "Добавление предмета");
+Line 350:             PrintArray(txtList1, ObjectsAdded, "Added items");
+
+
+Line 351:             PrintArray(txtList2, ObjectsDeleted, "Удаление предмета");
+Line 351:             PrintArray(txtList2, ObjectsDeleted, "Remove item");
+
+
+Line 352:             Log("Добавлений предметов: " + ObjectsAdded.Count.ToString());
+Line 352:             Log("Items adding: " + ObjectsAdded.Count.ToString());
+
+
+Line 353:             Log("Удалений предметов: " + ObjectsDeleted.Count.ToString());
+Line 353:             Log("Items removing: " + ObjectsDeleted.Count.ToString());
+
+
+Line 355:             Log("Начинаем поиск удаления несуществующих предметов...");
+Line 355:             Log("Search of nonexisting items...");
+
+
+Line 356:             PrintArray(txtList3, ObjectsUnDefined, "Неверное удаление");
+Line 356:             PrintArray(txtList3, ObjectsUnDefined, "Invalid deletion");
+
+
+Line 357:             Log("Найдено неправильных удалений: " + ObjectsUnDefined.Count.ToString());
+Line 357:             Log("Found invalid deletions: " + ObjectsUnDefined.Count.ToString());
+
+
+Line 359:             Log("Начинаем поиск потерянных предметов - те, которые не удаляются в процессе игры...");
+Line 359:             Log("Looking for lost items - those that are not deleted during the game ...");
+
+
+Line 360:             PrintArray(txtList3, ObjectsLost, "Потерянные предметы");
+Line 360:             PrintArray(txtList3, ObjectsLost, "Lost items");
+
+
+Line 361:             Log("Найдено потерянных предметов: " + ObjectsLost.Count.ToString());
+Line 361:             Log("Lost items found: " + ObjectsLost.Count.ToString());
+
+
+Line 392:             Log("Выполняем поиск действий...");
+Line 392:             Log("Search for actions...");
+
+
+Line 393:             PrintArray(txtList1, ActsAdded, "Добавление действия");
+Line 393:             PrintArray(txtList1, ActsAdded, "Add an action");
+
+
+Line 394:             PrintArray(txtList2, ActsDeleted, "Удаление действия");
+Line 394:             PrintArray(txtList2, ActsDeleted, "Remove an action");
+
+
+Line 395:             Log("Добавлений действий: " + ActsAdded.Count.ToString());
+Line 395:             Log("Added action: " + ActsAdded.Count.ToString());
+
+
+Line 396:             Log("Удалений действий: " + ActsDeleted.Count.ToString());
+Line 396:             Log("Removed action: " + ActsDeleted.Count.ToString());
+
+
+Line 398:             Log("Начинаем поиск удаления несуществующих действий...");
+Line 398:             Log("We begin to search for deletion of nonexistent actions...");
+
+
+Line 399:             PrintArray(txtList3, ActsUnDefined, "Неверное удаление");
+Line 399:             PrintArray(txtList3, ActsUnDefined, "Invalid deletion");
+
+
+Line 400:             Log("Найдено неправильных удалений: " + ActsUnDefined.Count.ToString());
+Line 400:             Log("Invalid deletions found: " + ActsUnDefined.Count.ToString());
+
+
+Line 450:                     MessageBox.Show("Ошибка: " + error.text);
+Line 450:                     MessageBox.Show("Error: " + error.text);
+
+
+Line 464:                     MessageBox.Show("В файле есть ошибки синтаксиса, экспорт невозможен!");
+Line 464:                     MessageBox.Show("There are syntax errors in the file, export is not possible!");
+
+
+Line 498:                     MessageBox.Show("В файле есть ошибки синтаксиса, экспорт невозможен!");
+Line 498:                     MessageBox.Show("There are syntax errors in the file, export is not possible!");
+
+
+Line 505:                     MessageBox.Show("Не обнаружен файл CSV!");
+Line 505:                     MessageBox.Show("CSV file was not found!");
+
+
+Line 510:                     MessageBox.Show("Введите суффикс для файла перевода.");
+Line 510:                     MessageBox.Show("Enter an extension of the conversion file.");
+
+
+QSPGameCode.cs
+
+Line 98:                 SubmitError("Слишком сложное выражение", currentLine);
+Line 98:                 SubmitError("Quite complicated expression", currentLine);
+
+
+Line 110:                 SubmitError("Слишком много аргументов в выражении", currentLine);
+Line 110:                 SubmitError("Quite many arguments in the expression", currentLine);
+
+
+Line 193:                                 SubmitError("Закрывающая фигурная скобка без открывающей", oldLine + 1);
+Line 193:                                 SubmitError("Closing curly brace without opening one", oldLine + 1);
+
+
+Line 229:                 SubmitError("Незакрытая строка", oldLine + 1);
+Line 229:                 SubmitError("Unclosed string", oldLine + 1);
+
+
+Line 235:                 SubmitError("Незакрытая фигурная скобка", oldLine + 1);
+Line 235:                 SubmitError("Unclosed curly bracket", oldLine + 1);
+
+
+Line 476:                             SubmitError("Внутренняя ошибка анализатора - незакрытая фигурная скобка \"{\"", currentLine);
+Line 476:                             SubmitError("Internal error of the analyzer - unclosed curly bracket \"{\"", currentLine);
+
+
+Line 505:                                     SubmitError("Пустая метка", lineNum);
+Line 505:                                     SubmitError("Empty label", lineNum);
+
+
+Line 510:                                     SubmitError("Незакрытая строка в названии метки", lineNum);
+Line 510:                                     SubmitError("Unclosed string in the label name", lineNum);
+
+
+Line 546:                                             SubmitError("ELSEIF без IF", lineNum);
+Line 546:                                             SubmitError("ELSEIF without IF", lineNum);
+
+
+Line 557:                                         SubmitError("Многострочный IF должен стоять в начале строки", lineNum);
+Line 557:                                         SubmitError("Multiline IF should be placed at the beginning of the line", lineNum);
+
+
+Line 559:                                         SubmitError("Многострочный ELSEIF должен стоять в начале строки", lineNum);
+Line 559:                                         SubmitError("Multiline ELSEIF should be placed at the beginning of the line", lineNum);
+
+
+Line 578:                                     SubmitError("ELSEIF в однострочном IF не поддерживается", lineNum);
+Line 578:                                     SubmitError("ELSEIF cannot be used in single line IF", lineNum);
+
+
+Line 584:                                 SubmitError("После знака \":\" в многострочном ELSEIF не должно быть операторов", lineNum);
+Line 584:                                 SubmitError("An operator cannot be placed after colon\":\" in multiline ELSEIF", lineNum);
+
+
+Line 609:                                     SubmitError("Многострочный ACT должен стоять в начале строки", lineNum);
+Line 609:                                     SubmitError("Multiline ACT should be placed at the beginning of the line", lineNum);
+
+
+Line 637:                                     SubmitError("Лишний \"&\": возможно, вы хотели написать \"AND\"", lineNum);
+Line 637:                                     SubmitError("Redundant \"&\": perhaps should be \"AND\"", lineNum);
+
+
+Line 643:                                     SubmitError("Лишний \"&\"", lineNum);
+Line 643:                                     SubmitError("Redundant \"&\"", lineNum);
+
+
+Line 678:                                 SubmitError("Квадратная скобка ставится только сразу за именем массива, без пробелов", lineNum);
+Line 678:                                 SubmitError("A square bracket has to be placed just behind the name of the array, with no spaces", lineNum);
+
+
+Line 692:                                         SubmitError("Лишняя скобка \")\"", lineNum);
+Line 692:                                         SubmitError("Redundant bracket \")\"", lineNum);
+
+
+Line 788:                             SubmitError("Внутренняя ошибка анализатора! Пустой блок!", lineNum);
+Line 788:                             SubmitError("Internal error of analyzer! Empty block!", lineNum);
+
+
+Line 817:                                 SubmitError("ELSEIF без IF", lineNum);
+Line 817:                                 SubmitError("ELSEIF без IF", lineNum);
+
+
+Line 839:                                         SubmitError("После многострочного ELSE не должно быть операторов", lineNum);
+Line 839:                                         SubmitError("An operator cannot be placed after multiline ELSE", lineNum);
+
+
+Line 864:                                             SubmitError("ELSE без IF", lineNum);
+Line 864:                                             SubmitError("ELSE without IF", lineNum);
+
+
+Line 870:                                         SubmitError("Неверная запись однострочного ACT", lineNum);
+Line 870:                                         SubmitError("Invalid notation of single line ACT", lineNum);
+
+
+Line 882:                                         SubmitError("Перед ELSE в однострочном IF должны быть операторы", lineNum);
+Line 882:                                         SubmitError("After single line IF has to be any operators before ELSE", lineNum);
+
+
+Line 888:                                     SubmitError("ELSE без IF", lineNum);
+Line 888:                                     SubmitError("ELSE without IF", lineNum);
+
+
+Line 923:                                 SubmitError("Лишний END", lineNum);
+Line 923:                                 SubmitError("Redundant END", lineNum);
+
+
+Line 982:                             SubmitError("Внутренняя ошибка анализатора! Пустой блок!", lineNum);
+Line 982:                             SubmitError("Internal error of the analyzer! Empty block!", lineNum);
+
+
+Line 1000:                     SubmitError("Лишняя скобка \"(\"", lineNum);
+Line 1000:                     SubmitError("Redundant bracket \"(\"", lineNum);
+
+
+Line 1005:                     SubmitError("IF без \":\"", lineNum);
+Line 1005:                     SubmitError("IF without \":\"", lineNum);
+
+
+Line 1010:                     SubmitError("ACT без \":\"", lineNum);
+Line 1010:                     SubmitError("ACT without \":\"", lineNum);
+
+
+Line 1031:                         SubmitError("Неверная запись однострочного ACT", lineNum);
+Line 1031:                         SubmitError("Invalid notation of single line ACT", lineNum);
+
+
+Line 1036:                         SubmitError("Неверная запись однострочного IF", lineNum);
+Line 1036:                         SubmitError("Invalid notation of single line IF", lineNum);
+
+
+Line 1041:                         SubmitError("После ELSE в однострочном IF должны быть операторы", lineNum);
+Line 1041:                         SubmitError("In single line IF has to be any operators after ELSE", lineNum);
+
+
+Line 1085:                     SubmitError("Многострочный IF без END", cline.line);
+Line 1085:                     SubmitError("Multi line IF without END", cline.line);
+
+
+Line 1090:                     SubmitError("Многострочный ACT без END", cline.line);
+Line 1090:                     SubmitError("Multi line ACT without END", cline.line);
+
+
+Line 1117:                     SubmitError("Не найден знак \"=\"", currentLine);
+Line 1117:                     SubmitError("Not found the char \"=\"", currentLine);
+
+
+Line 1125:                         SubmitError("Не указано имя переменной для присваивания, слева от знака \"=\"", currentLine);
+Line 1125:                         SubmitError("The name of a variable before the character \"=\" is not specified!", currentLine);
+
+
+Line 1131:                         SubmitError("После знака \"=\" должно быть значение для присваивания", currentLine);
+Line 1131:                         SubmitError("It should be a value after char \"=\"", currentLine);
+
+
+Line 1191:                         SubmitError("Оператор IF без условия", currentLine);
+Line 1191:                         SubmitError("Operator IF without condition", currentLine);
+
+
+Line 1195:                         SubmitError("Оператор ELSEIF без условия", currentLine);
+Line 1195:                         SubmitError("Operator ELSEIF without condition", currentLine);
+
+
+Line 1298:                         SubmitError("Слишком много аргументов для оператора", currentLine);
+Line 1298:                         SubmitError("Too many arguments for the operator", currentLine);
+
+
+Line 1312:                             SubmitError("Аргумент не может быть пустым", currentLine);
+Line 1312:                             SubmitError("Argument can not be empty", currentLine);
+
+
+Line 1327:                         SubmitError("Аргумент не может быть пустым", currentLine);
+Line 1327:                         SubmitError("Argument can not be empty", currentLine);
+
+
+Line 1334:                 SubmitError("Для оператора требуется больше аргументов", currentLine);
+Line 1334:                 SubmitError("The operator requires more arguments", currentLine);
+
+
+Line 1369:                         SubmitError("Неизвестное действие в выражении", currentLine);
+Line 1369:                         SubmitError("Unknown action in the expression", currentLine);
+
+
+Line 1376:                         SubmitError("Ошибка синтаксиса", currentLine);
+Line 1376:                         SubmitError("Syntax error", currentLine);
+
+
+Line 1390:                             SubmitError("Ошибка синтаксиса", currentLine);
+Line 1390:                             SubmitError("Syntax error", currentLine);
+
+
+Line 1402:                             SubmitError("Не найдена закрывающая скобка", currentLine);
+Line 1402:                             SubmitError("Closing bracket not found", currentLine);
+
+
+Line 1410:                             SubmitError("Не найдена открывающая скобка", currentLine);
+Line 1410:                             SubmitError("Opening bracket not found", currentLine);
+
+
+Line 1419:                                 SubmitError("Неверное число аргументов функции", currentLine);
+Line 1419:                                 SubmitError("Invalid number of arguments", currentLine);
+
+
+Line 1496:                                 SubmitError("Неверное число аргументов функции", currentLine);
+Line 1496:                                 SubmitError("Invalid number of arguments", currentLine);
+
+
+Line 1498:                                 SubmitError("Ошибка синтаксиса", currentLine);
+Line 1498:                                 SubmitError("Syntax error", currentLine);
+
+
+Line 1504:                             SubmitError("Ошибка синтаксиса", currentLine);
+Line 1504:                             SubmitError("Syntax error", currentLine);
+
+
+Line 1509:                             SubmitError("Неверное число аргументов функции", currentLine);
+Line 1509:                             SubmitError("Invalid number of arguments", currentLine);
+
+
+Line 1522:                             SubmitError("Внутренняя ошибка анализатора: недопустимые символы в имени переменной", currentLine);
+Line 1522:                             SubmitError("Internal error of the analyzer: Invalid characters in the variable name", currentLine);
+
+
+Line 1554:                                 SubmitError("Скобки не найдены", currentLine);
+Line 1554:                                 SubmitError("Brackets not found", currentLine);
+
+
+Line 1587:                                     SubmitError("Незакрытая скобка \"[\"", currentLine);
+Line 1587:                                     SubmitError("Unclosed parenthesis \"[\"", currentLine);
+
+
+Line 1609:                             SubmitError("Неверное число аргументов функции", currentLine);
+Line 1609:                             SubmitError("Invalid number of arguments", currentLine);
+
+
+Line 1611:                             SubmitError("Ошибка синтаксиса", currentLine);
+Line 1611:                             SubmitError("Syntax error", currentLine);
+
+
+Line 1625:                 SubmitError("Внутренняя ошибка анализатора: пустое имя переменной!", currentLine);
+Line 1625:                 SubmitError("Internal error of the analyzer: empty name of variable!", currentLine);
+
+
+Line 1634:                 SubmitError("Ключевое слово языка \"" + name + "\" не может быть использовано в качестве имени переменной", currentLine);
+Line 1634:                 SubmitError("QSP Keyword \"" + name + "\" cannot be used as a variable name", currentLine);
+
+
+Line 1647:                 SubmitError("Недопустимое имя переменной \"" + name + "\"", currentLine);
+Line 1647:                 SubmitError("Invalid variable name \"" + name + "\"", currentLine);
+
+
+Line 1653:                 SubmitError("Имя переменной \"" + name + "\" не может начинаться с цифры", currentLine);
+Line 1653:                 SubmitError("Variable name \"" + name + "\" cannot start with a digit", currentLine);
+
+
+Line 1659:                 SubmitError("Недопустимые символы в имени переменной \"" + name + "\"", currentLine);
+Line 1659:                 SubmitError("Invalid symbols in the name of the variable \"" + name + "\"", currentLine);
+
+
+Line 1666:                 SubmitWarning("В имени переменной \"" + name + "\" используются одновременно английские и русские символы, возможно опечатка", currentLine);
+Line 1666:                 SubmitWarning("English and Russian symbols are used simultaneously in the name of varible \"" + name + "\" , possibly a typo", currentLine);
+
+
+Line 1687:                     SubmitError("Недопустимое выражение", currentLine);
+Line 1687:                     SubmitError("Invalid expression", currentLine);
+
+
+Line 1708:                 SubmitError("Слева от знака \"=\" в операции присваивания должно стоять имя переменной", currentLine);
+Line 1708:                 SubmitError("Name of the variable should be before char \"=\" in the assignment operation", currentLine);
+
+
+Line 1908:                     SubmitWarning("Незакрытый апостроф внутри тега", currentLine);
+Line 1908:                     SubmitWarning("Unclosed apostrophe inside the tag", currentLine);
+
+
+Line 1913:                     SubmitWarning("Незакрытая кавычка внутри тега", currentLine);
+Line 1913:                     SubmitWarning("Unclosed quote inside the tag", currentLine);
+
+
+Line 1918:                     SubmitWarning("Незакрытый тег",currentLine);
+Line 1918:                     SubmitWarning("Unclosed tag",currentLine);
+
+
+Line 1923:                     SubmitWarning("Имя тега должно следовать сразу за открывающей угловой скобкой, без пробелов", currentLine);
+Line 1923:                     SubmitWarning("The name of the tag should follow immediately after the opening angle bracket, without spaces", currentLine);
+
+
+Line 2048:                         SubmitError("Незакрытый апостроф в подвыражении", currentLine);
+Line 2048:                         SubmitError("Unclosed apostrophe in a subexpression", currentLine);	
+	
+
+Line 2055:                         SubmitError("Незакрытая кавычка в подвыражении", currentLine);	
+Line 2055:                         SubmitError("Unclosed quote in a subexpression", currentLine);
+
+
+Line 2062:                         SubmitError("Незакрытая фигурная скобка в подвыражении", currentLine);
+Line 2062:                         SubmitError("Unclosed curly bracket in a subexpression", currentLine);
+
+
+Line 2069:                         SubmitError("Незакрытое подвыражение", currentLine);
+Line 2069:                         SubmitError("Unclosed subexpression", currentLine);
+
+
+Line 2076:                         SubmitError("Пустое подвыражение", currentLine);
+Line 2076:                         SubmitError("Empty subexpression", currentLine);
+
+
+Line 2173:                 SubmitError("Пустое имя локации", line);
+Line 2173:                 SubmitError("Empty name of location", line);
+
+
+Line 2178:                 SubmitError("Локация с именем " + name + " уже существует", line);
+Line 2178:                 SubmitError("Location named " + name + " exist already", line);

+ 609 - 0
QSP/qsp-analyser/QSP_Analyser/MainForm.Designer.cs

@@ -0,0 +1,609 @@
+namespace Analyser
+{
+    partial class MainForm
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.label1 = new System.Windows.Forms.Label();
+            this.dlgOpen = new System.Windows.Forms.OpenFileDialog();
+            this.btnBrowse = new System.Windows.Forms.Button();
+            this.txtList1 = new System.Windows.Forms.TextBox();
+            this.txtList2 = new System.Windows.Forms.TextBox();
+            this.txtList3 = new System.Windows.Forms.TextBox();
+            this.btnTry1 = new System.Windows.Forms.Button();
+            this.btnTry2 = new System.Windows.Forms.Button();
+            this.btnTry3 = new System.Windows.Forms.Button();
+            this.txtStatus = new System.Windows.Forms.TextBox();
+            this.tabControl = new System.Windows.Forms.TabControl();
+            this.tabCheck = new System.Windows.Forms.TabPage();
+            this.btnTry4 = new System.Windows.Forms.Button();
+            this.btnReload = new System.Windows.Forms.Button();
+            this.tabOptions = new System.Windows.Forms.TabPage();
+            this.chkCurlyParse = new System.Windows.Forms.CheckBox();
+            this.chkActions = new System.Windows.Forms.CheckBox();
+            this.txtSystemAeroVars = new System.Windows.Forms.TextBox();
+            this.chkAero = new System.Windows.Forms.CheckBox();
+            this.lblSystemVariables = new System.Windows.Forms.Label();
+            this.lblSortHeader = new System.Windows.Forms.Label();
+            this.btnReset = new System.Windows.Forms.Button();
+            this.txtSystemVariables = new System.Windows.Forms.TextBox();
+            this.chkSortObjects = new System.Windows.Forms.CheckBox();
+            this.chkSortVariables = new System.Windows.Forms.CheckBox();
+            this.chkSortLocations = new System.Windows.Forms.CheckBox();
+            this.txtVariableNames = new System.Windows.Forms.TextBox();
+            this.chkVariableCalls = new System.Windows.Forms.CheckBox();
+            this.tabTranslate = new System.Windows.Forms.TabPage();
+            this.chkIgnoreEmptyTranslationsCsv = new System.Windows.Forms.CheckBox();
+            this.lblSuffixCsv = new System.Windows.Forms.Label();
+            this.edtSuffixCsv = new System.Windows.Forms.TextBox();
+            this.btnTranslateFromCsv = new System.Windows.Forms.Button();
+            this.grpCsvDelimiter = new System.Windows.Forms.GroupBox();
+            this.radComma = new System.Windows.Forms.RadioButton();
+            this.radSemicolon = new System.Windows.Forms.RadioButton();
+            this.btnExportCsv = new System.Windows.Forms.Button();
+            this.edtFile = new System.Windows.Forms.TextBox();
+            this.grpTranslateCsv = new System.Windows.Forms.GroupBox();
+            this.btnBeautify = new System.Windows.Forms.Button();
+            this.tabControl.SuspendLayout();
+            this.tabCheck.SuspendLayout();
+            this.tabOptions.SuspendLayout();
+            this.tabTranslate.SuspendLayout();
+            this.grpCsvDelimiter.SuspendLayout();
+            this.grpTranslateCsv.SuspendLayout();
+            this.SuspendLayout();
+            // 
+            // label1
+            // 
+            this.label1.AutoSize = true;
+            this.label1.Location = new System.Drawing.Point(15, 13);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(372, 13);
+            this.label1.TabIndex = 0;
+            this.label1.Text = "This utility analyzes the QSP game code in form TXT2GAM.";
+            // 
+            // btnBrowse
+            // 
+            this.btnBrowse.Location = new System.Drawing.Point(591, 8);
+            this.btnBrowse.Name = "btnBrowse";
+            this.btnBrowse.Size = new System.Drawing.Size(29, 23);
+            this.btnBrowse.TabIndex = 2;
+            this.btnBrowse.Text = "...";
+            this.btnBrowse.UseVisualStyleBackColor = true;
+            this.btnBrowse.Click += new System.EventHandler(this.btnBrowse_Click);
+            // 
+            // txtList1
+            // 
+            this.txtList1.BackColor = System.Drawing.SystemColors.Window;
+            this.txtList1.Location = new System.Drawing.Point(3, 59);
+            this.txtList1.Multiline = true;
+            this.txtList1.Name = "txtList1";
+            this.txtList1.ReadOnly = true;
+            this.txtList1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
+            this.txtList1.Size = new System.Drawing.Size(205, 348);
+            this.txtList1.TabIndex = 3;
+            // 
+            // txtList2
+            // 
+            this.txtList2.BackColor = System.Drawing.SystemColors.Window;
+            this.txtList2.Location = new System.Drawing.Point(214, 59);
+            this.txtList2.Multiline = true;
+            this.txtList2.Name = "txtList2";
+            this.txtList2.ReadOnly = true;
+            this.txtList2.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
+            this.txtList2.Size = new System.Drawing.Size(210, 348);
+            this.txtList2.TabIndex = 4;
+            // 
+            // txtList3
+            // 
+            this.txtList3.BackColor = System.Drawing.SystemColors.Window;
+            this.txtList3.Location = new System.Drawing.Point(430, 59);
+            this.txtList3.Multiline = true;
+            this.txtList3.Name = "txtList3";
+            this.txtList3.ReadOnly = true;
+            this.txtList3.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
+            this.txtList3.Size = new System.Drawing.Size(229, 348);
+            this.txtList3.TabIndex = 5;
+            // 
+            // btnTry1
+            // 
+            this.btnTry1.Location = new System.Drawing.Point(12, 6);
+            this.btnTry1.Name = "btnTry1";
+            this.btnTry1.Size = new System.Drawing.Size(77, 28);
+            this.btnTry1.TabIndex = 6;
+            this.btnTry1.Text = "Locations";
+            this.btnTry1.UseVisualStyleBackColor = true;
+            this.btnTry1.Click += new System.EventHandler(this.btnTry1_Click);
+            // 
+            // btnTry2
+            // 
+            this.btnTry2.Location = new System.Drawing.Point(95, 6);
+            this.btnTry2.Name = "btnTry2";
+            this.btnTry2.Size = new System.Drawing.Size(91, 28);
+            this.btnTry2.TabIndex = 7;
+            this.btnTry2.Text = "Variables";
+            this.btnTry2.UseVisualStyleBackColor = true;
+            this.btnTry2.Click += new System.EventHandler(this.btnTry2_Click);
+            // 
+            // btnTry3
+            // 
+            this.btnTry3.Location = new System.Drawing.Point(192, 6);
+            this.btnTry3.Name = "btnTry3";
+            this.btnTry3.Size = new System.Drawing.Size(80, 28);
+            this.btnTry3.TabIndex = 8;
+            this.btnTry3.Text = "Items";
+            this.btnTry3.UseVisualStyleBackColor = true;
+            this.btnTry3.Click += new System.EventHandler(this.btnTry3_Click);
+            // 
+            // txtStatus
+            // 
+            this.txtStatus.BackColor = System.Drawing.SystemColors.Window;
+            this.txtStatus.Location = new System.Drawing.Point(3, 413);
+            this.txtStatus.Multiline = true;
+            this.txtStatus.Name = "txtStatus";
+            this.txtStatus.ReadOnly = true;
+            this.txtStatus.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
+            this.txtStatus.Size = new System.Drawing.Size(656, 148);
+            this.txtStatus.TabIndex = 9;
+            // 
+            // tabControl
+            // 
+            this.tabControl.Controls.Add(this.tabCheck);
+            this.tabControl.Controls.Add(this.tabOptions);
+            this.tabControl.Controls.Add(this.tabTranslate);
+            this.tabControl.Location = new System.Drawing.Point(1, 37);
+            this.tabControl.Name = "tabControl";
+            this.tabControl.SelectedIndex = 0;
+            this.tabControl.Size = new System.Drawing.Size(670, 590);
+            this.tabControl.TabIndex = 12;
+            // 
+            // tabCheck
+            // 
+            this.tabCheck.Controls.Add(this.btnTry4);
+            this.tabCheck.Controls.Add(this.btnReload);
+            this.tabCheck.Controls.Add(this.btnTry1);
+            this.tabCheck.Controls.Add(this.txtStatus);
+            this.tabCheck.Controls.Add(this.txtList3);
+            this.tabCheck.Controls.Add(this.btnTry2);
+            this.tabCheck.Controls.Add(this.txtList2);
+            this.tabCheck.Controls.Add(this.btnTry3);
+            this.tabCheck.Controls.Add(this.txtList1);
+            this.tabCheck.Location = new System.Drawing.Point(4, 22);
+            this.tabCheck.Name = "tabCheck";
+            this.tabCheck.Padding = new System.Windows.Forms.Padding(3);
+            this.tabCheck.Size = new System.Drawing.Size(662, 564);
+            this.tabCheck.TabIndex = 0;
+            this.tabCheck.Text = "Analysis";
+            this.tabCheck.UseVisualStyleBackColor = true;
+            // 
+            // btnTry4
+            // 
+            this.btnTry4.Location = new System.Drawing.Point(278, 6);
+            this.btnTry4.Name = "btnTry4";
+            this.btnTry4.Size = new System.Drawing.Size(75, 28);
+            this.btnTry4.TabIndex = 13;
+            this.btnTry4.Text = "Events";
+            this.btnTry4.UseVisualStyleBackColor = true;
+            this.btnTry4.Click += new System.EventHandler(this.btnTry4_Click);
+            // 
+            // btnReload
+            // 
+            this.btnReload.Location = new System.Drawing.Point(538, 6);
+            this.btnReload.Name = "btnReload";
+            this.btnReload.Size = new System.Drawing.Size(77, 28);
+            this.btnReload.TabIndex = 12;
+            this.btnReload.Text = "Reload";
+            this.btnReload.UseVisualStyleBackColor = true;
+            this.btnReload.Click += new System.EventHandler(this.btnReload_Click);
+            // 
+            // tabOptions
+            // 
+            this.tabOptions.Controls.Add(this.chkCurlyParse);
+            this.tabOptions.Controls.Add(this.chkActions);
+            this.tabOptions.Controls.Add(this.txtSystemAeroVars);
+            this.tabOptions.Controls.Add(this.chkAero);
+            this.tabOptions.Controls.Add(this.lblSystemVariables);
+            this.tabOptions.Controls.Add(this.lblSortHeader);
+            this.tabOptions.Controls.Add(this.btnReset);
+            this.tabOptions.Controls.Add(this.txtSystemVariables);
+            this.tabOptions.Controls.Add(this.chkSortObjects);
+            this.tabOptions.Controls.Add(this.chkSortVariables);
+            this.tabOptions.Controls.Add(this.chkSortLocations);
+            this.tabOptions.Controls.Add(this.txtVariableNames);
+            this.tabOptions.Controls.Add(this.chkVariableCalls);
+            this.tabOptions.Location = new System.Drawing.Point(4, 22);
+            this.tabOptions.Name = "tabOptions";
+            this.tabOptions.Padding = new System.Windows.Forms.Padding(3);
+            this.tabOptions.Size = new System.Drawing.Size(662, 564);
+            this.tabOptions.TabIndex = 1;
+            this.tabOptions.Text = "Settings";
+            this.tabOptions.UseVisualStyleBackColor = true;
+            // 
+            // chkCurlyParse
+            // 
+            this.chkCurlyParse.AutoSize = true;
+            this.chkCurlyParse.Checked = global::Analyser.Properties.Settings.Default.EnableCurlyParsing;
+            this.chkCurlyParse.CheckState = System.Windows.Forms.CheckState.Checked;
+            this.chkCurlyParse.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::Analyser.Properties.Settings.Default, "EnableCurlyParsing", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
+            this.chkCurlyParse.Location = new System.Drawing.Point(250, 290);
+            this.chkCurlyParse.Name = "chkCurlyParse";
+            this.chkCurlyParse.Size = new System.Drawing.Size(321, 17);
+            this.chkCurlyParse.TabIndex = 23;
+            this.chkCurlyParse.Text = "Content between curly brackets take as a code";
+            this.chkCurlyParse.UseVisualStyleBackColor = true;
+            // 
+            // chkActions
+            // 
+            this.chkActions.AutoSize = true;
+            this.chkActions.Checked = global::Analyser.Properties.Settings.Default.EnableSortingActions;
+            this.chkActions.CheckState = System.Windows.Forms.CheckState.Checked;
+            this.chkActions.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::Analyser.Properties.Settings.Default, "EnableSortingActions", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
+            this.chkActions.Location = new System.Drawing.Point(260, 112);
+            this.chkActions.Name = "chkActions";
+            this.chkActions.Size = new System.Drawing.Size(76, 17);
+            this.chkActions.TabIndex = 22;
+            this.chkActions.Text = "Actions";
+            this.chkActions.UseVisualStyleBackColor = true;
+            // 
+            // txtSystemAeroVars
+            // 
+            this.txtSystemAeroVars.DataBindings.Add(new System.Windows.Forms.Binding("Enabled", global::Analyser.Properties.Settings.Default, "EnableAero", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
+            this.txtSystemAeroVars.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::Analyser.Properties.Settings.Default, "AeroSystemVars", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
+            this.txtSystemAeroVars.Enabled = global::Analyser.Properties.Settings.Default.EnableAero;
+            this.txtSystemAeroVars.Location = new System.Drawing.Point(423, 42);
+            this.txtSystemAeroVars.Multiline = true;
+            this.txtSystemAeroVars.Name = "txtSystemAeroVars";
+            this.txtSystemAeroVars.ReadOnly = true;
+            this.txtSystemAeroVars.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
+            this.txtSystemAeroVars.Size = new System.Drawing.Size(157, 190);
+            this.txtSystemAeroVars.TabIndex = 21;
+            this.txtSystemAeroVars.Text = global::Analyser.Properties.Settings.Default.AeroSystemVars;
+            // 
+            // chkAero
+            // 
+            this.chkAero.AutoSize = true;
+            this.chkAero.Checked = global::Analyser.Properties.Settings.Default.EnableAero;
+            this.chkAero.CheckState = System.Windows.Forms.CheckState.Checked;
+            this.chkAero.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::Analyser.Properties.Settings.Default, "EnableAero", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
+            this.chkAero.Location = new System.Drawing.Point(423, 13);
+            this.chkAero.Name = "chkAero";
+            this.chkAero.Size = new System.Drawing.Size(70, 17);
+            this.chkAero.TabIndex = 20;
+            this.chkAero.Text = "AeroQSP";
+            this.chkAero.UseVisualStyleBackColor = true;
+            // 
+            // lblSystemVariables
+            // 
+            this.lblSystemVariables.AutoSize = true;
+            this.lblSystemVariables.Location = new System.Drawing.Point(0, 255);
+            this.lblSystemVariables.Name = "lblSystemVariables";
+            this.lblSystemVariables.Size = new System.Drawing.Size(408, 13);
+            this.lblSystemVariables.TabIndex = 19;
+            this.lblSystemVariables.Text = "System variables (exception from the list of unused variables)";
+            // 
+            // lblSortHeader
+            // 
+            this.lblSortHeader.AutoSize = true;
+            this.lblSortHeader.Location = new System.Drawing.Point(245, 14);
+            this.lblSortHeader.Name = "lblSortHeader";
+            this.lblSortHeader.Size = new System.Drawing.Size(137, 13);
+            this.lblSortHeader.TabIndex = 15;
+            this.lblSortHeader.Text = "Sort by output:";
+            // 
+            // btnReset
+            // 
+            this.btnReset.Location = new System.Drawing.Point(13, 519);
+            this.btnReset.Name = "btnReset";
+            this.btnReset.Size = new System.Drawing.Size(147, 23);
+            this.btnReset.TabIndex = 13;
+            this.btnReset.Text = "Reset settings";
+            this.btnReset.UseVisualStyleBackColor = true;
+            this.btnReset.Click += new System.EventHandler(this.btnReset_Click);
+            // 
+            // txtSystemVariables
+            // 
+            this.txtSystemVariables.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::Analyser.Properties.Settings.Default, "SystemVariables", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
+            this.txtSystemVariables.Location = new System.Drawing.Point(0, 274);
+            this.txtSystemVariables.Multiline = true;
+            this.txtSystemVariables.Name = "txtSystemVariables";
+            this.txtSystemVariables.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
+            this.txtSystemVariables.Size = new System.Drawing.Size(213, 220);
+            this.txtSystemVariables.TabIndex = 18;
+            this.txtSystemVariables.Text = global::Analyser.Properties.Settings.Default.SystemVariables;
+            // 
+            // chkSortObjects
+            // 
+            this.chkSortObjects.AutoSize = true;
+            this.chkSortObjects.Checked = global::Analyser.Properties.Settings.Default.EnableSortingObjects;
+            this.chkSortObjects.CheckState = System.Windows.Forms.CheckState.Checked;
+            this.chkSortObjects.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::Analyser.Properties.Settings.Default, "EnableSortingObjects", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
+            this.chkSortObjects.Location = new System.Drawing.Point(260, 88);
+            this.chkSortObjects.Name = "chkSortObjects";
+            this.chkSortObjects.Size = new System.Drawing.Size(79, 17);
+            this.chkSortObjects.TabIndex = 17;
+            this.chkSortObjects.Text = "Items";
+            this.chkSortObjects.UseVisualStyleBackColor = true;
+            // 
+            // chkSortVariables
+            // 
+            this.chkSortVariables.AutoSize = true;
+            this.chkSortVariables.Checked = global::Analyser.Properties.Settings.Default.EnableSortingVariables;
+            this.chkSortVariables.CheckState = System.Windows.Forms.CheckState.Checked;
+            this.chkSortVariables.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::Analyser.Properties.Settings.Default, "EnableSortingVariables", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
+            this.chkSortVariables.Location = new System.Drawing.Point(260, 65);
+            this.chkSortVariables.Name = "chkSortVariables";
+            this.chkSortVariables.Size = new System.Drawing.Size(92, 17);
+            this.chkSortVariables.TabIndex = 16;
+            this.chkSortVariables.Text = "Variables";
+            this.chkSortVariables.UseVisualStyleBackColor = true;
+            // 
+            // chkSortLocations
+            // 
+            this.chkSortLocations.AutoSize = true;
+            this.chkSortLocations.Checked = global::Analyser.Properties.Settings.Default.EnableSortingLocations;
+            this.chkSortLocations.CheckState = System.Windows.Forms.CheckState.Checked;
+            this.chkSortLocations.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::Analyser.Properties.Settings.Default, "EnableSortingLocations", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
+            this.chkSortLocations.Location = new System.Drawing.Point(260, 42);
+            this.chkSortLocations.Name = "chkSortLocations";
+            this.chkSortLocations.Size = new System.Drawing.Size(70, 17);
+            this.chkSortLocations.TabIndex = 14;
+            this.chkSortLocations.Text = "Locations";
+            this.chkSortLocations.UseVisualStyleBackColor = true;
+            // 
+            // txtVariableNames
+            // 
+            this.txtVariableNames.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::Analyser.Properties.Settings.Default, "VariableNames", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
+            this.txtVariableNames.DataBindings.Add(new System.Windows.Forms.Binding("Enabled", global::Analyser.Properties.Settings.Default, "EnableVariableCalls", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
+            this.txtVariableNames.Enabled = global::Analyser.Properties.Settings.Default.EnableVariableCalls;
+            this.txtVariableNames.Location = new System.Drawing.Point(0, 42);
+            this.txtVariableNames.Multiline = true;
+            this.txtVariableNames.Name = "txtVariableNames";
+            this.txtVariableNames.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
+            this.txtVariableNames.Size = new System.Drawing.Size(213, 190);
+            this.txtVariableNames.TabIndex = 12;
+            this.txtVariableNames.Text = global::Analyser.Properties.Settings.Default.VariableNames;
+            // 
+            // chkVariableCalls
+            // 
+            this.chkVariableCalls.AutoSize = true;
+            this.chkVariableCalls.Checked = global::Analyser.Properties.Settings.Default.EnableVariableCalls;
+            this.chkVariableCalls.CheckState = System.Windows.Forms.CheckState.Checked;
+            this.chkVariableCalls.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::Analyser.Properties.Settings.Default, "EnableVariableCalls", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
+            this.chkVariableCalls.Location = new System.Drawing.Point(3, 6);
+            this.chkVariableCalls.Name = "chkVariableCalls";
+            this.chkVariableCalls.Size = new System.Drawing.Size(210, 30);
+            this.chkVariableCalls.TabIndex = 11;
+            this.chkVariableCalls.Text = "Consider variable assignment \r\nby link to location:";
+            this.chkVariableCalls.UseVisualStyleBackColor = true;
+            // 
+            // tabTranslate
+            // 
+            this.tabTranslate.Controls.Add(this.btnBeautify);
+            this.tabTranslate.Controls.Add(this.grpTranslateCsv);
+            this.tabTranslate.Location = new System.Drawing.Point(4, 22);
+            this.tabTranslate.Name = "tabTranslate";
+            this.tabTranslate.Size = new System.Drawing.Size(662, 564);
+            this.tabTranslate.TabIndex = 2;
+            this.tabTranslate.Text = "Conversion";
+            this.tabTranslate.UseVisualStyleBackColor = true;
+            // 
+            // chkIgnoreEmptyTranslationsCsv
+            // 
+            this.chkIgnoreEmptyTranslationsCsv.AutoSize = true;
+            this.chkIgnoreEmptyTranslationsCsv.Checked = global::Analyser.Properties.Settings.Default.IgnoreEmptyTranslationsCsv;
+            this.chkIgnoreEmptyTranslationsCsv.CheckState = System.Windows.Forms.CheckState.Checked;
+            this.chkIgnoreEmptyTranslationsCsv.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::Analyser.Properties.Settings.Default, "IgnoreEmptyTranslationsCsv", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
+            this.chkIgnoreEmptyTranslationsCsv.Location = new System.Drawing.Point(235, 55);
+            this.chkIgnoreEmptyTranslationsCsv.Name = "chkIgnoreEmptyTranslationsCsv";
+            this.chkIgnoreEmptyTranslationsCsv.Size = new System.Drawing.Size(367, 30);
+            this.chkIgnoreEmptyTranslationsCsv.TabIndex = 7;
+            this.chkIgnoreEmptyTranslationsCsv.Text = "Ignore unconverted strings\r\n(for \"empty\" value of conversion will be used original text)";
+            this.chkIgnoreEmptyTranslationsCsv.UseVisualStyleBackColor = true;
+            // 
+            // 
+            // lblSuffixCsv
+            // 
+            this.lblSuffixCsv.AutoSize = true;
+            this.lblSuffixCsv.Location = new System.Drawing.Point(232, 32);
+            this.lblSuffixCsv.Name = "lblSuffixCsv";
+            this.lblSuffixCsv.Size = new System.Drawing.Size(163, 13);
+            this.lblSuffixCsv.TabIndex = 6;
+            this.lblSuffixCsv.Text = "Extension for conversion file:";
+            // 
+            // edtSuffixCsv
+            // 
+            this.edtSuffixCsv.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::Analyser.Properties.Settings.Default, "CsvTranslationSuffix", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
+            this.edtSuffixCsv.Location = new System.Drawing.Point(401, 29);
+            this.edtSuffixCsv.Name = "edtSuffixCsv";
+            this.edtSuffixCsv.Size = new System.Drawing.Size(100, 20);
+            this.edtSuffixCsv.TabIndex = 5;
+            this.edtSuffixCsv.Text = global::Analyser.Properties.Settings.Default.CsvTranslationSuffix;
+            // 
+            // btnTranslateFromCsv
+            // 
+            this.btnTranslateFromCsv.Location = new System.Drawing.Point(303, 126);
+            this.btnTranslateFromCsv.Name = "btnTranslateFromCsv";
+            this.btnTranslateFromCsv.Size = new System.Drawing.Size(198, 23);
+            this.btnTranslateFromCsv.TabIndex = 4;
+            this.btnTranslateFromCsv.Text = "Make conversion, use CSV";
+            this.btnTranslateFromCsv.UseVisualStyleBackColor = true;
+            this.btnTranslateFromCsv.Click += new System.EventHandler(this.btnTranslateFromCsv_Click);
+            // 
+            // grpCsvDelimiter
+            // 
+            this.grpCsvDelimiter.Controls.Add(this.radComma);
+            this.grpCsvDelimiter.Controls.Add(this.radSemicolon);
+            this.grpCsvDelimiter.Location = new System.Drawing.Point(24, 29);
+            this.grpCsvDelimiter.Name = "grpCsvDelimiter";
+            this.grpCsvDelimiter.Size = new System.Drawing.Size(138, 72);
+            this.grpCsvDelimiter.TabIndex = 3;
+            this.grpCsvDelimiter.TabStop = false;
+            this.grpCsvDelimiter.Text = "Split CSV";
+            // 
+            // radComma
+            // 
+            this.radComma.AutoSize = true;
+            this.radComma.Checked = true;
+            this.radComma.Location = new System.Drawing.Point(6, 19);
+            this.radComma.Name = "radComma";
+            this.radComma.Size = new System.Drawing.Size(79, 17);
+            this.radComma.TabIndex = 1;
+            this.radComma.TabStop = true;
+            this.radComma.Text = "Comma - ,";
+            this.radComma.UseVisualStyleBackColor = true;
+            // 
+            // radSemicolon
+            // 
+            this.radSemicolon.AutoSize = true;
+            this.radSemicolon.Location = new System.Drawing.Point(6, 42);
+            this.radSemicolon.Name = "radSemicolon";
+            this.radSemicolon.Size = new System.Drawing.Size(120, 17);
+            this.radSemicolon.TabIndex = 2;
+            this.radSemicolon.Text = "Semicolon - ;";
+            this.radSemicolon.UseVisualStyleBackColor = true;
+            // 
+            // btnExportCsv
+            // 
+            this.btnExportCsv.Location = new System.Drawing.Point(41, 126);
+            this.btnExportCsv.Name = "btnExportCsv";
+            this.btnExportCsv.Size = new System.Drawing.Size(97, 23);
+            this.btnExportCsv.TabIndex = 0;
+            this.btnExportCsv.Text = "Export to CSV";
+            this.btnExportCsv.UseVisualStyleBackColor = true;
+            this.btnExportCsv.Click += new System.EventHandler(this.btnExportCsv_Click);
+            // 
+            // edtFile
+            // 
+            this.edtFile.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::Analyser.Properties.Settings.Default, "filepath", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
+            this.edtFile.Location = new System.Drawing.Point(409, 10);
+            this.edtFile.Name = "edtFile";
+            this.edtFile.Size = new System.Drawing.Size(176, 20);
+            this.edtFile.TabIndex = 1;
+            this.edtFile.Text = global::Analyser.Properties.Settings.Default.filepath;
+            // 
+            // grpTranslateCsv
+            // 
+            this.grpTranslateCsv.Controls.Add(this.grpCsvDelimiter);
+            this.grpTranslateCsv.Controls.Add(this.btnTranslateFromCsv);
+            this.grpTranslateCsv.Controls.Add(this.chkIgnoreEmptyTranslationsCsv);
+            this.grpTranslateCsv.Controls.Add(this.lblSuffixCsv);
+            this.grpTranslateCsv.Controls.Add(this.btnExportCsv);
+            this.grpTranslateCsv.Controls.Add(this.edtSuffixCsv);
+            this.grpTranslateCsv.Location = new System.Drawing.Point(7, 3);
+            this.grpTranslateCsv.Name = "grpTranslateCsv";
+            this.grpTranslateCsv.Size = new System.Drawing.Size(642, 168);
+            this.grpTranslateCsv.TabIndex = 8;
+            this.grpTranslateCsv.TabStop = false;
+            this.grpTranslateCsv.Text = "Conversion";
+            // 
+            // btnBeautify
+            // 
+            this.btnBeautify.Location = new System.Drawing.Point(56, 279);
+            this.btnBeautify.Name = "btnBeautify";
+            this.btnBeautify.Size = new System.Drawing.Size(129, 23);
+            this.btnBeautify.TabIndex = 9;
+            this.btnBeautify.Text = "Format the code";
+            this.btnBeautify.UseVisualStyleBackColor = true;
+            this.btnBeautify.Click += new System.EventHandler(this.btnBeautify_Click);
+            // 
+            // MainForm
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(666, 630);
+            this.Controls.Add(this.tabControl);
+            this.Controls.Add(this.btnBrowse);
+            this.Controls.Add(this.edtFile);
+            this.Controls.Add(this.label1);
+            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+            this.MaximizeBox = false;
+            this.MinimizeBox = false;
+            this.Name = "MainForm";
+            this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
+            this.Text = "QSP Code Analyzer";
+            this.Load += new System.EventHandler(this.MainForm_Load);
+            this.Shown += new System.EventHandler(this.MainForm_Shown);
+            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing);
+            this.tabControl.ResumeLayout(false);
+            this.tabCheck.ResumeLayout(false);
+            this.tabCheck.PerformLayout();
+            this.tabOptions.ResumeLayout(false);
+            this.tabOptions.PerformLayout();
+            this.tabTranslate.ResumeLayout(false);
+            this.grpCsvDelimiter.ResumeLayout(false);
+            this.grpCsvDelimiter.PerformLayout();
+            this.grpTranslateCsv.ResumeLayout(false);
+            this.grpTranslateCsv.PerformLayout();
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.TextBox edtFile;
+        private System.Windows.Forms.OpenFileDialog dlgOpen;
+        private System.Windows.Forms.Button btnBrowse;
+        private System.Windows.Forms.TextBox txtList1;
+        private System.Windows.Forms.TextBox txtList2;
+        private System.Windows.Forms.TextBox txtList3;
+        private System.Windows.Forms.Button btnTry1;
+        private System.Windows.Forms.Button btnTry2;
+        private System.Windows.Forms.Button btnTry3;
+        private System.Windows.Forms.TextBox txtStatus;
+        private System.Windows.Forms.TabControl tabControl;
+        private System.Windows.Forms.TabPage tabCheck;
+        private System.Windows.Forms.TabPage tabOptions;
+        private System.Windows.Forms.CheckBox chkVariableCalls;
+        private System.Windows.Forms.TextBox txtVariableNames;
+        private System.Windows.Forms.Button btnReset;
+        private System.Windows.Forms.Label lblSortHeader;
+        private System.Windows.Forms.CheckBox chkSortLocations;
+        private System.Windows.Forms.CheckBox chkSortObjects;
+        private System.Windows.Forms.CheckBox chkSortVariables;
+        private System.Windows.Forms.Button btnReload;
+        private System.Windows.Forms.Label lblSystemVariables;
+        private System.Windows.Forms.TextBox txtSystemVariables;
+        private System.Windows.Forms.CheckBox chkAero;
+        private System.Windows.Forms.TextBox txtSystemAeroVars;
+        private System.Windows.Forms.Button btnTry4;
+        private System.Windows.Forms.CheckBox chkActions;
+        private System.Windows.Forms.TabPage tabTranslate;
+        private System.Windows.Forms.GroupBox grpCsvDelimiter;
+        private System.Windows.Forms.RadioButton radComma;
+        private System.Windows.Forms.RadioButton radSemicolon;
+        private System.Windows.Forms.Button btnExportCsv;
+        private System.Windows.Forms.TextBox edtSuffixCsv;
+        private System.Windows.Forms.Button btnTranslateFromCsv;
+        private System.Windows.Forms.Label lblSuffixCsv;
+        private System.Windows.Forms.CheckBox chkIgnoreEmptyTranslationsCsv;
+        private System.Windows.Forms.CheckBox chkCurlyParse;
+        private System.Windows.Forms.GroupBox grpTranslateCsv;
+        private System.Windows.Forms.Button btnBeautify;
+    }
+}
+

+ 556 - 0
QSP/qsp-analyser/QSP_Analyser/MainForm.cs

@@ -0,0 +1,556 @@
+using System;
+using System.Collections.Generic;
+using System.Collections;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Windows.Forms;
+using System.IO;
+
+namespace Analyser
+{
+    public partial class MainForm : Form
+    {
+        //Глобальные переменные II
+        QSPGameCode game;
+
+
+
+        //Глобальные переменные
+        ArrayList ObjectsAdded;
+        ArrayList ObjectsDeleted;
+
+        bool inited = false;
+        string logText = "";
+
+        public MainForm()
+        {
+            InitializeComponent();
+        }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+        private void btnBrowse_Click(object sender, EventArgs e)
+        {
+            //выбираем файл
+            if (dlgOpen.ShowDialog() == DialogResult.OK)
+            {
+                Properties.Settings.Default.filepath = dlgOpen.FileName;
+                txtStatus.Clear();
+                logText = "";
+                ClearMains();
+                ParseFile();
+            }
+        }
+
+        private void PrintErrors()
+        {
+            //Выводим ошибки и ворнинги
+            //Log("Строка #" + Convert.ToString(game.GetErrorLine()) + ": " + game.GetError());
+            Log("No of errors: " + Common.GetErrorsCount() + ", warnings: " + Common.GetWarningsCount());
+            List<Common.QspError> errors = Common.GetErrors();
+            foreach (Common.QspError error in errors)
+            {
+                int err_line = game.GetLocation(error.locationName).GetLine() + error.line;
+                string errorMessage = "Location \"" + error.locationName + "\", Line #" + Convert.ToString(err_line) + " : " + error.text;
+                if (error.isError)
+                {
+                    Log("Error, " + errorMessage);
+                }
+                else
+                {
+                    Log("Warning, " + errorMessage);
+                }
+            }
+            PrintLog();
+        }
+
+        private void ParseFile()
+        {
+            //Устанаваливаем настройки парсера
+            List<string> systemVars = new List<string>(txtSystemVariables.Lines);
+            if (chkAero.Checked)
+                systemVars.AddRange(txtSystemAeroVars.Lines);
+            Common.SetConfig(new List<string>(txtVariableNames.Lines), systemVars, chkCurlyParse.Checked);
+
+            if (CheckForFile(edtFile.Text, true))
+            {
+                Log("Trying to read the file ...");
+                if (game.ParseGame(edtFile.Text))
+                {
+                    Log("The file was read successfully");
+                }
+                PrintErrors();
+                Common.ClearNonGameErrors();
+            }
+            else
+            {
+                Log("File was not read.");
+            }
+            PrintLog();
+        }
+
+        private void btnReset_Click(object sender, EventArgs e)
+        {
+            Analyser.Properties.Settings.Default.Reset();
+        }
+
+        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
+        {
+            Analyser.Properties.Settings.Default.Save();
+        }
+
+        private void MainForm_Load(object sender, EventArgs e)
+        {
+            this.Text += "   v " + System.Windows.Forms.Application.ProductVersion;
+        }
+
+        private void Log(string line)
+        {
+            logText += line + Environment.NewLine;
+        }
+
+        private void PrintLog()
+        {
+            txtStatus.Text = logText;
+        }
+
+        private void ClearMains()
+        {
+            txtList1.Clear();
+            txtList2.Clear();
+            txtList3.Clear();
+        }
+
+        //Выводим список значений в textbox, перед списком выводим заголовок
+        private void PrintArray(Control textbox, ArrayList val, string header)
+        {
+            if (textbox.Text.Length > 0)
+                textbox.Text += Environment.NewLine;
+            if (header.Length > 0)
+                textbox.Text += "[" + header + "]" + Environment.NewLine;
+            string s = String.Join(Environment.NewLine, (string[])val.ToArray(typeof(string)));
+            textbox.Text += s;
+        }
+
+        private ArrayList SubstractArray(ArrayList search_in, ArrayList search_for)
+        {
+            ArrayList res = new ArrayList();
+            string tosearch = Environment.NewLine + String.Join(Environment.NewLine, (string[])search_in.ToArray(typeof(string))) + Environment.NewLine;
+            tosearch = tosearch.ToUpper();
+            foreach (string titem in search_for)
+            {
+                if (!tosearch.Contains(Environment.NewLine + titem.ToUpper() + Environment.NewLine))
+                    res.Add(titem);
+            }
+            return res;
+        }
+
+        private bool CheckForFile(string filename, bool silent)
+        {
+            if (filename != "")
+            {
+                if (File.Exists(filename))
+                {
+                    return true;
+                }
+                else
+                {
+                    if (!silent)
+                        MessageBox.Show("Input file was not found!");
+                }
+            }
+            else
+            {
+                if (!silent)
+                    MessageBox.Show("Select input file!");
+            }
+            return false;
+        }
+
+        private void SortArray(ArrayList arr)
+        {
+            string[] tarr = (string[])arr.ToArray(typeof(string));
+            Array.Sort(tarr);
+            arr.Clear();
+            arr.AddRange(tarr);
+        }
+
+        //************************************************************
+        //************************************************************
+        //************************************************************
+
+//Локации
+        private void btnTry1_Click(object sender, EventArgs e)
+        {
+            ClearMains();
+
+            ArrayList LocationsDefined = new ArrayList();
+            ArrayList LocationsReferenced = new ArrayList();
+            ArrayList LocationsUnDefined = new ArrayList();
+            ArrayList LocationsUnReferenced = new ArrayList();
+
+            foreach (Common.QspLocationLink loc in Common.locationLinks)
+            {
+                if (loc.LocationExists)
+                    LocationsDefined.Add(loc.LocationName);
+                if (loc.LocationCalled)
+                    LocationsReferenced.Add(loc.LocationName);
+                if (!loc.LocationExists)
+                    LocationsUnDefined.Add(loc.LocationName);
+                if (!loc.LocationCalled)
+                    LocationsUnReferenced.Add(loc.LocationName);
+            }
+
+            if (chkSortLocations.Checked)
+            {
+                SortArray(LocationsDefined);
+                SortArray(LocationsReferenced);
+                SortArray(LocationsUnDefined);
+                SortArray(LocationsUnReferenced);
+            }
+
+            Log("We process the names of locations ...");
+            PrintArray(txtList1, LocationsDefined, "Existing locations");
+            Log("Added locations: " + LocationsDefined.Count.ToString());
+
+            Log("We process the reference to locations...");
+            PrintArray(txtList2, LocationsReferenced, "References to locations");
+            Log("Added reference to location: " + LocationsReferenced.Count.ToString());
+
+            Log("We begin to search for incorrect links ...");
+            PrintArray(txtList3, LocationsUnDefined, "Incorrect links");
+            Log("Found incorrect links: " + LocationsUnDefined.Count.ToString());
+
+            Log("We begin to search for lost locations - those for which there are no references ...");
+            PrintArray(txtList3, LocationsUnReferenced, "Lost locations");
+            Log("Found lost locations: " + LocationsUnReferenced.Count.ToString());
+            
+            PrintLog();
+        }
+
+//Переменные
+        private void btnTry2_Click(object sender, EventArgs e)
+        {
+            ClearMains();
+
+            ArrayList TextVars = new ArrayList();
+            ArrayList NumericVars = new ArrayList();
+            ArrayList TextVars_unassigned = new ArrayList();
+            ArrayList NumericVars_unassigned = new ArrayList();
+            ArrayList TextVars_unused = new ArrayList();
+            ArrayList NumericVars_unused = new ArrayList();
+
+            Log("Search for variables ...");
+
+            foreach (Common.QspVariable var in Common.vars)
+            {
+                if (var.IsString)
+                {
+                    if (!var.Assigned)
+                        TextVars_unassigned.Add(var.Name);
+                    if (!var.Used)
+                        TextVars_unused.Add(var.Name);
+                    TextVars.Add(var.Name);
+                }
+                else
+                {
+                    if (!var.Assigned)
+                        NumericVars_unassigned.Add(var.Name);
+                    if (!var.Used)
+                        NumericVars_unused.Add(var.Name);
+                    NumericVars.Add(var.Name);
+                }
+            }
+
+            if (chkSortVariables.Checked)
+            {
+                SortArray(TextVars);
+                SortArray(NumericVars);
+            }
+            PrintArray(txtList1, TextVars, "String variables");
+            PrintArray(txtList2, NumericVars, "Numeric variables");
+
+            Log("Added variables: " + Common.vars.Count.ToString());
+            
+            if (chkSortVariables.Checked)
+                SortArray(TextVars_unassigned);
+            PrintArray(txtList3, TextVars_unassigned, "no init variables:");
+            Log("Found using of uninitialized text variables: " + TextVars_unassigned.Count.ToString());
+            if (chkSortVariables.Checked)
+                SortArray(NumericVars_unassigned);
+            PrintArray(txtList3, NumericVars_unassigned, "");
+            Log("Found using of uninitialized numeric variables: " + NumericVars_unassigned.Count.ToString());
+
+            if (chkSortVariables.Checked)
+                SortArray(TextVars_unused);
+            PrintArray(txtList3, TextVars_unused, "Unused variables:");
+            Log("Found unused string variables: " + TextVars_unused.Count.ToString());
+            if (chkSortVariables.Checked)
+                SortArray(NumericVars_unused);
+            PrintArray(txtList3, NumericVars_unused, "");
+            Log("Found unused numeric variables: " + NumericVars_unused.Count.ToString());
+
+            PrintLog();
+        }
+
+//Предметы
+        private void btnTry3_Click(object sender, EventArgs e)
+        {
+            ClearMains();
+
+            ArrayList ObjectsAdded = new ArrayList();
+            ArrayList ObjectsDeleted = new ArrayList();
+            ArrayList ObjectsUnDefined = new ArrayList();
+            ArrayList ObjectsLost = new ArrayList();
+
+            foreach (Common.QspObj obj in Common.objects)
+            {
+                if (obj.Added)
+                    ObjectsAdded.Add(obj.Name);
+                if (obj.Removed)
+                    ObjectsDeleted.Add(obj.Name);
+                if (!obj.Added)
+                    ObjectsUnDefined.Add(obj.Name);
+                if (!obj.Removed)
+                    ObjectsLost.Add(obj.Name);
+            }
+
+            if (chkSortObjects.Checked)
+            {
+                SortArray(ObjectsAdded);
+                SortArray(ObjectsDeleted);
+                SortArray(ObjectsUnDefined);
+                SortArray(ObjectsLost);
+            }
+
+            Log("Search of items...");
+            PrintArray(txtList1, ObjectsAdded, "Added items");
+            PrintArray(txtList2, ObjectsDeleted, "Remove item");
+            Log("Items adding: " + ObjectsAdded.Count.ToString());
+            Log("Items removing: " + ObjectsDeleted.Count.ToString());
+
+            Log("Search of nonexisting items...");
+            PrintArray(txtList3, ObjectsUnDefined, "Invalid deletion");
+            Log("Found invalid deletions: " + ObjectsUnDefined.Count.ToString());
+
+            Log("Looking for lost items - those that are not deleted during the game ...");
+            PrintArray(txtList3, ObjectsLost, "Lost items");
+            Log("Lost items found: " + ObjectsLost.Count.ToString());
+
+            PrintLog();
+        }
+
+//Действия
+        private void btnTry4_Click(object sender, EventArgs e)
+        {
+            ClearMains();
+
+            ArrayList ActsAdded = new ArrayList();
+            ArrayList ActsDeleted = new ArrayList();
+            ArrayList ActsUnDefined = new ArrayList();
+
+            foreach (Common.QspAct act in Common.acts)
+            {
+                if (act.Added)
+                    ActsAdded.Add(act.Name);
+                if (act.Removed)
+                    ActsDeleted.Add(act.Name);
+                if (!act.Added)
+                    ActsUnDefined.Add(act.Name);
+            }
+
+            if (chkSortObjects.Checked)
+            {
+                SortArray(ActsAdded);
+                SortArray(ActsDeleted);
+                SortArray(ActsUnDefined);
+            }
+
+            Log("Search for actions...");
+            PrintArray(txtList1, ActsAdded, "Add an action");
+            PrintArray(txtList2, ActsDeleted, "Remove an action");
+            Log("Added action: " + ActsAdded.Count.ToString());
+            Log("Removed action: " + ActsDeleted.Count.ToString());
+
+            Log("We begin to search for deletion of nonexistent actions...");
+            PrintArray(txtList3, ActsUnDefined, "Invalid deletion");
+            Log("Invalid deletions found: " + ActsUnDefined.Count.ToString());
+
+            PrintLog();
+        }
+
+        //************************************************************
+        //************************************************************
+        //************************************************************
+
+        private void btnReload_Click(object sender, EventArgs e)
+        {
+            txtStatus.Clear();
+            logText = "";
+            ClearMains();
+            ParseFile();
+        }
+
+        private void setBindingContext(Control ctrl)
+        {
+            ctrl.Visible = true;
+            if (ctrl.HasChildren)
+                foreach (Control child in ctrl.Controls)
+                    setBindingContext(child);
+        }
+
+        private void MainForm_Shown(object sender, EventArgs e)
+        {
+            if (!inited)
+            {
+                setBindingContext(this);
+                btnBrowse.Select();
+
+
+                game = new QSPGameCode();
+                ParseFile();
+
+
+                ObjectsDeleted = new ArrayList();
+                ObjectsAdded = new ArrayList();
+                inited = true;
+            }
+        }
+
+        private void PrintNonGameErrors()
+        {
+            List<Common.QspError> errors = Common.GetErrors();
+            foreach (Common.QspError error in errors)
+            {
+                if (error.isError && (error.line == Common.INVALID_INDEX))
+                {
+                    MessageBox.Show("Error: " + error.text);
+                }
+            }
+            Common.ClearNonGameErrors();
+        }
+
+        private void btnExportCsv_Click(object sender, EventArgs e)
+        {
+            //Делаем экспорт текста в csv
+            string FileName = edtFile.Text;
+            if (CheckForFile(FileName, false))
+            {
+                if (Common.GetErrorsCount() > 0)
+                {
+                    MessageBox.Show("There are syntax errors in the file, export is not possible!");
+                    return;
+                }
+
+                edtFile.Enabled = false;
+                btnBrowse.Enabled = false;
+
+                bool success = false;
+                if (radComma.Checked)
+                {
+                    success = Common.ExportToCsv(FileName, ",");
+                }
+                else
+                {
+                    success = Common.ExportToCsv(FileName, ";");
+                }
+                if (!success)
+                {
+                    PrintNonGameErrors();
+                }
+
+                edtFile.Enabled = true;
+                btnBrowse.Enabled = true;
+            }
+        }
+
+        private void btnTranslateFromCsv_Click(object sender, EventArgs e)
+        {
+            //Делаем перевод текста на основе csv
+            string FileName = edtFile.Text;
+            if (CheckForFile(FileName, false))
+            {
+                if (Common.GetErrorsCount() > 0)
+                {
+                    MessageBox.Show("There are syntax errors in the file, export is not possible!");
+                    return;
+                }
+
+                string CsvFile = Common.GenerateCsvName(FileName);
+                if (!CheckForFile(FileName, true))
+                {
+                    MessageBox.Show("CSV file was not found!");
+                }
+
+                if (edtSuffixCsv.Text.Trim(Common.WhiteSpace).Length == 0)
+                {
+                    MessageBox.Show("Enter an extension of the conversion file.");
+                }
+
+                edtFile.Enabled = false;
+                btnBrowse.Enabled = false;
+
+                bool IgnoreEmptyTranslations = chkIgnoreEmptyTranslationsCsv.Checked;
+                bool success = false;
+                if (radComma.Checked)
+                {
+                    success = Common.TranslateFromCsv(FileName, edtSuffixCsv.Text, IgnoreEmptyTranslations, ",");
+                }
+                else
+                {
+                    success = Common.TranslateFromCsv(FileName, edtSuffixCsv.Text, IgnoreEmptyTranslations, ";");
+                }
+                if (!success)
+                {
+                    PrintNonGameErrors();
+                }
+
+                edtFile.Enabled = true;
+                btnBrowse.Enabled = true;
+            }
+        }
+
+        private void btnBeautify_Click(object sender, EventArgs e)
+        {
+            string FileName = edtFile.Text;
+            if (CheckForFile(FileName, false))
+            {
+                edtFile.Enabled = false;
+                btnBrowse.Enabled = false;
+
+                bool success = false;
+                success = game.Beautify(FileName);
+                if (!success)
+                {
+                    PrintNonGameErrors();
+                }
+
+                edtFile.Enabled = true;
+                btnBrowse.Enabled = true;
+            }
+        }
+    }
+}

+ 123 - 0
QSP/qsp-analyser/QSP_Analyser/MainForm.resx

@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="dlgOpen.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+</root>

+ 20 - 0
QSP/qsp-analyser/QSP_Analyser/Program.cs

@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Windows.Forms;
+
+namespace Analyser
+{
+    static class Program
+    {
+        /// <summary>
+        /// The main entry point for the application.
+        /// </summary>
+        [STAThread]
+        static void Main()
+        {
+            Application.EnableVisualStyles();
+            Application.SetCompatibleTextRenderingDefault(false);
+            Application.Run(new MainForm());
+        }
+    }
+}

+ 36 - 0
QSP/qsp-analyser/QSP_Analyser/Properties/AssemblyInfo.cs

@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("QSP Analyser")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Ghetto")]
+[assembly: AssemblyProduct("QSP Analyser")]
+[assembly: AssemblyCopyright("Copyright © Ghetto 2009")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("50a10fb9-5ab6-4d57-bbfa-ef9a0ef30b18")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.2.24.0")]

+ 63 - 0
QSP/qsp-analyser/QSP_Analyser/Properties/Resources.Designer.cs

@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Analyser.Properties {
+    using System;
+    
+    
+    /// <summary>
+    ///   A strongly-typed resource class, for looking up localized strings, etc.
+    /// </summary>
+    // This class was auto-generated by the StronglyTypedResourceBuilder
+    // class via a tool like ResGen or Visual Studio.
+    // To add or remove a member, edit your .ResX file then rerun ResGen
+    // with the /str option, or rebuild your VS project.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.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() {
+        }
+        
+        /// <summary>
+        ///   Returns the cached ResourceManager instance used by this class.
+        /// </summary>
+        [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("Analyser.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Overrides the current thread's CurrentUICulture property for all
+        ///   resource lookups using this strongly typed resource class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+    }
+}

+ 117 - 0
QSP/qsp-analyser/QSP_Analyser/Properties/Resources.resx

@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>

+ 281 - 0
QSP/qsp-analyser/QSP_Analyser/Properties/Settings.Designer.cs

@@ -0,0 +1,281 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Analyser.Properties {
+    
+    
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.1.0.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+        
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+        
+        public static Settings Default {
+            get {
+                return defaultInstance;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("")]
+        public string filepath {
+            get {
+                return ((string)(this["filepath"]));
+            }
+            set {
+                this["filepath"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("True")]
+        public bool EnableVariableCalls {
+            get {
+                return ((bool)(this["EnableVariableCalls"]));
+            }
+            set {
+                this["EnableVariableCalls"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("$COUNTER\r\n$ONGLOAD\r\n$ONGSAVE\r\n$ONNEWLOC\r\n$ONACTSEL\r\n$ONOBJSEL\r\n$ONOBJADD\r\n$ONOBJD" +
+            "EL\r\n$USERCOM")]
+        public string VariableNames {
+            get {
+                return ((string)(this["VariableNames"]));
+            }
+            set {
+                this["VariableNames"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("True")]
+        public bool EnableSortingLocations {
+            get {
+                return ((bool)(this["EnableSortingLocations"]));
+            }
+            set {
+                this["EnableSortingLocations"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("True")]
+        public bool EnableSortingVariables {
+            get {
+                return ((bool)(this["EnableSortingVariables"]));
+            }
+            set {
+                this["EnableSortingVariables"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("True")]
+        public bool EnableSortingObjects {
+            get {
+                return ((bool)(this["EnableSortingObjects"]));
+            }
+            set {
+                this["EnableSortingObjects"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("FSIZE\r\nFCOLOR\r\nBCOLOR\r\nLCOLOR\r\nUSEHTML\r\n$FNAME\r\n$BACKIMAGE\r\nNOSAVE\r\nDISABLESCROLL" +
+            "\r\nDISABLESUBEX\r\nDEBUG\r\n$COUNTER\r\n$ONGLOAD\r\n$ONGSAVE\r\n$ONNEWLOC\r\n$ONACTSEL\r\n$ONOB" +
+            "JSEL\r\n$ONOBJADD\r\n$ONOBJDEL\r\n$USERCOM\r\nARGS\r\n$ARGS\r\nRESULT\r\n$RESULT")]
+        public string SystemVariables {
+            get {
+                return ((string)(this["SystemVariables"]));
+            }
+            set {
+                this["SystemVariables"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("True")]
+        public bool EnableAero {
+            get {
+                return ((bool)(this["EnableAero"]));
+            }
+            set {
+                this["EnableAero"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute(@"SCROLL_SPEED
+$UP_ARROW_IMAGE
+$DOWN_ARROW_IMAGE
+HIDE_SCROLL_ARROWS
+$STYLESHEET
+DISABLESHADE
+DISABLEAUTOREF
+$NEWLOC_EFFECT
+NEWLOC_EFFECT_TIME
+NEWLOC_EFFECT_SEQ
+$TOPIMAGE
+INTEGRATED_ACTIONS
+MAINDESC_X
+MAINDESC_Y
+MAINDESC_W
+MAINDESC_H
+$MAIN_FORMAT
+$MAINDESC_BACKIMAGE
+STATDESC_X
+STATDESC_Y
+STATDESC_W
+STATDESC_H
+$STAT_FORMAT
+$STATDESC_BACKIMAGE
+ACTIONS_X
+ACTIONS_Y
+ACTIONS_W
+ACTIONS_H
+$ACTION_FORMAT
+$SEL_ACTION_FORMAT
+$ACTIONS_BACKIMAGE
+OBJECTS_X
+OBJECTS_Y
+OBJECTS_W
+OBJECTS_H
+$OBJECT_FORMAT
+$SEL_OBJECT_FORMAT
+$OBJECTS_BACKIMAGE
+USERINPUT_X
+USERINPUT_Y
+USERINPUT_W
+USERINPUT_H
+VIEW_X
+VIEW_Y
+VIEW_W
+VIEW_H
+$VIEW_EFFECT
+VIEW_EFFECT_TIME
+ALWAYS_SHOW_VIEW
+$INPUT_BACKIMAGE
+INPUT_X
+INPUT_Y
+$INPUT_FORMAT
+INPUT_TEXT_X
+INPUT_TEXT_Y
+INPUT_TEXT_W
+INPUT_TEXT_H
+INPUT_BAR_X
+INPUT_BAR_Y
+INPUT_BAR_W
+INPUT_BAR_H
+$INPUT_OK_IMAGE
+INPUT_OK_X
+INPUT_OK_Y
+$INPUT_CANCEL_IMAGE
+INPUT_CANCEL_X
+INPUT_CANCEL_Y
+$INPUT_EFFECT
+INPUT_EFFECT_TIME
+$MSG_BACKIMAGE
+MSG_X
+MSG_Y
+$MSG_FORMAT
+MSG_TEXT_X
+MSG_TEXT_Y
+MSG_TEXT_W
+MSG_TEXT_H
+$MSG_OK_IMAGE
+MSG_OK_X
+MSG_OK_Y
+$MSG_EFFECT
+MSG_EFFECT_TIME
+FIXED_SIZE_MENU
+MENU_PADDING
+MENU_BORDER
+MENU_BORDER_COLOR
+$MENU_BACKIMAGE
+MENU_X
+MENU_Y
+$MENU_FORMAT
+$SEL_MENU_FORMAT
+MENU_LIST_X
+MENU_LIST_Y
+MENU_LIST_W
+MENU_LIST_H
+$MENU_EFFECT
+MENU_EFFECT_TIME")]
+        public string AeroSystemVars {
+            get {
+                return ((string)(this["AeroSystemVars"]));
+            }
+            set {
+                this["AeroSystemVars"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("True")]
+        public bool EnableSortingActions {
+            get {
+                return ((bool)(this["EnableSortingActions"]));
+            }
+            set {
+                this["EnableSortingActions"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("_tr")]
+        public string CsvTranslationSuffix {
+            get {
+                return ((string)(this["CsvTranslationSuffix"]));
+            }
+            set {
+                this["CsvTranslationSuffix"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("True")]
+        public bool IgnoreEmptyTranslationsCsv {
+            get {
+                return ((bool)(this["IgnoreEmptyTranslationsCsv"]));
+            }
+            set {
+                this["IgnoreEmptyTranslationsCsv"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("True")]
+        public bool EnableCurlyParsing {
+            get {
+                return ((bool)(this["EnableCurlyParsing"]));
+            }
+            set {
+                this["EnableCurlyParsing"] = value;
+            }
+        }
+    }
+}

+ 172 - 0
QSP/qsp-analyser/QSP_Analyser/Properties/Settings.settings

@@ -0,0 +1,172 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="Analyser.Properties" GeneratedClassName="Settings">
+  <Profiles />
+  <Settings>
+    <Setting Name="filepath" Type="System.String" Scope="User">
+      <Value Profile="(Default)" />
+    </Setting>
+    <Setting Name="EnableVariableCalls" Type="System.Boolean" Scope="User">
+      <Value Profile="(Default)">True</Value>
+    </Setting>
+    <Setting Name="VariableNames" Type="System.String" Scope="User">
+      <Value Profile="(Default)">$COUNTER
+$ONGLOAD
+$ONGSAVE
+$ONNEWLOC
+$ONACTSEL
+$ONOBJSEL
+$ONOBJADD
+$ONOBJDEL
+$USERCOM</Value>
+    </Setting>
+    <Setting Name="EnableSortingLocations" Type="System.Boolean" Scope="User">
+      <Value Profile="(Default)">True</Value>
+    </Setting>
+    <Setting Name="EnableSortingVariables" Type="System.Boolean" Scope="User">
+      <Value Profile="(Default)">True</Value>
+    </Setting>
+    <Setting Name="EnableSortingObjects" Type="System.Boolean" Scope="User">
+      <Value Profile="(Default)">True</Value>
+    </Setting>
+    <Setting Name="SystemVariables" Type="System.String" Scope="User">
+      <Value Profile="(Default)">FSIZE
+FCOLOR
+BCOLOR
+LCOLOR
+USEHTML
+$FNAME
+$BACKIMAGE
+NOSAVE
+DISABLESCROLL
+DISABLESUBEX
+DEBUG
+$COUNTER
+$ONGLOAD
+$ONGSAVE
+$ONNEWLOC
+$ONACTSEL
+$ONOBJSEL
+$ONOBJADD
+$ONOBJDEL
+$USERCOM
+ARGS
+$ARGS
+RESULT
+$RESULT</Value>
+    </Setting>
+    <Setting Name="EnableAero" Type="System.Boolean" Scope="User">
+      <Value Profile="(Default)">True</Value>
+    </Setting>
+    <Setting Name="AeroSystemVars" Type="System.String" Scope="User">
+      <Value Profile="(Default)">SCROLL_SPEED
+$UP_ARROW_IMAGE
+$DOWN_ARROW_IMAGE
+HIDE_SCROLL_ARROWS
+$STYLESHEET
+DISABLESHADE
+DISABLEAUTOREF
+$NEWLOC_EFFECT
+NEWLOC_EFFECT_TIME
+NEWLOC_EFFECT_SEQ
+$TOPIMAGE
+INTEGRATED_ACTIONS
+MAINDESC_X
+MAINDESC_Y
+MAINDESC_W
+MAINDESC_H
+$MAIN_FORMAT
+$MAINDESC_BACKIMAGE
+STATDESC_X
+STATDESC_Y
+STATDESC_W
+STATDESC_H
+$STAT_FORMAT
+$STATDESC_BACKIMAGE
+ACTIONS_X
+ACTIONS_Y
+ACTIONS_W
+ACTIONS_H
+$ACTION_FORMAT
+$SEL_ACTION_FORMAT
+$ACTIONS_BACKIMAGE
+OBJECTS_X
+OBJECTS_Y
+OBJECTS_W
+OBJECTS_H
+$OBJECT_FORMAT
+$SEL_OBJECT_FORMAT
+$OBJECTS_BACKIMAGE
+USERINPUT_X
+USERINPUT_Y
+USERINPUT_W
+USERINPUT_H
+VIEW_X
+VIEW_Y
+VIEW_W
+VIEW_H
+$VIEW_EFFECT
+VIEW_EFFECT_TIME
+ALWAYS_SHOW_VIEW
+$INPUT_BACKIMAGE
+INPUT_X
+INPUT_Y
+$INPUT_FORMAT
+INPUT_TEXT_X
+INPUT_TEXT_Y
+INPUT_TEXT_W
+INPUT_TEXT_H
+INPUT_BAR_X
+INPUT_BAR_Y
+INPUT_BAR_W
+INPUT_BAR_H
+$INPUT_OK_IMAGE
+INPUT_OK_X
+INPUT_OK_Y
+$INPUT_CANCEL_IMAGE
+INPUT_CANCEL_X
+INPUT_CANCEL_Y
+$INPUT_EFFECT
+INPUT_EFFECT_TIME
+$MSG_BACKIMAGE
+MSG_X
+MSG_Y
+$MSG_FORMAT
+MSG_TEXT_X
+MSG_TEXT_Y
+MSG_TEXT_W
+MSG_TEXT_H
+$MSG_OK_IMAGE
+MSG_OK_X
+MSG_OK_Y
+$MSG_EFFECT
+MSG_EFFECT_TIME
+FIXED_SIZE_MENU
+MENU_PADDING
+MENU_BORDER
+MENU_BORDER_COLOR
+$MENU_BACKIMAGE
+MENU_X
+MENU_Y
+$MENU_FORMAT
+$SEL_MENU_FORMAT
+MENU_LIST_X
+MENU_LIST_Y
+MENU_LIST_W
+MENU_LIST_H
+$MENU_EFFECT
+MENU_EFFECT_TIME</Value>
+    </Setting>
+    <Setting Name="EnableSortingActions" Type="System.Boolean" Scope="User">
+      <Value Profile="(Default)">True</Value>
+    </Setting>
+    <Setting Name="CsvTranslationSuffix" Type="System.String" Scope="User">
+      <Value Profile="(Default)">_tr</Value>
+    </Setting>
+    <Setting Name="IgnoreEmptyTranslationsCsv" Type="System.Boolean" Scope="User">
+      <Value Profile="(Default)">True</Value>
+    </Setting>
+    <Setting Name="EnableCurlyParsing" Type="System.Boolean" Scope="User">
+      <Value Profile="(Default)">True</Value>
+    </Setting>
+  </Settings>
+</SettingsFile>

+ 26 - 0
QSP/qsp-analyser/QSP_Analyser/Properties/app.manifest

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <assemblyIdentity version="1.0.0.0" name="MyApplication.app" />
+  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
+    <security>
+      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
+        <!-- UAC Manifest Options
+            If you want to change the Windows User Account Control level replace the 
+            requestedExecutionLevel node with one of the following.
+
+        <requestedExecutionLevel  level="asInvoker" uiAccess="false" />
+        <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
+        <requestedExecutionLevel  level="highestAvailable" uiAccess="false" />
+
+            If you want to utilize File and Registry Virtualization for backward 
+            compatibility then delete the requestedExecutionLevel node.
+        -->
+        <requestedExecutionLevel level="asInvoker" uiAccess="false" />
+      </requestedPrivileges>
+      <applicationRequestMinimum>
+        <PermissionSet class="System.Security.PermissionSet" version="1" Unrestricted="true" ID="Custom" SameSite="site" />
+        <defaultAssemblyRequest permissionSetReference="Custom" />
+      </applicationRequestMinimum>
+    </security>
+  </trustInfo>
+</asmv1:assembly>

+ 2233 - 0
QSP/qsp-analyser/QSP_Analyser/QSPGameCode.cs

@@ -0,0 +1,2233 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace Analyser
+{
+    public class Location : Common
+    {
+        QSPGameCode m_gamecode;
+        string m_name;
+        int m_line;
+        bool m_start; //Стартовая локация
+        List<string> location_codeline_text;
+        Dictionary<int, int> location_codeline_level;
+
+        int currentLine;
+        bool currentRoot;
+
+        enum ControlBlockType
+        {
+            None,
+            SL_If,
+            SL_Else,
+            SL_Act,
+            ML_If,
+            ML_Else,
+            ML_Act,
+            IfCondition,
+            ElseIfCondition,
+            ActCondition
+        }
+        
+        struct ControlLine
+        {
+            public ControlBlockType controlBlock;
+            public int line;
+        }
+
+        public Location(QSPGameCode code, string name, int line, bool start)
+        {
+            m_gamecode = code;
+            m_name = name;
+            m_line = line;
+            m_start = start;
+            location_codeline_text = null;
+            location_codeline_level = null;
+        }
+
+        public string GetName()
+        {
+            return m_name;
+        }
+
+        public int GetLine()
+        {
+            return m_line;
+        }
+
+        public int GetCodeLinesCount()
+        {
+            return location_codeline_text.Count;
+        }
+
+        public void GetCodeLine(int lineNum, ref string text, ref int level)
+        {
+            //Нужно для утилиты форматирования
+            int realNum = lineNum + 1;
+            text = location_codeline_text[lineNum];
+            if (location_codeline_level.ContainsKey(realNum))
+                level = location_codeline_level[realNum];
+            else
+                level = INVALID_INDEX;
+            return;
+        }
+
+        new void SubmitError(string text, int line)
+        {
+            if (currentRoot)
+                Common.SubmitError(text, line);
+            else
+                Common.SubmitError(text, currentLine);
+        }
+
+        new void SubmitWarning(string text, int line)
+        {
+            if (currentRoot)
+                Common.SubmitWarning(text, line);
+            else
+                Common.SubmitWarning(text, currentLine);
+        }
+
+        bool qspCompileExprPushOpCode(ref int[] opStack, ref int opSp, ref int[] argStack, ref int argSp, int opCode)
+        {
+            if ((opSp == QSP_STACKSIZE - 1) || (argSp == QSP_STACKSIZE - 1))
+            {
+                SubmitError("Quite complicated expression", currentLine);
+                return false;
+            }
+            opStack[++opSp] = opCode;
+            argStack[++argSp] = (opCode < (int)QspFunctionType.First_Function) ? qspOps[opCode].MinArgsCount : 0;
+            return true;
+        }
+
+        bool qspAppendToCompiled(ref int itemsCount)
+        {
+            if (itemsCount == QSP_MAXITEMS)
+            {
+                SubmitError("Quite many arguments in the expression", currentLine);
+                return false;
+            }
+            ++itemsCount;
+            return true;
+        }
+
+        public bool ParseLocation(List<string> code, bool root)
+        {
+            int quote = (int)QuoteType.None;
+            if (root)
+            {
+                currentRoot = true;
+                currentLine = 0;
+                location_codeline_text = new List<string>(code);
+                location_codeline_level = new Dictionary<int, int>();
+            }
+
+            //Склеиваем строки
+            List<int> lineIndexes = new List<int>();
+            List<string> escapedLines = new List<string>();
+            int linesCount = code.Count;
+            int oldLine = 0;
+            int curLine = 0;
+            int curlyLevel = 0;
+            string extraLine = "";
+            while (curLine < linesCount)
+            {
+                string line = code.ToArray()[curLine];
+                int pos = 0;
+                while (pos < line.Length)
+                {
+                    char c = line[pos];
+                    if (c == '\'')
+                    {
+                        //Апостроф
+                        if (quote == (int)QuoteType.None)
+                        {
+                            quote = (int)QuoteType.Single;
+                        }
+                        else if (quote == (int)QuoteType.Single)
+                        {
+                            if ((pos + 1 < line.Length) && (line[pos + 1] == '\''))
+                            {
+                                //Экранированный апостроф
+                                pos++;
+                            }
+                            else
+                            {
+                                quote = (int)QuoteType.None;
+                            }
+                        }
+                    }
+                    else if (c == '"')
+                    {
+                        //Кавычка
+                        if (quote == (int)QuoteType.None)
+                        {
+                            quote = (int)QuoteType.Double;
+                        }
+                        else if (quote == (int)QuoteType.Double)
+                        {
+                            if ((pos + 1 < line.Length) && (line[pos + 1] == '"'))
+                            {
+                                //Экранированная кавычка
+                                pos++;
+                            }
+                            else
+                            {
+                                quote = (int)QuoteType.None;
+                            }
+                        }
+                    }
+                    else if (quote == (int)QuoteType.None)
+                    {
+                        if (c == '{')
+                        {
+                            curlyLevel++;
+                        }
+                        else if (c == '}')
+                        {
+                            if (curlyLevel == 0)
+                            {
+                                SubmitError("Closing curly brace without opening one", oldLine + 1);
+                                return false;
+                            }
+                            curlyLevel--;
+                        }
+                    }
+                    pos++;
+                }
+
+                if ((curlyLevel > 0) || (quote != (int)QuoteType.None) || line.EndsWith(" _"))
+                {
+                    if (line.EndsWith(" _"))
+                        line = line.Substring(0, line.Length - 2);
+                    extraLine += line;
+                    if (curlyLevel > 0)
+                        extraLine += "\n";//Вставляем разделитель для строк, потом по нему "разобьем" строки
+                    if (curLine == linesCount - 1)
+                    {
+                        lineIndexes.Add(oldLine + 1);
+                        string escaped = extraLine + line;
+                        escapedLines.Add(escaped.Trim(WhiteSpace));
+                    }
+                }
+                else
+                {
+                    lineIndexes.Add(oldLine + 1);
+                    string escaped = extraLine + line;
+                    escapedLines.Add(escaped.Trim(WhiteSpace));
+                    oldLine = curLine + 1;
+                    extraLine = "";
+                }
+                curLine++;
+            }
+            //Проверка на незакрытые в конце локации многострочные строки
+            if (quote != (int)QuoteType.None)
+            {
+                SubmitError("Unclosed string", oldLine + 1);
+                return false;
+            }
+            //Проверка на незакрытые в конце локации фигурные скобки
+            if (curlyLevel > 0)
+            {
+                SubmitError("Unclosed curly bracket", oldLine + 1);
+                return false;
+            }
+
+            //TODO
+            // FOR
+            // перечисления asd|12|ddd
+
+            //Разбираем код
+
+            int lineNum = 0;
+            int linePlainNum = 0;
+            string block = "";
+            string quotedText = "";
+            int controlBlock = (int)ControlBlockType.None;
+            Stack<ControlLine> ControlStack = new Stack<ControlLine>();
+            List<string> blockGroup = new List<string>();
+            List<bool> blockInGroupIsText = new List<bool>();
+
+            int groupInnerCounter = 0;
+
+            bool blockStarted = false;
+            bool blockCompleted = false;
+            bool blockGroupStarted = false;
+            bool blockGroupCompleted = false;
+            bool quotedTextCompleted = false;
+
+            string rawText = "";
+            string debugText = "";
+            foreach (string line in escapedLines)
+            {
+                lineNum = lineIndexes[linePlainNum];
+                linePlainNum++;
+
+                int startIndentLevel = 0;
+                int endIndentLevel = 0;
+                if (currentRoot)
+                {
+                    currentLine = lineNum;
+                    //Вычисляем уровень вложенности(для утилиты форматирования кода)
+                    int stackSize = ControlStack.Count;
+                    if (stackSize > 0)
+                        startIndentLevel = stackSize;
+                }
+
+                int pos = 0;
+                int firstSymbolPos = INVALID_INDEX;
+                int blockStartPos = INVALID_INDEX;
+                int lastIfPos = INVALID_INDEX;
+                int lastActPos = INVALID_INDEX;
+                int bracketLevel = 0;
+
+                bool comment = false;
+                bool label = false;
+                string labelText = "";
+                bool singleBlockGroup = false;
+                
+                //Разбор строки
+                while (pos < line.Length)
+                {
+                    bool appendDelimiter = false;
+                    String delimiterToAppend = "";
+                    char c = line[pos];
+                    if ((c.ToString().IndexOfAny(WhiteSpace) != 0) && (firstSymbolPos == INVALID_INDEX))
+                    {
+                        firstSymbolPos = pos;
+                    }
+                    if (c == '\'')
+                    {
+                        //Апостроф
+                        if (quote == (int)QuoteType.None)
+                        {
+                            quote = (int)QuoteType.Single;
+
+                            quotedText = "";
+                            if (blockStarted && !comment)
+                                blockCompleted = true;
+
+                            //для отладки
+                            if (rawText.Length == 0)
+                                rawText += c;
+                            else
+                                rawText += Environment.NewLine + c;
+                        }
+                        else if (quote == (int)QuoteType.Single)
+                        {
+                            if ((pos + 1 < line.Length) && (line[pos + 1] == '\''))
+                            {
+                                //Экранированный апостроф
+                                pos++;
+                                quotedText += c;
+                            }
+                            else
+                            {
+                                quote = (int)QuoteType.None;
+                                if (!comment && !label)
+                                    quotedTextCompleted = true;
+                            }
+
+                            //для отладки
+                            rawText += c;
+                        }
+                        else
+                        {
+                            quotedText += c;
+
+                            //для отладки
+                            rawText += c;
+                        }
+                    }
+                    else if (c == '"')
+                    {
+                        //Кавычка
+                        if (quote == (int)QuoteType.None)
+                        {
+                            quote = (int)QuoteType.Double;
+
+                            quotedText = "";
+                            if (blockStarted && !comment)
+                                blockCompleted = true;
+
+                            //для отладки
+                            if (rawText.Length == 0)
+                                rawText += c;
+                            else
+                                rawText += Environment.NewLine + c;
+                        }
+                        else if (quote == (int)QuoteType.Double)
+                        {
+                            if ((pos + 1 < line.Length) && (line[pos + 1] == '"'))
+                            {
+                                //Экранированная кавычка
+                                pos++;
+                                quotedText += c;
+                            }
+                            else
+                            {
+                                quote = (int)QuoteType.None;
+                                if (!comment && !label)
+                                    quotedTextCompleted = true;
+                            }
+
+                            //для отладки
+                            rawText += c;
+                        }
+                        else
+                        {
+                            quotedText += c;
+
+                            //для отладки
+                            rawText += c;
+                        }
+                    }
+                    else if (comment)
+                    {
+                        //Здесь игнорируем все до самого конца строки, но учитываем переводы строк внутри кавычек и апострофов.
+                    }
+                    else if (quote != (int)QuoteType.None)
+                    {
+                        //Строка текста внутри кавычек или апострофов
+                        quotedText += c;
+
+                        //для отладки
+                        rawText += c;
+                    }
+                    else if (c == '{')
+                    {
+                        if (blockStarted && !comment)
+                            blockCompleted = true;
+
+                        //Записываем содержимое фигурных скобок
+                        string curlyText = "";
+                        curlyLevel = 1;
+                        pos++;
+                        int curlyQuote = (int)QuoteType.None;
+                        while (pos < line.Length)
+                        {
+                            char c2 = line[pos];
+
+                            if (c2 == '\'')
+                            {
+                                //Апостроф
+                                if (curlyQuote == (int)QuoteType.None)
+                                {
+                                    curlyQuote = (int)QuoteType.Single;
+                                }
+                                else if (curlyQuote == (int)QuoteType.Single)
+                                {
+                                    if ((pos + 1 < line.Length) && (line[pos + 1] == '\''))
+                                    {
+                                        //Экранированный апостроф
+                                        curlyText += c2;
+                                        pos++;
+                                        c2 = line[pos];
+                                    }
+                                    else
+                                    {
+                                        curlyQuote = (int)QuoteType.None;
+                                    }
+                                }
+                            }
+                            else if (c2 == '"')
+                            {
+                                //Кавычка
+                                if (curlyQuote == (int)QuoteType.None)
+                                {
+                                    curlyQuote = (int)QuoteType.Double;
+                                }
+                                else if (curlyQuote == (int)QuoteType.Double)
+                                {
+                                    if ((pos + 1 < line.Length) && (line[pos + 1] == '"'))
+                                    {
+                                        //Экранированная кавычка
+                                        curlyText += c2;
+                                        pos++;
+                                        c2 = line[pos];
+                                    }
+                                    else
+                                    {
+                                        curlyQuote = (int)QuoteType.None;
+                                    }
+                                }
+                            }
+                            else if (curlyQuote == (int)QuoteType.None)
+                            {
+                                if (c2 == '{')
+                                {
+                                    curlyLevel++;
+                                }
+                                else if (c2 == '}')
+                                {
+                                    curlyLevel--;
+                                    if (curlyLevel == 0)
+                                        break;
+                                }
+                            }
+                            curlyText += c2;
+                            pos++;
+                        }
+                        if (curlyLevel > 0)
+                        {
+                            SubmitError("Internal error of the analyzer - unclosed curly bracket \"{\"", currentLine);
+                            break;
+                        }
+
+                        if (curlyParsing)
+                        {
+                            //Парсим содержимое фигурных скобок
+                            List<string> curlyLines = new List<string>(curlyText.Split('\n'));
+                            currentRoot = false;
+                            ParseLocation(curlyLines, currentRoot);
+                            currentRoot = root;
+                            //Добавляем пустую "строку в кавычках", чтобы анализатор не ругался на отсутствие параметра
+                            quotedText = "";
+                        }
+                        else
+                        {
+                            quotedText = curlyText;
+                        }
+                        quotedTextCompleted = true;
+                    }
+                    else
+                    {
+                        //Обычные символы
+                        if (label)
+                        {
+                            if (c == '&')
+                            {
+                                if (labelText.Trim(WhiteSpace).Equals(":"))
+                                {
+                                    SubmitError("Empty label", lineNum);
+                                    return false;
+                                }
+                                if (quote != (int)QuoteType.None)
+                                {
+                                    SubmitError("Unclosed string in the label name", lineNum);
+                                    return false;
+                                }
+                                label = false;
+                            }
+                            else
+                            {
+                                labelText += c;
+                            }
+                        }
+                        else if ((c == ':') && ((controlBlock == (int)ControlBlockType.IfCondition) ||
+                                           (controlBlock == (int)ControlBlockType.ElseIfCondition)))
+                        {
+                            //Разбор условия
+                            if (blockStarted)
+                                blockCompleted = true;
+                            blockGroupCompleted = true;
+
+                            //Двоеточие после условия
+                            if ((pos == line.Length - 1))
+                            {
+                                //В конце строки - многострочный IF или ELSEIF
+                                if (firstSymbolPos == lastIfPos)
+                                {
+                                    if (controlBlock == (int)ControlBlockType.IfCondition)
+                                    {
+                                        ControlLine cline;
+                                        cline.line = lineNum;
+                                        cline.controlBlock = ControlBlockType.ML_If;
+                                        ControlStack.Push(cline);
+                                    }
+                                    else
+                                    {
+                                        ControlLine cline = ControlStack.Pop();
+                                        if (cline.controlBlock != ControlBlockType.ML_If)
+                                        {
+                                            SubmitError("ELSEIF without IF", lineNum);
+                                            return false;
+                                        }
+                                        cline.line = lineNum;
+                                        ControlStack.Push(cline);
+                                    }
+                                    controlBlock = (int)ControlBlockType.ML_If;
+                                }
+                                else
+                                {
+                                    if (controlBlock == (int)ControlBlockType.IfCondition)
+                                        SubmitError("Multiline IF should be placed at the beginning of the line", lineNum);
+                                    else
+                                        SubmitError("Multiline ELSEIF should be placed at the beginning of the line", lineNum);
+                                    return false;
+                                }
+                            }
+                            else if (controlBlock == (int)ControlBlockType.IfCondition)
+                            {
+                                //Строка не заканчивается - однострочный IF
+                                if (controlBlock == (int)ControlBlockType.IfCondition)
+                                {
+                                    ControlLine cline;
+                                    cline.line = lineNum;
+                                    cline.controlBlock = ControlBlockType.SL_If;
+                                    ControlStack.Push(cline);
+
+                                    controlBlock = (int)cline.controlBlock;
+                                    groupInnerCounter = 0;
+                                }
+                                else
+                                {
+                                    SubmitError("ELSEIF cannot be used in single line IF", lineNum);
+                                    return false;
+                                }
+                            }
+                            else
+                            {
+                                SubmitError("An operator cannot be placed after colon\":\" in multiline ELSEIF", lineNum);
+                                return false;
+                            }
+                        }
+                        else if ((c == ':') && (controlBlock == (int)ControlBlockType.ActCondition))
+                        {
+                            //Разбор аргумента
+                            if (blockStarted)
+                                blockCompleted = true;
+                            blockGroupCompleted = true;
+
+                            //Двоеточие после ACT
+                            if (pos == line.Length - 1)
+                            {
+                                //В конце строки - многострочный ACT
+                                if (firstSymbolPos == lastActPos)
+                                {
+                                    controlBlock = (int)ControlBlockType.ML_Act;
+                                    ControlLine cline;
+                                    cline.line = lineNum;
+                                    cline.controlBlock = ControlBlockType.ML_Act;
+                                    ControlStack.Push(cline);
+                                }
+                                else
+                                {
+                                    SubmitError("Multiline ACT should be placed at the beginning of the line", lineNum);
+                                    return false;
+                                }
+                            }
+                            else
+                            {
+                                //Строка не заканчивается - однострочный ACT
+                                controlBlock = (int)ControlBlockType.SL_Act;
+                                groupInnerCounter = 0;
+                            }
+                        }
+                        else if (!comment && (c == '!') && !blockGroupStarted && !blockStarted)
+                        {
+                            //Начало комментария
+                            comment = true;
+                        }
+                        else if ((c == ':') && (firstSymbolPos == pos))
+                        {
+                            //Начало метки
+                            label = true;
+                        }
+                        else if (c.ToString().IndexOfAny(Delimiters) == 0)
+                        {
+                            if ((c == '&') && (bracketLevel == 0))
+                            {
+                                if (controlBlock == (int)ControlBlockType.IfCondition)
+                                {
+                                    //В условии IF недопустимо использование "&" вне скобок
+                                    SubmitError("Redundant \"&\": perhaps should be \"AND\"", lineNum);
+                                    return false;
+                                }
+                                else if (controlBlock == (int)ControlBlockType.ActCondition)
+                                {
+                                    //В названии ACT недопустимо использование "&" вне скобок
+                                    SubmitError("Redundant \"&\"", lineNum);
+                                    return false;
+                                }
+                                else
+                                {
+                                    if (blockStarted)
+                                        blockCompleted = true;
+                                    if (blockGroupStarted)
+                                        blockGroupCompleted = true;
+                                    if (blockStarted && !blockGroupStarted)
+                                        singleBlockGroup = true;
+                                }
+                            }
+                            else if (blockStarted && (c == ' ') && StartOfMultiWordOperator(block))
+                            {
+                                //Составной оператор - DEL ACT, DEL OBJ
+                                block += c;
+                            }
+                            else if (blockStarted && (c == ' ') && (qspGetStatCode(block) == (int)QspStatementType.Close) &&
+                                     (line.Length > pos + 3) && line.Substring(pos + 1, 3).Equals("ALL", StringComparison.OrdinalIgnoreCase))
+                            {
+                                //CLOSE ALL
+                                block += c;
+                            }
+                            else if (!blockStarted && (c == '*'))
+                            {
+                                //Возможно, *PL, *P, *NL
+                                blockStarted = true;
+                                blockCompleted = false;
+                                block += c;
+                                blockStartPos = pos;
+                            }
+                            else if (!blockStarted && (c == '['))
+                            {
+                                //Квадратная скобка должна идти вплотную к имени массива
+                                SubmitError("A square bracket has to be placed just behind the name of the array, with no spaces", lineNum);
+                                return false;
+                            }
+                            else
+                            {
+                                //Самостоятельные знаки
+                                if (c == '(')
+                                {
+                                    bracketLevel++;
+                                }
+                                else if (c == ')')
+                                {
+                                    if (bracketLevel == 0)
+                                    {
+                                        SubmitError("Redundant bracket \")\"", lineNum);
+                                        return false;
+                                    }
+                                    bracketLevel--;
+                                }
+                                bool whiteSpace = c.ToString().IndexOfAny(WhiteSpace) == 0;
+
+                                //Особый учет для последовательностей >=, => и т.д.
+                                bool comparer = pos + 1 < line.Length;
+                                String cmp = "";
+                                if (comparer)
+                                {
+                                    cmp = line.Substring(pos, 2);
+                                    comparer = cmp.Equals("<=") || cmp.Equals(">=") || cmp.Equals("=>") || cmp.Equals("=<") || cmp.Equals("<>") ||
+                                               cmp.Equals("+=") || cmp.Equals("-=");
+                                }
+                                if (comparer)
+                                {
+                                    //<= >= => =< <> += -=
+                                    if (blockStarted)
+                                    {
+                                        appendDelimiter = true;
+                                        delimiterToAppend = cmp;
+                                    }
+                                    else
+                                    {
+                                        blockStarted = true;
+                                        blockStartPos = pos;
+                                        block = cmp;
+                                    }
+                                    blockCompleted = true;
+                                    pos++;
+                                }
+                                else if (blockStarted)
+                                {
+                                    blockCompleted = true;
+                                    if (!whiteSpace)
+                                    {
+                                        appendDelimiter = true;
+                                        delimiterToAppend += c;
+                                    }
+                                    else
+                                    {
+                                        //Обрабатываем END IF, END ACT
+                                        int blockCode = qspGetStatCode(block);
+                                        if (blockCode == (int)QspStatementType.End)
+                                        {
+                                            int nextPos = line.LastIndexOfAny(WhiteSpace, blockStartPos + block.Length) + 1;
+                                            if (nextPos < line.Length)
+                                            {
+                                                int delimPos = line.IndexOfAny(Delimiters, nextPos);
+                                                string nextWord = "";
+                                                if (delimPos == INVALID_INDEX)
+                                                    nextWord = line.Substring(nextPos);
+                                                else
+                                                    nextWord = line.Substring(nextPos, delimPos - nextPos);
+                                                int nextCode = qspGetStatCode(nextWord);
+                                                if ((nextCode == (int)QspStatementType.If) || (nextCode == (int)QspStatementType.Act))
+                                                {
+                                                    pos = nextPos + nextWord.Length - 1;
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                                else if (!whiteSpace)
+                                {
+                                    blockStarted = true;
+                                    blockCompleted = true;
+                                    blockStartPos = pos;
+                                    block += c;
+                                }
+                            }
+                        }
+                        else
+                        {
+                            //Просто буквы
+                            if (!blockStarted)
+                            {
+                                blockStarted = true;
+                                blockCompleted = false;
+                                blockStartPos = pos;
+                            }
+                            block += c;
+                        }
+                    }
+                    //Последний символ в строке
+                    if (blockStarted && (pos == line.Length - 1))
+                    {
+                        blockCompleted = true;
+                    }
+
+                    if (blockCompleted || quotedTextCompleted)
+                    {
+                        if (!quotedTextCompleted && (block.Length == 0))
+                        {
+                            SubmitError("Internal error of analyzer! Empty block!", lineNum);
+                            return false;
+                        }
+                        debugText += "[" + block + "] ";
+                        bool skip = false;
+                        int blockCode = qspGetStatCode(block);
+
+                        if (blockCode == (int)QspStatementType.If)
+                        {
+                            controlBlock = (int)ControlBlockType.IfCondition;
+                            debugText += "<IfCondition> ";
+                            lastIfPos = blockStartPos;
+                        }
+                        if (blockCode == (int)QspStatementType.Act)
+                        {
+                            controlBlock = (int)ControlBlockType.ActCondition;
+                            debugText += "<ActCondition> ";
+                            lastActPos = blockStartPos;
+                        }
+                        if (blockCode == (int)QspStatementType.ElseIf)
+                        {
+                            if (controlBlock == (int)ControlBlockType.ML_If)
+                            {
+                                controlBlock = (int)ControlBlockType.ElseIfCondition;
+                                debugText += "<ElseIfCondition> ";
+                                lastIfPos = blockStartPos;
+                            }
+                            else
+                            {
+                                SubmitError("ELSEIF без IF", lineNum);
+                                return false;
+                            }
+                        }
+                        if (blockCode == (int)QspStatementType.Else)
+                        {
+                            if (controlBlock == (int)ControlBlockType.ML_If)
+                            {
+                                if (firstSymbolPos == blockStartPos)
+                                {
+                                    if ((blockStartPos + block.Length == line.Length) || (line.Substring(blockStartPos + block.Length).Trim(WhiteSpace).Equals(":")))
+                                    {
+                                        controlBlock = (int)ControlBlockType.ML_Else;
+                                        
+                                        ControlStack.Pop();
+                                        ControlLine cline;
+                                        cline.controlBlock = ControlBlockType.ML_Else;
+                                        cline.line = lineNum;
+                                        ControlStack.Push(cline);
+                                    }
+                                    else
+                                    {
+                                        SubmitError("An operator cannot be placed after multiline ELSE", lineNum);
+                                        return false;
+                                    }
+                                }
+                                else
+                                {
+                                    SubmitError("Multiline ELSE should be at the beginning of the line", lineNum);
+                                    return false;
+                                }
+                            }
+                            else
+                            {
+                                if (controlBlock == (int)ControlBlockType.SL_Act)
+                                {
+                                    if (groupInnerCounter > 0)
+                                    {
+                                        if ((ControlStack.Peek().controlBlock == ControlBlockType.SL_If) && (ControlStack.Peek().line == lineNum))
+                                        {
+                                            if (blockGroupStarted)
+                                            {
+                                                blockGroupCompleted = true;
+                                            }
+                                        }
+                                        else
+                                        {
+                                            SubmitError("ELSE without IF", lineNum);
+                                            return false;
+                                        }
+                                    }
+                                    else
+                                    {
+                                        SubmitError("Invalid notation of single line ACT", lineNum);
+                                        return false;
+                                    }
+                                }
+                                else if (controlBlock == (int)ControlBlockType.SL_If)
+                                {
+                                    if (blockGroupStarted)
+                                    {
+                                        blockGroupCompleted = true;
+                                    }
+                                    else if (groupInnerCounter == 0)
+                                    {
+                                        SubmitError("After single line IF has to be any operators before ELSE", lineNum);
+                                        return false;
+                                    }
+                                }
+                                else
+                                {
+                                    SubmitError("ELSE without IF", lineNum);
+                                    return false;
+                                }
+                                //Это правильный ELSE
+                                if (blockStartPos + block.Length < line.Length)
+                                {
+                                    string restLine = line.Substring(blockStartPos + block.Length);
+                                    if (restLine.Trim(WhiteSpace).StartsWith(":"))
+                                    {
+                                        pos += restLine.IndexOf(':') + 1;
+                                    }
+                                }
+                                ControlStack.Pop();
+                                controlBlock = (int)ControlBlockType.SL_Else;
+                                groupInnerCounter = 0;
+                            }
+                            skip = true;
+                        }
+                        if (blockCode == (int)QspStatementType.End)
+                        {
+                            if (ControlStack.Count > 0)
+                            {
+                                ControlStack.Pop();
+                                if (ControlStack.Count > 0)
+                                {
+                                    ControlLine cline = ControlStack.Peek();
+                                    controlBlock = (int)cline.controlBlock;
+                                }
+                                else
+                                {
+                                    controlBlock = (int)ControlBlockType.None;
+                                }
+                            }
+                            else
+                            {
+                                SubmitError("Redundant END", lineNum);
+                                return false;
+                            }
+                            skip = true;
+                        }
+                        if (!skip)
+                        {
+                            if (!blockGroupStarted)
+                            {
+                                blockGroupStarted = true;
+                                groupInnerCounter++;
+                                if (singleBlockGroup)
+                                {
+                                    singleBlockGroup = false;
+                                    blockGroupCompleted = true;
+                                }
+                            }
+                            if (quotedTextCompleted)
+                            {
+                                blockGroup.Add(quotedText);
+                                blockInGroupIsText.Add(true);
+                                quotedTextCompleted = false;
+                            }
+                            else
+                            {
+                                if ((blockCode == (int)QspStatementType.Unknown) && (block.Length > 1))
+                                {
+                                    //Обрабатываем попытки "склеить" некоторые последовательности символов
+                                    string first = block.Substring(0, 1);
+                                    if (first.Equals("*"))
+                                    {
+                                        //Если была неудачная попытка прочесть *NL, *P, и т.д., "разделяем" блок на части
+                                        blockGroup.Add(first);
+                                        blockInGroupIsText.Add(false);
+                                        block = block.Substring(1);
+                                    }
+                                }
+                                blockGroup.Add(block);
+                                blockInGroupIsText.Add(false);
+                            }
+                            if (appendDelimiter)
+                            {
+                                blockGroup.Add(delimiterToAppend);
+                                blockInGroupIsText.Add(false);
+                            }
+                            if (blockGroupStarted && (pos == line.Length - 1))
+                            {
+                                blockGroupCompleted = true;
+                            }
+                        }
+                        block = "";
+                        blockCompleted = false;
+                        blockStarted = false;
+                    }
+                    if (blockGroupCompleted)
+                    {
+                        //Разбор аргументов
+                        if (blockGroup.Count == 0)
+                        {
+                            SubmitError("Internal error of the analyzer! Empty block!", lineNum);
+                            return false;
+                        }
+                        if (!CheckBlockGroup(blockGroup, blockInGroupIsText))
+                            return false;
+                        blockGroup.Clear();
+                        blockInGroupIsText.Clear();
+                        blockGroupStarted = false;
+                        blockGroupCompleted = false;
+                    }
+
+                    pos++;
+                }
+                
+                //Строка закончилась
+
+                if (bracketLevel>0)
+                {
+                    SubmitError("Redundant bracket \"(\"", lineNum);
+                    return false;
+                }
+                if (controlBlock == (int)ControlBlockType.IfCondition)
+                {
+                    SubmitError("IF without \":\"", lineNum);
+                    return false;
+                }
+                if (controlBlock == (int)ControlBlockType.ActCondition)
+                {
+                    SubmitError("ACT without \":\"", lineNum);
+                    return false;
+                }
+                if ((controlBlock == (int)ControlBlockType.SL_Act) || (controlBlock == (int)ControlBlockType.SL_If) || (controlBlock == (int)ControlBlockType.SL_Else))
+                {
+                    if (groupInnerCounter > 0)
+                    {
+                        while ((ControlStack.Count > 0) && (ControlStack.Peek().controlBlock == ControlBlockType.SL_If))
+                            ControlStack.Pop();
+                        if (ControlStack.Count > 0)
+                        {
+                            ControlLine cline = ControlStack.Peek();
+                            controlBlock = (int)cline.controlBlock;
+                        }
+                        else
+                        {
+                            controlBlock = (int)ControlBlockType.None;
+                        }
+                    }
+                    else if (controlBlock == (int)ControlBlockType.SL_Act)
+                    {
+                        SubmitError("Invalid notation of single line ACT", lineNum);
+                        return false;
+                    }
+                    else if (controlBlock == (int)ControlBlockType.SL_If)
+                    {
+                        SubmitError("Invalid notation of single line IF", lineNum);
+                        return false;
+                    }
+                    else if (controlBlock == (int)ControlBlockType.SL_Else)
+                    {
+                        SubmitError("In single line IF has to be any operators after ELSE", lineNum);
+                        return false;
+                    }
+                }
+
+                //для отладки
+                if (line.Length > 0)
+                {
+                    debugText += Environment.NewLine;
+                }
+                
+                if (currentRoot)
+                {
+                    //Вычисляем уровень вложенности(для утилиты форматирования кода)
+                    int stackSize = ControlStack.Count;
+                    int level = 0;
+                    if (stackSize > 0)
+                    {
+                        endIndentLevel = stackSize;
+                        ControlLine cline = ControlStack.Peek();
+                        int b = (int)cline.controlBlock;
+                        bool openingLine = cline.line == currentLine;
+                        if (openingLine && ((b == (int)ControlBlockType.ML_Act) || (b == (int)ControlBlockType.ML_If)))
+                        {
+                            level = startIndentLevel;
+                        }
+                        else if (openingLine && (b == (int)ControlBlockType.ML_Else))
+                        {
+                            level = startIndentLevel - 1;
+                        }
+                        else
+                        {
+                            level = endIndentLevel;
+                        }
+                    }
+                    location_codeline_level.Add(currentLine, level);
+                }
+            }
+            //Проверка на незакрытые в конце локации многострочные IF и ACT
+            if (ControlStack.Count > 0)
+            {
+                ControlLine cline = ControlStack.Pop();
+                if ((cline.controlBlock == ControlBlockType.ML_If) || (cline.controlBlock == ControlBlockType.ML_Else))
+                {
+                    SubmitError("Multi line IF without END", cline.line);
+                    return false;
+                }
+                else
+                {
+                    SubmitError("Multi line ACT without END", cline.line);
+                    return false;
+                }
+            }
+
+            AddLocationLink(m_name, true, m_start);
+
+            return true;
+        }
+
+        bool CheckBlockGroup(List<string> blockGroup, List<bool> blockInGroupIsText)
+        {
+            //Разбор аргументов для операторов ACT, IF, прочих операторов и функций.
+            int blockCode = qspGetStatCode(blockGroup.ToArray()[0]);
+            if (blockInGroupIsText[0])
+                blockCode = (int)QspStatementType.Unknown;
+            bool isSetOp = blockCode == (int)QspStatementType.Set;
+            if ((blockCode == (int)QspStatementType.Unknown) || isSetOp)
+            {
+                //Это присваивание?
+                int setpos = FindInTopBracketLevel(blockGroup, blockInGroupIsText, "=");
+                if (setpos == INVALID_INDEX)
+                    setpos = FindInTopBracketLevel(blockGroup, blockInGroupIsText, "+=");
+                if (setpos == INVALID_INDEX)
+                    setpos = FindInTopBracketLevel(blockGroup, blockInGroupIsText, "-=");
+                if (isSetOp && (setpos == INVALID_INDEX))
+                {
+                    SubmitError("Not found the char \"=\"", currentLine);
+                    return false;
+                }
+                if (setpos != INVALID_INDEX)
+                {
+                    //Присваивание
+                    if ((setpos == 0) || (isSetOp && (setpos == 1)))
+                    {
+                        SubmitError("The name of a variable before the character \"=\" is not specified!", currentLine);
+                        return false;
+                    }
+                    int last = blockGroup.Count - 1;
+                    if (setpos==last)
+                    {
+                        SubmitError("It should be a value after char \"=\"", currentLine);
+                        return false;
+                    }
+
+                    //Проверяем левую часть
+                    int start = 0;
+                    if (isSetOp)
+                        start = 1;
+                    int count = setpos - start;
+                    List<string> args = new List<string>();
+                    List<bool> types = new List<bool>();
+                    args = blockGroup.GetRange(start, count);
+                    types = blockInGroupIsText.GetRange(start, count);
+                    if (!CheckLeftAssign(args, types))
+                        return false;
+
+                    string assignedVarName = args[0];
+
+                    //Проверяем правую часть
+                    start = setpos + 1;
+                    count = last - start + 1;
+                    args = blockGroup.GetRange(start, count);
+                    types = blockInGroupIsText.GetRange(start, count);
+                    if (!CheckExpression(args, types))
+                        return false;
+
+                    //Засчитываем присваивание некоторым переменным как обращение к локации
+                    if ((count == 1) && types[0] && ListContainsIgnoreCase(callerVariables, assignedVarName))
+                    {
+                        AddLocationLink(args[0], false, true);
+                    }
+                }
+                else
+                {
+                    //Если оператор неизвестен, пытаемся разобрать выражение
+                    if (!CheckExpression(blockGroup, blockInGroupIsText))
+                        return false;
+
+                    //Разбираем код в ссылках <a href="EXEC:GOTO 'loc1'">
+                    if ((blockGroup.Count == 1) && (blockInGroupIsText[0]))
+                    {
+                        ParseExecInOutputText(blockGroup[0]);
+                    }
+                }
+            }
+            else if ((blockCode == (int)QspStatementType.If) || (blockCode == (int)QspStatementType.ElseIf))
+            {
+                int start = 1;
+                int count = blockGroup.Count - 1;
+                if (count > 0)
+                {
+                    List<string> args = blockGroup.GetRange(start, count);
+                    List<bool> types = blockInGroupIsText.GetRange(start, count);
+                    if (!CheckExpression(args, types))
+                        return false;
+                }
+                else
+                {
+                    if (blockCode == (int)QspStatementType.If)
+                    {
+                        SubmitError("Operator IF without condition", currentLine);
+                    }
+                    else
+                    {
+                        SubmitError("Operator ELSEIF without condition", currentLine);
+                    }
+                    return false;
+                }
+            }
+            else
+            {
+                //Если оператор известен, проверяем его аргументы.
+                int count = blockGroup.Count - 1;
+                List<string> args = new List<string>();
+                List<bool> types = new List<bool>();
+                if (count > 0)
+                {
+                    args = blockGroup.GetRange(1, count);
+                    types = blockInGroupIsText.GetRange(1, count);
+                }
+
+                if (!CheckStatementArgs(blockCode, args, types))
+                    return false;
+            }
+
+            //Проверяем подвыражения вида <<$var>> в любых строках
+            for (int i = 0; i < blockGroup.Count; i++)
+            {
+                if (blockInGroupIsText[i])
+                {
+                    if (!ParseSubExpressions(blockGroup[i]))
+                        return false;
+                }
+            }
+            return true;
+        }
+
+        bool CheckStatementArgs(int code, List<string> argsSrc, List<bool> typesSrc)
+        {
+            int count = argsSrc.Count;
+            List<string> args = new List<string>();
+            List<bool> types = new List<bool>();
+            if (count > 0)
+            {
+                if ((count > 1) && argsSrc.ToArray()[0].Equals("(") && !typesSrc.ToArray()[0] &&
+                    argsSrc.ToArray()[count - 1].Equals(")") && !typesSrc.ToArray()[count - 1])
+                {
+                    //Игнорируем одну пару скобок по краям
+                    args = argsSrc.GetRange(1, count - 2);
+                    types = typesSrc.GetRange(1, count - 2);
+                }
+                else
+                {
+                    args = argsSrc.GetRange(0, count);
+                    types = typesSrc.GetRange(0, count);
+                }
+            }
+            count = args.Count;
+
+            if ((count == 1) && types[0])
+            {
+                //Отмечаем в списке явные ссылки на локации
+                if ((code == (int)QspStatementType.GoSub) || (code == (int)QspStatementType.GoTo) ||
+                 (code == (int)QspStatementType.XGoTo))
+                {
+                    AddLocationLink(args[0], false, true);
+                }
+                //Разбираем код в ссылках <a href="EXEC:GOTO 'loc1'">
+                else if ((code == (int)QspStatementType.P) || (code == (int)QspStatementType.PL) ||
+                    (code == (int)QspStatementType.NL) || (code == (int)QspStatementType.MP) ||
+                    (code == (int)QspStatementType.MPL) || (code == (int)QspStatementType.MNL)) 
+                {
+                    ParseExecInOutputText(args[0]);
+                }
+                //Отмечаем в списке добавленные предметы
+                else if (code == (int)QspStatementType.AddObj)
+                {
+                    AddObj(args[0], true, false);
+                }
+                //Отмечаем в списке удаленные предметы
+                else if (code == (int)QspStatementType.DelObj)
+                {
+                    AddObj(args[0], false, true);
+                }
+                //Отмечаем в списке добавленные действия
+                else if (code == (int)QspStatementType.Act)
+                {
+                    AddAct(args[0], true, false);
+                }
+                //Отмечаем в списке удаленные действия
+                else if (code == (int)QspStatementType.DelAct)
+                {
+                    AddAct(args[0], false, true);
+                }
+            }
+
+            int minArgCount = qspStats[code].MinArgsCount;
+            int maxArgCount = qspStats[code].MaxArgsCount;
+            int argCount = 0;
+            int curIndex = 0;
+            List<string> expr = new List<string>();
+            if (count > 0)
+            {
+                while (true)
+                {
+                    if (argCount == maxArgCount)
+                    {
+                        SubmitError("Too many arguments for the operator", currentLine);
+                        return false;
+                    }
+
+                    int index = FindInTopBracketLevel(args, types, ",", curIndex);
+                    if (index != INVALID_INDEX)
+                    {
+                        if (index > curIndex)
+                        {
+                            if (!CheckExpression(args.GetRange(curIndex, index - curIndex), types.GetRange(curIndex, index - curIndex)))
+                                return false;
+                        }
+                        else
+                        {
+                            SubmitError("Argument can not be empty", currentLine);
+                            return false;
+                        }
+                    }
+                    else
+                    {
+                        if (!CheckExpression(args.GetRange(curIndex, count - curIndex), types.GetRange(curIndex, count - curIndex)))
+                            return false;
+                    }
+                    argCount++;
+                    if (index == INVALID_INDEX)
+                        break;
+                    curIndex = index + 1;
+                    if (curIndex == count)
+                    {
+                        SubmitError("Argument can not be empty", currentLine);
+                        return false;
+                    }
+                }
+            }
+            if (argCount < minArgCount)
+            {
+                SubmitError("The operator requires more arguments", currentLine);
+                return false;
+            }
+            return true;
+        }
+
+        bool CheckExpression(List<string> args, List<bool> types)
+        {
+            //Проверка выражения
+            int[] opStack = new int[QSP_STACKSIZE];
+            int[] argStack = new int[QSP_STACKSIZE];
+
+	        bool waitForOperator = false;
+            int opCode, itemsCount = 0, opSp = -1, argSp = -1;
+	        if (!qspCompileExprPushOpCode(ref opStack, ref opSp, ref argStack, ref argSp, (int)QspFunctionType.Start))
+                return false;
+            int argIndex = 0;
+	        while (argIndex <= args.Count)
+	        {
+                String s = "";
+                if (argIndex < args.Count)
+                    s = args[argIndex];
+		        if (waitForOperator)
+		        {
+			        opCode = qspGetFunctionCode(s, false);
+                    String nextArg = "";
+                    bool nextArgIsString = false;
+                    bool hasNextArg = argIndex + 1 < args.Count;
+                    if (hasNextArg)
+                    {
+                        nextArg = args[argIndex + 1];
+                        nextArgIsString = types[argIndex + 1];
+                    }
+                    if (opCode == (int)QspFunctionType.Unknown || opCode >= (int)QspFunctionType.First_Function)
+			        {
+                        SubmitError("Unknown action in the expression", currentLine);
+				        break;
+			        }
+                    if (((opCode == (int)QspFunctionType.And) || (opCode == (int)QspFunctionType.Or) || (opCode == (int)QspFunctionType.Mod)) &&
+                        !(hasNextArg && (nextArgIsString || nextArg.Equals("(") || (nextArg.IndexOfAny(Delimiters) == INVALID_INDEX)))
+                        )
+			        {
+                        SubmitError("Syntax error", currentLine);
+				        break;
+			        }
+                    bool bError = false;
+			        while (qspOps[opCode].Priority <= qspOps[opStack[opSp]].Priority && qspOps[opStack[opSp]].Priority != 127)
+			        {
+                        if (opStack[opSp] >= (int)QspFunctionType.First_Function) ++argStack[argSp];
+                        if (!qspAppendToCompiled(ref itemsCount))
+                        {
+                            bError = true;
+                            break;
+                        }
+				        if (--opSp < 0 || --argSp < 0)
+				        {
+                            SubmitError("Syntax error", currentLine);
+                            bError = true;
+					        break;
+				        }
+			        }
+                    if (bError) 
+                        break;
+			        switch (opCode)
+			        {
+                    case (int)QspFunctionType.End:
+				        if (opSp > 0)
+				        {
+                            SubmitError("Closing bracket not found", currentLine);
+                            bError = true;
+                            break;
+				        }
+				        return itemsCount > 0;
+                    case (int)QspFunctionType.CloseBracket:
+                        if (opStack[opSp] != (int)QspFunctionType.OpenBracket)
+				        {
+                            SubmitError("Opening bracket not found", currentLine);
+                            bError = true;
+                            break;
+				        }
+				        opCode = opStack[--opSp];
+                        if (opCode >= (int)QspFunctionType.First_Function)
+				        {
+                            if (argStack[argSp] + 1 < qspOps[opCode].MinArgsCount || argStack[argSp] + 1 > qspOps[opCode].MaxArgsCount)
+                            {
+                                SubmitError("Invalid number of arguments", currentLine);
+                                bError = true;
+                            }
+				        }
+				        else
+					        --argSp;
+				        break;
+                    case (int)QspFunctionType.Comma:
+                        if ((opSp > 0) && opStack[opSp - 1] >= (int)QspFunctionType.First_Function)
+				        {
+					        if (++argStack[argSp] > qspOps[opStack[opSp - 1]].MaxArgsCount)
+					        {
+                                SubmitError("Invalid number of arguments", currentLine);
+                                bError = true;
+                                break;
+					        }
+				        }
+				        else
+				        {
+                            if (!qspCompileExprPushOpCode(ref opStack, ref opSp, ref argStack, ref argSp, (int)QspFunctionType.Comma))
+                            {
+                                bError = true;
+                                break;
+                            }
+				        }
+				        waitForOperator = false;
+				        break;
+			        default:
+                        if (!qspCompileExprPushOpCode(ref opStack, ref opSp, ref argStack, ref argSp, opCode))
+                        {
+                            bError = true;
+                            break;
+                        }
+				        waitForOperator = false;
+				        break;
+			        }
+			        if (bError)
+                        break;
+		        }
+		        else
+		        {
+                    if ((argIndex < args.Count) && !types[argIndex] && IsNumber(s))
+			        {
+                        if (opStack[opSp] == (int)QspFunctionType.Minus)
+				        {
+					        --opSp;
+					        --argSp;
+				        }
+				        if (!qspAppendToCompiled(ref itemsCount))
+				            break;
+				        waitForOperator = true;
+			        }
+                    else if ((argIndex < args.Count) && types[argIndex])
+			        {
+				        if (!qspAppendToCompiled(ref itemsCount))
+				            break;
+				        waitForOperator = true;
+			        }
+			        else if (s.Equals("+"))
+			        {
+			        }
+			        else if (s.Equals("-"))
+			        {
+                        if (!qspCompileExprPushOpCode(ref opStack, ref opSp, ref argStack, ref argSp, (int)QspFunctionType.Minus))
+                            break;
+			        }
+			        else if (s.Equals("("))
+			        {
+                        if (!qspCompileExprPushOpCode(ref opStack, ref opSp, ref argStack, ref argSp, (int)QspFunctionType.OpenBracket))
+				            break;
+			        }
+			        else if (s.Equals(")"))
+			        {
+				        opCode = opStack[opSp];
+                        if (opCode != (int)QspFunctionType.OpenBracket)
+				        {
+                            if (opCode >= (int)QspFunctionType.First_Function)
+                                SubmitError("Invalid number of arguments", currentLine);
+					        else
+                                SubmitError("Syntax error", currentLine);
+					        break;
+				        }
+				        opCode = opStack[--opSp];
+                        if (opCode < (int)QspFunctionType.First_Function)
+				        {
+                            SubmitError("Syntax error", currentLine);
+					        break;
+				        }
+				        if (qspOps[opCode].MinArgsCount > 0)
+				        {
+                            SubmitError("Invalid number of arguments", currentLine);
+					        break;
+				        }
+				        if (!qspAppendToCompiled(ref itemsCount))
+				            break;
+				        --opSp;
+				        --argSp;
+				        waitForOperator = true;
+			        }
+			        else if ((argIndex < args.Count) && s.IndexOfAny(Delimiters) != 0)
+			        {
+                        if (s.IndexOfAny(Delimiters) != INVALID_INDEX)
+                        {
+                            SubmitError("Internal error of the analyzer: Invalid characters in the variable name", currentLine);
+                            break;
+                        }
+
+                        opCode = qspGetFunctionCode(s, true);
+                        if (opCode >= (int)QspFunctionType.First_Function)
+				        {
+                            if ((args.Count - argIndex > 1) && (args[argIndex + 1].Equals("(") && !types[argIndex + 1]))
+					        {
+						        if (!qspCompileExprPushOpCode(ref opStack, ref opSp, ref argStack, ref argSp, opCode))
+						            break;
+                                if (!qspCompileExprPushOpCode(ref opStack, ref opSp, ref argStack, ref argSp, (int)QspFunctionType.OpenBracket))
+						            break;
+                                argIndex++;
+						        --argSp;
+					        }
+					        else if (qspOps[opCode].MinArgsCount < 2)
+					        {
+						        if (qspOps[opCode].MinArgsCount > 0)
+						        {
+							        if (!qspCompileExprPushOpCode(ref opStack, ref opSp, ref argStack, ref argSp, opCode))
+							            break;
+						        }
+						        else
+						        {
+				                    if (!qspAppendToCompiled(ref itemsCount))
+				                        break;
+							        waitForOperator = true;
+						        }
+					        }
+					        else
+					        {
+                                SubmitError("Brackets not found", currentLine);
+                                break;
+					        }
+				        }
+				        else
+				        {
+                            int optArgsCount = 0;
+
+                            //Проверяем выражение(индекс массива)
+                            if ((args.Count - argIndex > 1) && (args[argIndex + 1].Equals("[") && !types[argIndex + 1]))
+                            {
+                                int optIndex = argIndex + 2;
+                                int level = 1;
+                                bool bFound = false;
+                                while (optIndex < args.Count)
+                                {
+                                    if (args[optIndex].Equals("[") && !types[optIndex])
+                                    {
+                                        level++;
+                                    }
+                                    else if (args[optIndex].Equals("]") && !types[optIndex])
+                                    {
+                                        level--;
+                                        if (level == 0)
+                                        {
+                                            bFound = true;
+                                            break;
+                                        }
+                                    }
+                                    optIndex++;
+                                }
+                                if (level > 0)
+                                {
+                                    SubmitError("Unclosed parenthesis \"[\"", currentLine);
+                                    break;
+                                }
+                                if (bFound)
+                                    optArgsCount = optIndex - argIndex;
+                            }
+                            List<string> subArgs = args.GetRange(argIndex, optArgsCount + 1);
+                            List<bool> subTypes = types.GetRange(argIndex, optArgsCount + 1);
+
+                            if (!CheckVariable(subArgs, subTypes, false))
+                                break;
+                            
+                            argIndex += optArgsCount;
+
+				            if (!qspAppendToCompiled(ref itemsCount))
+				                break;
+					        waitForOperator = true;
+				        }
+			        }
+			        else
+			        {
+                        if (opStack[opSp] >= (int)QspFunctionType.First_Function)
+                            SubmitError("Invalid number of arguments", currentLine);
+                        else
+                            SubmitError("Syntax error", currentLine);
+                        break;
+			        }
+		        }
+                argIndex++;
+	        }
+            return false;
+        }
+
+        bool CheckVariable(List<string> args, List<bool> types, bool assignment)
+        {
+            //Проверка имени переменной
+            if ((args.Count == 0) || (args[0].Length == 0) || types[0])
+            {
+                SubmitError("Internal error of the analyzer: empty name of variable!", currentLine);
+                return false;
+            }
+
+            string name = args[0];
+            int code1 = qspGetStatCode(name);
+            int code2 = qspGetFunctionCode(name, true);
+            if ((code1 != (int)QspStatementType.Unknown) || (code2 != (int)QspFunctionType.Unknown))
+            {
+                SubmitError("QSP Keyword \"" + name + "\" cannot be used as a variable name", currentLine);
+                return false;
+            }
+
+            //Проверяем имя переменной на валидность
+            //В имени переменной разрешены все символы, кроме DELIMS и цифры в начале имени
+            //Перед именем переменной может находиться префикс "$"
+            string checkName = name;
+            if (checkName.StartsWith("$"))
+                checkName = checkName.Substring(1);
+            // $ =
+            if (checkName.Length == 0)
+            {
+                SubmitError("Invalid variable name \"" + name + "\"", currentLine);
+                return false;
+            }
+            // 1asd =
+            if (checkName.Substring(0, 1).IndexOfAny(Digits) != INVALID_INDEX)
+            {
+                SubmitError("Variable name \"" + name + "\" cannot start with a digit", currentLine);
+                return false;
+            }
+            // /asd =
+            if (checkName.IndexOfAny(Delimiters) != INVALID_INDEX)
+            {
+                SubmitError("Invalid symbols in the name of the variable \"" + name + "\"", currentLine);
+                return false;
+            }
+
+            //Проверяем переменную на "смешанные раскладки"
+            if ((checkName.IndexOfAny(LatinLetters) != INVALID_INDEX) && (checkName.IndexOfAny(RussianLetters) != INVALID_INDEX))
+            {
+                SubmitWarning("English and Russian symbols are used simultaneously in the name of varible \"" + name + "\" , possibly a typo", currentLine);
+            }
+
+            //Проверяем выражение(индекс массива)
+            if (args.Count > 1)
+            {
+                if (args.Count > 2 && args[1].Equals("[") && !types[1] &&
+                                        args[args.Count - 1].Equals("]") && !types[args.Count - 1])
+                {
+                    int start = 2;
+                    int count = args.Count - 3;
+                    if (count > 0)
+                    {
+                        List<string> argsCut = args.GetRange(start, count);
+                        List<bool> typesCut = types.GetRange(start, count);
+                        if (!CheckExpression(argsCut, typesCut))
+                            return false;
+                    }
+                }
+                else
+                {
+                    SubmitError("Invalid expression", currentLine);
+                    return false;
+                }
+            }
+
+            //Сохраняем имя переменной в глобальном списке
+            if (!assignment)
+            {
+                bool usedBySystem = ListContainsIgnoreCase(systemVariables, name);
+                AddVar(name, usedBySystem, true);
+            }
+
+            return true;
+        }
+        
+        bool CheckLeftAssign(List<string> args, List<bool> types)
+        {
+            //Проверка имени переменной(слева от знака "=" в операции присваивания)
+            if ((args.Count == 0) || (args[0].Length == 0) || types[0])
+            {
+                //Текстовая строка
+                SubmitError("Name of the variable should be before char \"=\" in the assignment operation", currentLine);
+                return false;
+            }
+
+            if (!CheckVariable(args, types, true))
+                return false;
+
+            //Сохраняем имя переменной в глобальном списке
+            bool usedBySystem = ListContainsIgnoreCase(systemVariables, args[0]);
+            AddVar(args[0], true, usedBySystem);
+
+            return true;
+        }
+
+        int FindInTopBracketLevel(List<string> args, List<bool> types, string what)
+        {
+            return FindInTopBracketLevel(args, types, what, 0);
+        }
+
+        int FindInTopBracketLevel(List<string> args, List<bool> types, string what, int startIndex)
+        {
+            //Ищем знак "=" или запятую вне скобок
+            int bracketLevel = 0;
+            for (int i = startIndex; i < args.Count; i++)
+            {
+                if (types[i])
+                    continue;
+                string block = args[i];
+                if (block.Equals("("))
+                {
+                    bracketLevel++;
+                }
+                else if (block.Equals(")"))
+                {
+                    bracketLevel--;
+                }
+                else if (block.Equals(what) && (bracketLevel == 0))
+                {
+                    return i;
+                }
+            }
+            return INVALID_INDEX;
+        }
+
+        void ParseExecInOutputText(string text)
+        {
+            //Разбираем код в ссылках <a href="EXEC:GOTO 'loc1'">
+            int pos = 0;
+
+            //Строим "карту" подвыражений.
+            //Если подвыражения в строке содержат ошибки, то разбирать теги нет смысла.
+            List<int> subExpMap = new List<int>();
+            if (!ParseSubExpressions(text, ref subExpMap))
+                return;
+            int subExpSkipped = 0;
+
+            while (pos < text.Length)
+            {
+                pos = text.IndexOf('<', pos);
+                if (pos == INVALID_INDEX)
+                    break;
+
+                if (subExpMap.Count / 2 > subExpSkipped)
+                {
+                    int subExpStartPos = subExpMap[subExpSkipped * 2];
+                    int subExpEndPos = subExpMap[subExpSkipped * 2 + 1];
+                    if (subExpStartPos == pos)
+                    {
+                        //Пропускаем подвыражения вне тегов
+                        subExpSkipped++;
+                        pos = subExpEndPos + 1;
+                        continue;
+                    }
+                }
+
+                //Разбираем содержимое угловых скобок
+                //Внутри HTML-тега кавычки экранируются не через дублирование, как в QSP, а через "\",
+                //причем экранирование требуется только внутри окавыченной строки.
+                List<string> blockGroup = new List<string>();
+                List<bool> blockInGroupIsText = new List<bool>();
+                int firstBlockPosition = INVALID_INDEX;
+
+                string quotedText = "";
+                string block = "";
+                bool tagClosed = false;
+                bool quotedTextCompleted = false;
+                bool blockCompleted = false;
+                pos++;
+                int startPos = pos;
+                if ((pos < text.Length) && (text[pos] == '/'))
+                    startPos++;
+                int tagQuote = (int)QuoteType.None;
+                while (!tagClosed && (pos < text.Length))
+                {
+                    if (subExpMap.Count / 2 > subExpSkipped)
+                    {
+                        int subExpStartPos = subExpMap[subExpSkipped * 2];
+                        int subExpEndPos = subExpMap[subExpSkipped * 2 + 1];
+                        if (subExpStartPos == pos)
+                        {
+                            //Пропускаем подвыражения вне тегов
+                            subExpSkipped++;
+                            string subExpText = text.Substring(pos, subExpEndPos - pos + 1);
+                            if (tagQuote == (int)QuoteType.None)
+                                block += subExpText;
+                            else
+                                quotedText += subExpText;
+                            pos = subExpEndPos + 1;
+                            continue;
+                        }
+                    }
+
+                    char c2 = text[pos];
+
+                    if (tagQuote != (int)QuoteType.None)
+                    {
+                        //Апостроф либо кавычка
+                        if (((tagQuote == (int)QuoteType.Single) && (c2 == '\'')) ||
+                            ((tagQuote == (int)QuoteType.Double) && (c2 == '"')))
+                        {
+                            if ((pos - 1 > 0) && (text[pos - 1] == '\\'))
+                            {
+                                //Экранированный апостроф либо кавычка
+                                if (!quotedTextCompleted)
+                                    quotedText = quotedText.Substring(0, quotedText.Length - 1) + c2;
+                            }
+                            else
+                            {
+                                tagQuote = (int)QuoteType.None;
+                                quotedTextCompleted = true;
+                            }
+                        }
+                        else if (!quotedTextCompleted)
+                        {
+                            quotedText += c2;
+                        }
+                    }
+                    else if (c2 == '>')
+                    {
+                        tagClosed = true;
+                    }
+                    else if ((block.Length == 0) && (c2 == '\''))
+                    {
+                        tagQuote = (int)QuoteType.Single;
+                    }
+                    else if ((block.Length == 0) && (c2 == '"'))
+                    {
+                        tagQuote = (int)QuoteType.Double;
+                    }
+                    else if (c2.ToString().IndexOfAny(WhiteSpace) == 0)
+                    {
+                        if (block.Length > 0)
+                        {
+                            blockCompleted = true;
+                        }
+                    }
+                    else if (c2 == '=')
+                    {
+                        if (block.Length > 0)
+                        {
+                            blockGroup.Add(block);
+                            blockInGroupIsText.Add(false);
+                        }
+                        block = "=";
+                        blockCompleted = true;
+                    }
+                    else
+                    {
+                        if (firstBlockPosition == INVALID_INDEX)
+                        {
+                            firstBlockPosition = pos - startPos;
+                        }
+                        block += c2;
+                    }
+                    if (tagClosed)
+                    {
+                        if (block.Length > 0)
+                            blockCompleted = true;
+                    }
+
+                    if (blockCompleted)
+                    {
+                        blockGroup.Add(block);
+                        blockInGroupIsText.Add(false);
+                        blockCompleted = false;
+                        block = "";
+                    }
+                    if (quotedTextCompleted)
+                    {
+                        blockGroup.Add(quotedText);
+                        blockInGroupIsText.Add(true);
+                        quotedTextCompleted = false;
+                        quotedText = "";
+                    }
+
+                    pos++;
+                }
+                
+                if (tagQuote == (int)QuoteType.Single)
+                {
+                    SubmitWarning("Unclosed apostrophe inside the tag", currentLine);
+                    break;
+                }
+                else if (tagQuote == (int)QuoteType.Double)
+                {
+                    SubmitWarning("Unclosed quote inside the tag", currentLine);
+                    break;
+                }
+                if (!tagClosed)
+                {
+                    SubmitWarning("Unclosed tag",currentLine);
+                    break;
+                }
+                if (firstBlockPosition > 0)
+                {
+                    SubmitWarning("The name of the tag should follow immediately after the opening angle bracket, without spaces", currentLine);
+                    break;
+                }
+
+
+                //Ищем HREF в атрибутах тега A
+                int hrefIndex = INVALID_INDEX;
+                if ((blockGroup.Count > 3) && (blockGroup[0].Equals("A", StringComparison.OrdinalIgnoreCase)) && !blockInGroupIsText[0])
+                {
+                    for (int i = 1; i + 2 < blockGroup.Count; i++)
+                    {
+                        if (blockGroup[i].Equals("HREF", StringComparison.OrdinalIgnoreCase) && !blockInGroupIsText[i] &&
+                            blockGroup[i + 1].Equals("=") && !blockInGroupIsText[i + 1])
+                        {
+                            hrefIndex = i + 2;
+                        }
+                    }
+                }
+
+                if (hrefIndex != INVALID_INDEX)
+                {
+                    string hrefText = blockGroup[hrefIndex];
+                    int execKeywordLength = "EXEC:".Length;
+                    if (hrefText.StartsWith("EXEC:", StringComparison.OrdinalIgnoreCase) && (hrefText.Length > execKeywordLength))
+                    {
+                        string execText = hrefText.Substring(execKeywordLength);
+                        List<int> subExpMapExec = new List<int>();
+                        ParseSubExpressions(execText, ref subExpMapExec);
+                        if (subExpMapExec.Count == 0)
+                        {
+                            //В EXEC не разбираем код с подвыражениями, это невозможно без интерпретации
+                            List<string> tagLines = new List<string>(execText.Split('\n'));
+                            bool wasRoot = currentRoot;
+                            currentRoot = false;
+                            ParseLocation(tagLines, currentRoot);
+                            currentRoot = wasRoot;
+                        }
+                    }
+                }
+            }
+        }
+
+        bool ParseSubExpressions(string text)
+        {
+            List<int> dummy = null;
+            return ParseSubExpressions(text, ref dummy);
+        }
+        bool ParseSubExpressions(string text, ref List<int> subExpMap)
+        {
+            bool quiet = subExpMap != null;
+            //Разбираем подвыражения - <<$var>>
+            if (quiet)
+                subExpMap.Clear();
+            int pos = 0;
+            bool valid = true;
+            while (valid && pos < text.Length)
+            {
+                pos = text.IndexOf("<<", pos);
+                if (pos == INVALID_INDEX)
+                    break;
+                if (quiet)
+                    subExpMap.Add(pos);
+                //Разбираем содержимое двойных угловых скобок
+                string subText = "";
+                bool subClosed = false;
+                pos += 2;
+                int subQuote = (int)QuoteType.None;
+                int curlyLevel = 0;
+                while (pos < text.Length)
+                {
+                    char c2 = text[pos];
+
+                    if (subQuote == (int)QuoteType.None)
+                    {
+                        if ((c2 == '>') && (pos + 1 < text.Length) && (text[pos + 1] == '>') && (curlyLevel == 0))
+                        {
+                            subClosed = true;
+                            break;
+                        }
+                        else if (c2 == '\'')
+                        {
+                            subQuote = (int)QuoteType.Single;
+                        }
+                        else if (c2 == '"')
+                        {
+                            subQuote = (int)QuoteType.Double;
+                        }
+                        else if (c2 == '{')
+                        {
+                            curlyLevel++;
+                        }
+                        else if (c2 == '}')
+                        {
+                            curlyLevel--;
+                        }
+                    }
+                    else if (((subQuote == (int)QuoteType.Single) && (c2 == '\'')) ||
+                             ((subQuote == (int)QuoteType.Double) && (c2 == '"')))
+
+                    {
+                        //Апостроф или кавычка
+                        if ((pos + 1 < text.Length) && (
+                            ((subQuote == (int)QuoteType.Single) && (text[pos + 1] == '\'')) ||
+                            ((subQuote == (int)QuoteType.Double) && (text[pos + 1] == '"'))))
+                        {
+                            //Экранированный апостроф либо кавычка
+                        }
+                        else
+                        {
+                            subQuote = (int)QuoteType.None;
+                        }
+                    }
+                    subText += c2;
+                    pos++;
+                }
+                if (quiet)
+                {
+                    if (subClosed)
+                        subExpMap.Add(pos + 1);
+                    else
+                        subExpMap.Add(pos - 1);
+                }
+                if (subQuote == (int)QuoteType.Single)
+                {
+                    if (!quiet)
+                        SubmitError("Unclosed apostrophe in a subexpression", currentLine);
+                    valid = false;
+                    break;
+                }
+                else if (subQuote == (int)QuoteType.Double)
+                {
+                    if (!quiet)
+                        SubmitError("Unclosed quote in a subexpression", currentLine);
+                    valid = false;
+                    break;
+                }
+                else if (curlyLevel != 0)
+                {
+                    if (!quiet)
+                        SubmitError("Unclosed curly bracket in a subexpression", currentLine);
+                    valid = false;
+                    break;
+                }
+                if (!subClosed)
+                {
+                    if (!quiet)
+                        SubmitError("Unclosed subexpression", currentLine);
+                    valid = false;
+                    break;
+                }
+                if (subText.Trim(WhiteSpace).Length == 0)
+                {
+                    if (!quiet)
+                        SubmitError("Empty subexpression", currentLine);
+                    valid = false;
+                    break;
+                }
+
+                if (!quiet)
+                {
+                    //Парсим подвыражение как исполняемый код.
+                    //Для того, чтобы строка считалась именно выражением, добавляем ''+ в начало
+                    subText = "''+" + subText;
+                    List<string> subLines = new List<string>(subText.Split('\n'));
+                    bool wasRoot = currentRoot;
+                    currentRoot = false;
+                    valid = ParseLocation(subLines, currentRoot);
+                    currentRoot = wasRoot;
+                }
+            }
+            return valid;
+        }
+    }
+
+    public class QSPGameCode : Common
+    {
+        Hashtable m_LocationsByName;
+        List<Location> m_LocationsByOrder;
+        Location m_lastLocation;
+
+        public QSPGameCode()
+        {
+            m_LocationsByName = new Hashtable();
+            m_LocationsByOrder = new List<Location>();
+            m_lastLocation = null;
+        }
+
+        public bool ParseGame(string fileName)
+        {
+            m_LocationsByName.Clear();
+            m_LocationsByOrder.Clear();
+            ClearErrors();
+            m_lastLocation = null;
+            currentLocation = "";
+
+            vars = new List<QspVariable>();
+            locationLinks = new List<QspLocationLink>();
+            objects = new List<QspObj>();
+            acts = new List<QspAct>();
+
+            StreamReader fi = null;
+            if (!OpenStreamForReading(ref fi, fileName))
+            {
+                return false;
+            }
+            string s;
+            int line_counter = 0;
+            List<string> locationCode = new List<string>();
+            bool inside = false;
+            while ((s = fi.ReadLine()) != null)
+            {
+                line_counter++;
+                string trimmed = s.Trim(WhiteSpace);
+                if ((trimmed.Length > 0) && (trimmed[0] == '#'))
+                {
+                    //имя локации
+                    string locName = trimmed.Substring(1).Trim(WhiteSpace);
+                    if (!AddLocation(locName, line_counter))
+                    {
+                        fi.Close();
+                        return false;
+                    }
+                    currentLocation = locName;
+                    inside = true;
+                }
+                else if ((trimmed.Length > 38) && trimmed.StartsWith("--- ") && trimmed.EndsWith(" ---------------------------------"))
+                {
+                    inside = false;
+                    Location lastLoc = GetLastLocation();
+                    if (lastLoc != null)
+                    {
+                        lastLoc.ParseLocation(locationCode, true);
+                        locationCode.Clear();
+                        currentLocation = "";
+                    }
+                }
+                else
+                {
+                    if (inside && GetLastLocation() != null)
+                        locationCode.Add(s);
+                }
+            }
+            fi.Close();
+            return true;
+        }
+
+        public bool AddLocation(string name, int line)
+        {
+            if (name.Length <= 0)
+            {
+                SubmitError("Empty name of location", line);
+                return false;
+            }
+            if (m_LocationsByName.ContainsKey(name))
+            {
+                SubmitError("Location named " + name + " exist already", line);
+                return false;
+            }
+            Location newLoc = new Location(this, name, line, m_LocationsByOrder.Count == 0);
+            m_LocationsByName.Add(name, newLoc);
+            m_LocationsByOrder.Add(newLoc);
+            m_lastLocation = newLoc;
+            return true;
+        }
+
+        public Location GetLastLocation()
+        {
+            return m_lastLocation;
+        }
+
+        public Hashtable GetLocationsByName()
+        {
+            return m_LocationsByName;
+        }
+
+        public Location GetLocation(string locationName)
+        {
+            Location loc = (Location)m_LocationsByName[locationName];
+            return loc;
+        }
+
+        public bool Beautify(string fileName)
+        {
+            //Причесываем код - добавляем пробелов
+            StreamWriter fo = null;
+            if (!OpenStreamForWriting(ref fo, fileName))
+                return false;
+
+            for (int i = 0; i < m_LocationsByOrder.Count; i++)
+            {
+                Location loc = (Location)m_LocationsByOrder[i];
+                fo.WriteLine("# " + loc.GetName());
+                for (int j = 0; j < loc.GetCodeLinesCount(); j++)
+                {
+                    string text = "";
+                    int level = INVALID_INDEX;
+                    loc.GetCodeLine(j, ref text, ref level);
+                    if (level != INVALID_INDEX)
+                    {
+                        text = new string(' ', level * 4) + text.TrimStart(WhiteSpace);
+                    }
+                    fo.WriteLine(text);
+                }
+                fo.WriteLine("--- " + loc.GetName() + " ---------------------------------");
+                fo.WriteLine();
+            }
+            fo.Close();
+            return true;
+        }
+    }
+}

+ 141 - 0
QSP/qsp-analyser/QSP_Analyser/QSP_Analyser.csproj

@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{0EB1C8F9-E5A2-4C13-8ED2-C1897332F197}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Analyser</RootNamespace>
+    <AssemblyName>QSP_Analyser</AssemblyName>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <StartupObject>Analyser.Program</StartupObject>
+    <ManifestCertificateThumbprint>4BF816F664C87F6B56DA3F2582A6A8BDC305FB9C</ManifestCertificateThumbprint>
+    <ManifestKeyFile>QSP_Analyser_TemporaryKey.pfx</ManifestKeyFile>
+    <GenerateManifests>true</GenerateManifests>
+    <TargetZone>LocalIntranet</TargetZone>
+    <ApplicationManifest>Properties\app.manifest</ApplicationManifest>
+    <SignManifests>false</SignManifests>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <PublishUrl>C:\Site\QSP\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <PublishWizardCompleted>true</PublishWizardCompleted>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Deployment" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Common.cs" />
+    <Compile Include="MainForm.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="MainForm.Designer.cs">
+      <DependentUpon>MainForm.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <EmbeddedResource Include="MainForm.resx">
+      <DependentUpon>MainForm.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Resources.resx</DependentUpon>
+      <DesignTime>True</DesignTime>
+    </Compile>
+    <None Include="app.config" />
+    <None Include="Properties\app.manifest" />
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Settings.settings</DependentUpon>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+    </Compile>
+    <Compile Include="QSPGameCode.cs" />
+    <Compile Include="Settings.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>Профиль клиента .NET Framework</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 2.0 %28x86%29</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.0 %28x86%29</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>

+ 16 - 0
QSP/qsp-analyser/QSP_Analyser/QSP_Analyser.csproj.user

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <PublishUrlHistory />
+    <InstallUrlHistory />
+    <SupportUrlHistory />
+    <UpdateUrlHistory />
+    <BootstrapperUrlHistory />
+    <ErrorReportUrlHistory />
+    <FallbackCulture>en-US</FallbackCulture>
+    <VerifyUploadedFiles>false</VerifyUploadedFiles>
+  </PropertyGroup>
+  <PropertyGroup>
+    <EnableSecurityDebugging>false</EnableSecurityDebugging>
+  </PropertyGroup>
+</Project>

+ 28 - 0
QSP/qsp-analyser/QSP_Analyser/Settings.cs

@@ -0,0 +1,28 @@
+namespace Analyser.Properties {
+    
+    
+    // This class allows you to handle specific events on the settings class:
+    //  The SettingChanging event is raised before a setting's value is changed.
+    //  The PropertyChanged event is raised after a setting's value is changed.
+    //  The SettingsLoaded event is raised after the setting values are loaded.
+    //  The SettingsSaving event is raised before the setting values are saved.
+    internal sealed partial class Settings {
+        
+        public Settings() {
+            // // To add event handlers for saving and changing settings, uncomment the lines below:
+            //
+            // this.SettingChanging += this.SettingChangingEventHandler;
+            //
+            // this.SettingsSaving += this.SettingsSavingEventHandler;
+            //
+        }
+        
+        private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) {
+            // Add code to handle the SettingChangingEvent event here.
+        }
+        
+        private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) {
+            // Add code to handle the SettingsSaving event here.
+        }
+    }
+}

+ 178 - 0
QSP/qsp-analyser/QSP_Analyser/app.config

@@ -0,0 +1,178 @@
+<?xml version="1.0"?>
+<configuration>
+	<configSections>
+		<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+			<section name="Analyser.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
+		</sectionGroup>
+	</configSections>
+	<startup/><userSettings>
+		<Analyser.Properties.Settings>
+			<setting name="filepath" serializeAs="String">
+				<value/>
+			</setting>
+			<setting name="EnableVariableCalls" serializeAs="String">
+				<value>True</value>
+			</setting>
+			<setting name="VariableNames" serializeAs="String">
+				<value>$COUNTER
+$ONGLOAD
+$ONGSAVE
+$ONNEWLOC
+$ONACTSEL
+$ONOBJSEL
+$ONOBJADD
+$ONOBJDEL
+$USERCOM</value>
+			</setting>
+			<setting name="EnableSortingLocations" serializeAs="String">
+				<value>True</value>
+			</setting>
+			<setting name="EnableSortingVariables" serializeAs="String">
+				<value>True</value>
+			</setting>
+			<setting name="EnableSortingObjects" serializeAs="String">
+				<value>True</value>
+			</setting>
+			<setting name="SystemVariables" serializeAs="String">
+				<value>FSIZE
+FCOLOR
+BCOLOR
+LCOLOR
+USEHTML
+$FNAME
+$BACKIMAGE
+NOSAVE
+DISABLESCROLL
+DISABLESUBEX
+DEBUG
+$COUNTER
+$ONGLOAD
+$ONGSAVE
+$ONNEWLOC
+$ONACTSEL
+$ONOBJSEL
+$ONOBJADD
+$ONOBJDEL
+$USERCOM
+ARGS
+$ARGS
+RESULT
+$RESULT</value>
+			</setting>
+			<setting name="EnableAero" serializeAs="String">
+				<value>True</value>
+			</setting>
+			<setting name="AeroSystemVars" serializeAs="String">
+				<value>SCROLL_SPEED
+$UP_ARROW_IMAGE
+$DOWN_ARROW_IMAGE
+HIDE_SCROLL_ARROWS
+$STYLESHEET
+DISABLESHADE
+DISABLEAUTOREF
+$NEWLOC_EFFECT
+NEWLOC_EFFECT_TIME
+NEWLOC_EFFECT_SEQ
+$TOPIMAGE
+INTEGRATED_ACTIONS
+MAINDESC_X
+MAINDESC_Y
+MAINDESC_W
+MAINDESC_H
+$MAIN_FORMAT
+$MAINDESC_BACKIMAGE
+STATDESC_X
+STATDESC_Y
+STATDESC_W
+STATDESC_H
+$STAT_FORMAT
+$STATDESC_BACKIMAGE
+ACTIONS_X
+ACTIONS_Y
+ACTIONS_W
+ACTIONS_H
+$ACTION_FORMAT
+$SEL_ACTION_FORMAT
+$ACTIONS_BACKIMAGE
+OBJECTS_X
+OBJECTS_Y
+OBJECTS_W
+OBJECTS_H
+$OBJECT_FORMAT
+$SEL_OBJECT_FORMAT
+$OBJECTS_BACKIMAGE
+USERINPUT_X
+USERINPUT_Y
+USERINPUT_W
+USERINPUT_H
+VIEW_X
+VIEW_Y
+VIEW_W
+VIEW_H
+$VIEW_EFFECT
+VIEW_EFFECT_TIME
+ALWAYS_SHOW_VIEW
+$INPUT_BACKIMAGE
+INPUT_X
+INPUT_Y
+$INPUT_FORMAT
+INPUT_TEXT_X
+INPUT_TEXT_Y
+INPUT_TEXT_W
+INPUT_TEXT_H
+INPUT_BAR_X
+INPUT_BAR_Y
+INPUT_BAR_W
+INPUT_BAR_H
+$INPUT_OK_IMAGE
+INPUT_OK_X
+INPUT_OK_Y
+$INPUT_CANCEL_IMAGE
+INPUT_CANCEL_X
+INPUT_CANCEL_Y
+$INPUT_EFFECT
+INPUT_EFFECT_TIME
+$MSG_BACKIMAGE
+MSG_X
+MSG_Y
+$MSG_FORMAT
+MSG_TEXT_X
+MSG_TEXT_Y
+MSG_TEXT_W
+MSG_TEXT_H
+$MSG_OK_IMAGE
+MSG_OK_X
+MSG_OK_Y
+$MSG_EFFECT
+MSG_EFFECT_TIME
+FIXED_SIZE_MENU
+MENU_PADDING
+MENU_BORDER
+MENU_BORDER_COLOR
+$MENU_BACKIMAGE
+MENU_X
+MENU_Y
+$MENU_FORMAT
+$SEL_MENU_FORMAT
+MENU_LIST_X
+MENU_LIST_Y
+MENU_LIST_W
+MENU_LIST_H
+$MENU_EFFECT
+MENU_EFFECT_TIME</value>
+			</setting>
+			<setting name="EnableSortingActions" serializeAs="String">
+				<value>True</value>
+			</setting>
+			<setting name="CsvTranslationSuffix" serializeAs="String">
+				<value>_tr</value>
+			</setting>
+			<setting name="IgnoreEmptyTranslationsCsv" serializeAs="String">
+				<value>True</value>
+			</setting>
+			<setting name="EnableCurlyParsing" serializeAs="String">
+				<value>True</value>
+			</setting>
+		</Analyser.Properties.Settings>
+	</userSettings>
+</configuration>

+ 18 - 0
QSP/qsp-analyser/QSP_Analyser/bin/Debug/QSP_Analyser.application

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<asmv1:assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xrml="urn:mpeg:mpeg21:2003:01-REL-R-NS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" xmlns:co.v2="urn:schemas-microsoft-com:clickonce.v2">
+  <assemblyIdentity name="QSP_Analyser.application" version="1.0.0.0" publicKeyToken="0000000000000000" language="neutral" processorArchitecture="msil" xmlns="urn:schemas-microsoft-com:asm.v1" />
+  <description asmv2:publisher="QSP_Analyser" asmv2:product="QSP_Analyser" xmlns="urn:schemas-microsoft-com:asm.v1" />
+  <deployment install="true" mapFileExtensions="true" />
+  <dependency>
+    <dependentAssembly dependencyType="install" codebase="QSP_Analyser.exe.manifest" size="3499">
+      <assemblyIdentity name="QSP_Analyser.exe" version="1.0.0.0" publicKeyToken="0000000000000000" language="neutral" processorArchitecture="msil" type="win32" />
+      <hash>
+        <dsig:Transforms>
+          <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
+        </dsig:Transforms>
+        <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
+        <dsig:DigestValue>uP4mNa7X/HZJWIl1NrI2jAKEg3Y=</dsig:DigestValue>
+      </hash>
+    </dependentAssembly>
+  </dependency>
+</asmv1:assembly>

BIN
QSP/qsp-analyser/QSP_Analyser/bin/Debug/QSP_Analyser.exe


+ 178 - 0
QSP/qsp-analyser/QSP_Analyser/bin/Debug/QSP_Analyser.exe.config

@@ -0,0 +1,178 @@
+<?xml version="1.0"?>
+<configuration>
+	<configSections>
+		<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+			<section name="Analyser.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
+		</sectionGroup>
+	</configSections>
+	<startup/><userSettings>
+		<Analyser.Properties.Settings>
+			<setting name="filepath" serializeAs="String">
+				<value/>
+			</setting>
+			<setting name="EnableVariableCalls" serializeAs="String">
+				<value>True</value>
+			</setting>
+			<setting name="VariableNames" serializeAs="String">
+				<value>$COUNTER
+$ONGLOAD
+$ONGSAVE
+$ONNEWLOC
+$ONACTSEL
+$ONOBJSEL
+$ONOBJADD
+$ONOBJDEL
+$USERCOM</value>
+			</setting>
+			<setting name="EnableSortingLocations" serializeAs="String">
+				<value>True</value>
+			</setting>
+			<setting name="EnableSortingVariables" serializeAs="String">
+				<value>True</value>
+			</setting>
+			<setting name="EnableSortingObjects" serializeAs="String">
+				<value>True</value>
+			</setting>
+			<setting name="SystemVariables" serializeAs="String">
+				<value>FSIZE
+FCOLOR
+BCOLOR
+LCOLOR
+USEHTML
+$FNAME
+$BACKIMAGE
+NOSAVE
+DISABLESCROLL
+DISABLESUBEX
+DEBUG
+$COUNTER
+$ONGLOAD
+$ONGSAVE
+$ONNEWLOC
+$ONACTSEL
+$ONOBJSEL
+$ONOBJADD
+$ONOBJDEL
+$USERCOM
+ARGS
+$ARGS
+RESULT
+$RESULT</value>
+			</setting>
+			<setting name="EnableAero" serializeAs="String">
+				<value>True</value>
+			</setting>
+			<setting name="AeroSystemVars" serializeAs="String">
+				<value>SCROLL_SPEED
+$UP_ARROW_IMAGE
+$DOWN_ARROW_IMAGE
+HIDE_SCROLL_ARROWS
+$STYLESHEET
+DISABLESHADE
+DISABLEAUTOREF
+$NEWLOC_EFFECT
+NEWLOC_EFFECT_TIME
+NEWLOC_EFFECT_SEQ
+$TOPIMAGE
+INTEGRATED_ACTIONS
+MAINDESC_X
+MAINDESC_Y
+MAINDESC_W
+MAINDESC_H
+$MAIN_FORMAT
+$MAINDESC_BACKIMAGE
+STATDESC_X
+STATDESC_Y
+STATDESC_W
+STATDESC_H
+$STAT_FORMAT
+$STATDESC_BACKIMAGE
+ACTIONS_X
+ACTIONS_Y
+ACTIONS_W
+ACTIONS_H
+$ACTION_FORMAT
+$SEL_ACTION_FORMAT
+$ACTIONS_BACKIMAGE
+OBJECTS_X
+OBJECTS_Y
+OBJECTS_W
+OBJECTS_H
+$OBJECT_FORMAT
+$SEL_OBJECT_FORMAT
+$OBJECTS_BACKIMAGE
+USERINPUT_X
+USERINPUT_Y
+USERINPUT_W
+USERINPUT_H
+VIEW_X
+VIEW_Y
+VIEW_W
+VIEW_H
+$VIEW_EFFECT
+VIEW_EFFECT_TIME
+ALWAYS_SHOW_VIEW
+$INPUT_BACKIMAGE
+INPUT_X
+INPUT_Y
+$INPUT_FORMAT
+INPUT_TEXT_X
+INPUT_TEXT_Y
+INPUT_TEXT_W
+INPUT_TEXT_H
+INPUT_BAR_X
+INPUT_BAR_Y
+INPUT_BAR_W
+INPUT_BAR_H
+$INPUT_OK_IMAGE
+INPUT_OK_X
+INPUT_OK_Y
+$INPUT_CANCEL_IMAGE
+INPUT_CANCEL_X
+INPUT_CANCEL_Y
+$INPUT_EFFECT
+INPUT_EFFECT_TIME
+$MSG_BACKIMAGE
+MSG_X
+MSG_Y
+$MSG_FORMAT
+MSG_TEXT_X
+MSG_TEXT_Y
+MSG_TEXT_W
+MSG_TEXT_H
+$MSG_OK_IMAGE
+MSG_OK_X
+MSG_OK_Y
+$MSG_EFFECT
+MSG_EFFECT_TIME
+FIXED_SIZE_MENU
+MENU_PADDING
+MENU_BORDER
+MENU_BORDER_COLOR
+$MENU_BACKIMAGE
+MENU_X
+MENU_Y
+$MENU_FORMAT
+$SEL_MENU_FORMAT
+MENU_LIST_X
+MENU_LIST_Y
+MENU_LIST_W
+MENU_LIST_H
+$MENU_EFFECT
+MENU_EFFECT_TIME</value>
+			</setting>
+			<setting name="EnableSortingActions" serializeAs="String">
+				<value>True</value>
+			</setting>
+			<setting name="CsvTranslationSuffix" serializeAs="String">
+				<value>_tr</value>
+			</setting>
+			<setting name="IgnoreEmptyTranslationsCsv" serializeAs="String">
+				<value>True</value>
+			</setting>
+			<setting name="EnableCurlyParsing" serializeAs="String">
+				<value>True</value>
+			</setting>
+		</Analyser.Properties.Settings>
+	</userSettings>
+</configuration>

+ 64 - 0
QSP/qsp-analyser/QSP_Analyser/bin/Debug/QSP_Analyser.exe.manifest

@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<asmv1:assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:co.v2="urn:schemas-microsoft-com:clickonce.v2">
+  <asmv1:assemblyIdentity name="QSP_Analyser.exe" version="1.0.0.0" publicKeyToken="0000000000000000" language="neutral" processorArchitecture="msil" type="win32" />
+  <application />
+  <entryPoint>
+    <assemblyIdentity name="QSP_Analyser" version="1.0.0.0" language="neutral" processorArchitecture="msil" />
+    <commandLine file="QSP_Analyser.exe" parameters="" />
+  </entryPoint>
+  <trustInfo>
+    <security>
+      <applicationRequestMinimum>
+        <PermissionSet class="System.Security.PermissionSet" version="1" ID="Custom" SameSite="site" Unrestricted="true" />
+        <defaultAssemblyRequest permissionSetReference="Custom" />
+      </applicationRequestMinimum>
+      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
+        <!-- UAC Manifest Options
+            If you want to change the Windows User Account Control level replace the 
+            requestedExecutionLevel node with one of the following.
+
+        <requestedExecutionLevel  level="asInvoker" uiAccess="false" />
+        <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
+        <requestedExecutionLevel  level="highestAvailable" uiAccess="false" />
+
+            If you want to utilize File and Registry Virtualization for backward 
+            compatibility then delete the requestedExecutionLevel node.
+        -->
+        <requestedExecutionLevel level="asInvoker" uiAccess="false" />
+      </requestedPrivileges>
+    </security>
+  </trustInfo>
+  <dependency>
+    <dependentOS>
+      <osVersionInfo>
+        <os majorVersion="4" minorVersion="10" buildNumber="0" servicePackMajor="0" />
+      </osVersionInfo>
+    </dependentOS>
+  </dependency>
+  <dependency>
+    <dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
+      <assemblyIdentity name="Microsoft.Windows.CommonLanguageRuntime" version="2.0.50727.0" />
+    </dependentAssembly>
+  </dependency>
+  <dependency>
+    <dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="QSP_Analyser.exe" size="77824">
+      <assemblyIdentity name="QSP_Analyser" version="1.0.0.0" language="neutral" processorArchitecture="msil" />
+      <hash>
+        <dsig:Transforms>
+          <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
+        </dsig:Transforms>
+        <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
+        <dsig:DigestValue>thJRT8L4ZkRToqtichfxQW989qE=</dsig:DigestValue>
+      </hash>
+    </dependentAssembly>
+  </dependency>
+  <file name="QSP_Analyser.exe.config" size="3585">
+    <hash>
+      <dsig:Transforms>
+        <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
+      </dsig:Transforms>
+      <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
+      <dsig:DigestValue>J/ey7PHXPXO8TAhsxy0HFdTa/Zk=</dsig:DigestValue>
+    </hash>
+  </file>
+</asmv1:assembly>

BIN
QSP/qsp-analyser/QSP_Analyser/bin/Debug/QSP_Analyser.pdb


BIN
QSP/qsp-analyser/QSP_Analyser/bin/Debug/app.publish/QSP_Analyser.exe


+ 18 - 0
QSP/qsp-analyser/QSP_Analyser/bin/Release/QSP_Analyser.application

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<asmv1:assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xrml="urn:mpeg:mpeg21:2003:01-REL-R-NS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" xmlns:co.v2="urn:schemas-microsoft-com:clickonce.v2">
+  <assemblyIdentity name="QSP_Analyser.application" version="1.0.0.0" publicKeyToken="0000000000000000" language="neutral" processorArchitecture="msil" xmlns="urn:schemas-microsoft-com:asm.v1" />
+  <description asmv2:publisher="QSP_Analyser" asmv2:product="QSP_Analyser" xmlns="urn:schemas-microsoft-com:asm.v1" />
+  <deployment install="true" mapFileExtensions="true" />
+  <dependency>
+    <dependentAssembly dependencyType="install" codebase="QSP_Analyser.exe.manifest" size="3499">
+      <assemblyIdentity name="QSP_Analyser.exe" version="1.0.0.0" publicKeyToken="0000000000000000" language="neutral" processorArchitecture="msil" type="win32" />
+      <hash>
+        <dsig:Transforms>
+          <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
+        </dsig:Transforms>
+        <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
+        <dsig:DigestValue>lAPGr7Cf7vpNIJp5b1q55nXG27E=</dsig:DigestValue>
+      </hash>
+    </dependentAssembly>
+  </dependency>
+</asmv1:assembly>

BIN
QSP/qsp-analyser/QSP_Analyser/bin/Release/QSP_Analyser.exe


+ 178 - 0
QSP/qsp-analyser/QSP_Analyser/bin/Release/QSP_Analyser.exe.config

@@ -0,0 +1,178 @@
+<?xml version="1.0"?>
+<configuration>
+	<configSections>
+		<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+			<section name="Analyser.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
+		</sectionGroup>
+	</configSections>
+	<startup/><userSettings>
+		<Analyser.Properties.Settings>
+			<setting name="filepath" serializeAs="String">
+				<value/>
+			</setting>
+			<setting name="EnableVariableCalls" serializeAs="String">
+				<value>True</value>
+			</setting>
+			<setting name="VariableNames" serializeAs="String">
+				<value>$COUNTER
+$ONGLOAD
+$ONGSAVE
+$ONNEWLOC
+$ONACTSEL
+$ONOBJSEL
+$ONOBJADD
+$ONOBJDEL
+$USERCOM</value>
+			</setting>
+			<setting name="EnableSortingLocations" serializeAs="String">
+				<value>True</value>
+			</setting>
+			<setting name="EnableSortingVariables" serializeAs="String">
+				<value>True</value>
+			</setting>
+			<setting name="EnableSortingObjects" serializeAs="String">
+				<value>True</value>
+			</setting>
+			<setting name="SystemVariables" serializeAs="String">
+				<value>FSIZE
+FCOLOR
+BCOLOR
+LCOLOR
+USEHTML
+$FNAME
+$BACKIMAGE
+NOSAVE
+DISABLESCROLL
+DISABLESUBEX
+DEBUG
+$COUNTER
+$ONGLOAD
+$ONGSAVE
+$ONNEWLOC
+$ONACTSEL
+$ONOBJSEL
+$ONOBJADD
+$ONOBJDEL
+$USERCOM
+ARGS
+$ARGS
+RESULT
+$RESULT</value>
+			</setting>
+			<setting name="EnableAero" serializeAs="String">
+				<value>True</value>
+			</setting>
+			<setting name="AeroSystemVars" serializeAs="String">
+				<value>SCROLL_SPEED
+$UP_ARROW_IMAGE
+$DOWN_ARROW_IMAGE
+HIDE_SCROLL_ARROWS
+$STYLESHEET
+DISABLESHADE
+DISABLEAUTOREF
+$NEWLOC_EFFECT
+NEWLOC_EFFECT_TIME
+NEWLOC_EFFECT_SEQ
+$TOPIMAGE
+INTEGRATED_ACTIONS
+MAINDESC_X
+MAINDESC_Y
+MAINDESC_W
+MAINDESC_H
+$MAIN_FORMAT
+$MAINDESC_BACKIMAGE
+STATDESC_X
+STATDESC_Y
+STATDESC_W
+STATDESC_H
+$STAT_FORMAT
+$STATDESC_BACKIMAGE
+ACTIONS_X
+ACTIONS_Y
+ACTIONS_W
+ACTIONS_H
+$ACTION_FORMAT
+$SEL_ACTION_FORMAT
+$ACTIONS_BACKIMAGE
+OBJECTS_X
+OBJECTS_Y
+OBJECTS_W
+OBJECTS_H
+$OBJECT_FORMAT
+$SEL_OBJECT_FORMAT
+$OBJECTS_BACKIMAGE
+USERINPUT_X
+USERINPUT_Y
+USERINPUT_W
+USERINPUT_H
+VIEW_X
+VIEW_Y
+VIEW_W
+VIEW_H
+$VIEW_EFFECT
+VIEW_EFFECT_TIME
+ALWAYS_SHOW_VIEW
+$INPUT_BACKIMAGE
+INPUT_X
+INPUT_Y
+$INPUT_FORMAT
+INPUT_TEXT_X
+INPUT_TEXT_Y
+INPUT_TEXT_W
+INPUT_TEXT_H
+INPUT_BAR_X
+INPUT_BAR_Y
+INPUT_BAR_W
+INPUT_BAR_H
+$INPUT_OK_IMAGE
+INPUT_OK_X
+INPUT_OK_Y
+$INPUT_CANCEL_IMAGE
+INPUT_CANCEL_X
+INPUT_CANCEL_Y
+$INPUT_EFFECT
+INPUT_EFFECT_TIME
+$MSG_BACKIMAGE
+MSG_X
+MSG_Y
+$MSG_FORMAT
+MSG_TEXT_X
+MSG_TEXT_Y
+MSG_TEXT_W
+MSG_TEXT_H
+$MSG_OK_IMAGE
+MSG_OK_X
+MSG_OK_Y
+$MSG_EFFECT
+MSG_EFFECT_TIME
+FIXED_SIZE_MENU
+MENU_PADDING
+MENU_BORDER
+MENU_BORDER_COLOR
+$MENU_BACKIMAGE
+MENU_X
+MENU_Y
+$MENU_FORMAT
+$SEL_MENU_FORMAT
+MENU_LIST_X
+MENU_LIST_Y
+MENU_LIST_W
+MENU_LIST_H
+$MENU_EFFECT
+MENU_EFFECT_TIME</value>
+			</setting>
+			<setting name="EnableSortingActions" serializeAs="String">
+				<value>True</value>
+			</setting>
+			<setting name="CsvTranslationSuffix" serializeAs="String">
+				<value>_tr</value>
+			</setting>
+			<setting name="IgnoreEmptyTranslationsCsv" serializeAs="String">
+				<value>True</value>
+			</setting>
+			<setting name="EnableCurlyParsing" serializeAs="String">
+				<value>True</value>
+			</setting>
+		</Analyser.Properties.Settings>
+	</userSettings>
+</configuration>

+ 64 - 0
QSP/qsp-analyser/QSP_Analyser/bin/Release/QSP_Analyser.exe.manifest

@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<asmv1:assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:co.v2="urn:schemas-microsoft-com:clickonce.v2">
+  <asmv1:assemblyIdentity name="QSP_Analyser.exe" version="1.0.0.0" publicKeyToken="0000000000000000" language="neutral" processorArchitecture="msil" type="win32" />
+  <application />
+  <entryPoint>
+    <assemblyIdentity name="QSP_Analyser" version="1.0.0.0" language="neutral" processorArchitecture="msil" />
+    <commandLine file="QSP_Analyser.exe" parameters="" />
+  </entryPoint>
+  <trustInfo>
+    <security>
+      <applicationRequestMinimum>
+        <PermissionSet class="System.Security.PermissionSet" version="1" ID="Custom" SameSite="site" Unrestricted="true" />
+        <defaultAssemblyRequest permissionSetReference="Custom" />
+      </applicationRequestMinimum>
+      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
+        <!-- UAC Manifest Options
+            If you want to change the Windows User Account Control level replace the 
+            requestedExecutionLevel node with one of the following.
+
+        <requestedExecutionLevel  level="asInvoker" uiAccess="false" />
+        <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
+        <requestedExecutionLevel  level="highestAvailable" uiAccess="false" />
+
+            If you want to utilize File and Registry Virtualization for backward 
+            compatibility then delete the requestedExecutionLevel node.
+        -->
+        <requestedExecutionLevel level="asInvoker" uiAccess="false" />
+      </requestedPrivileges>
+    </security>
+  </trustInfo>
+  <dependency>
+    <dependentOS>
+      <osVersionInfo>
+        <os majorVersion="4" minorVersion="10" buildNumber="0" servicePackMajor="0" />
+      </osVersionInfo>
+    </dependentOS>
+  </dependency>
+  <dependency>
+    <dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
+      <assemblyIdentity name="Microsoft.Windows.CommonLanguageRuntime" version="2.0.50727.0" />
+    </dependentAssembly>
+  </dependency>
+  <dependency>
+    <dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="QSP_Analyser.exe" size="70656">
+      <assemblyIdentity name="QSP_Analyser" version="1.0.0.0" language="neutral" processorArchitecture="msil" />
+      <hash>
+        <dsig:Transforms>
+          <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
+        </dsig:Transforms>
+        <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
+        <dsig:DigestValue>moLI6Ib1XlcPSbHLeYuvwQLN79I=</dsig:DigestValue>
+      </hash>
+    </dependentAssembly>
+  </dependency>
+  <file name="QSP_Analyser.exe.config" size="3585">
+    <hash>
+      <dsig:Transforms>
+        <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
+      </dsig:Transforms>
+      <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
+      <dsig:DigestValue>J/ey7PHXPXO8TAhsxy0HFdTa/Zk=</dsig:DigestValue>
+    </hash>
+  </file>
+</asmv1:assembly>

BIN
QSP/qsp-analyser/QSP_Analyser/bin/Release/QSP_Analyser.pdb


BIN
QSP/qsp-analyser/QSP_Analyser/bin/Release/app.publish/QSP_Analyser.exe


BIN
QSP/qsp-analyser/QSP_Analyser/obj/Debug/Analyser.MainForm.resources


BIN
QSP/qsp-analyser/QSP_Analyser/obj/Debug/Analyser.Properties.Resources.resources


+ 1 - 0
QSP/qsp-analyser/QSP_Analyser/obj/Debug/CoreCompileInputs.cache

@@ -0,0 +1 @@
+58f8df29b193a22e0b3e789a3004b76cb7f6a0e1

BIN
QSP/qsp-analyser/QSP_Analyser/obj/Debug/DesignTimeResolveAssemblyReferences.cache


BIN
QSP/qsp-analyser/QSP_Analyser/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache


+ 11 - 0
QSP/qsp-analyser/QSP_Analyser/obj/Debug/QSP_Analyser.TrustInfo.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?><trustInfo xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"><security><applicationRequestMinimum><PermissionSet class="System.Security.PermissionSet" version="1" ID="Custom" SameSite="site" Unrestricted="true" /><defaultAssemblyRequest permissionSetReference="Custom" /></applicationRequestMinimum><requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"><!-- UAC Manifest Options
+            If you want to change the Windows User Account Control level replace the 
+            requestedExecutionLevel node with one of the following.
+
+        <requestedExecutionLevel  level="asInvoker" uiAccess="false" />
+        <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
+        <requestedExecutionLevel  level="highestAvailable" uiAccess="false" />
+
+            If you want to utilize File and Registry Virtualization for backward 
+            compatibility then delete the requestedExecutionLevel node.
+        --><requestedExecutionLevel level="asInvoker" uiAccess="false" /></requestedPrivileges></security></trustInfo>

+ 18 - 0
QSP/qsp-analyser/QSP_Analyser/obj/Debug/QSP_Analyser.application

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<asmv1:assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xrml="urn:mpeg:mpeg21:2003:01-REL-R-NS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" xmlns:co.v2="urn:schemas-microsoft-com:clickonce.v2">
+  <assemblyIdentity name="QSP_Analyser.application" version="1.0.0.0" publicKeyToken="0000000000000000" language="neutral" processorArchitecture="msil" xmlns="urn:schemas-microsoft-com:asm.v1" />
+  <description asmv2:publisher="QSP_Analyser" asmv2:product="QSP_Analyser" xmlns="urn:schemas-microsoft-com:asm.v1" />
+  <deployment install="true" mapFileExtensions="true" />
+  <dependency>
+    <dependentAssembly dependencyType="install" codebase="QSP_Analyser.exe.manifest" size="3499">
+      <assemblyIdentity name="QSP_Analyser.exe" version="1.0.0.0" publicKeyToken="0000000000000000" language="neutral" processorArchitecture="msil" type="win32" />
+      <hash>
+        <dsig:Transforms>
+          <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
+        </dsig:Transforms>
+        <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
+        <dsig:DigestValue>uP4mNa7X/HZJWIl1NrI2jAKEg3Y=</dsig:DigestValue>
+      </hash>
+    </dependentAssembly>
+  </dependency>
+</asmv1:assembly>

+ 27 - 0
QSP/qsp-analyser/QSP_Analyser/obj/Debug/QSP_Analyser.csproj.FileListAbsolute.txt

@@ -0,0 +1,27 @@
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\bin\Debug\QSP_Analyser.exe.config
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\bin\Debug\QSP_Analyser.exe.manifest
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\bin\Debug\QSP_Analyser.application
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\bin\Debug\QSP_Analyser.exe
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\bin\Debug\QSP_Analyser.pdb
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\obj\Debug\Analyser.MainForm.resources
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\obj\Debug\Analyser.Properties.Resources.resources
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\obj\Debug\QSP_Analyser.csproj.GenerateResource.Cache
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\obj\Debug\QSP_Analyser.TrustInfo.xml
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\obj\Debug\QSP_Analyser.exe.manifest
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\obj\Debug\QSP_Analyser.application
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\obj\Debug\QSP_Analyser.exe
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\obj\Debug\QSP_Analyser.pdb
+C:\Temp\qsp-analyser\QSP_Analyser\bin\Debug\QSP_Analyser.exe.config
+C:\Temp\qsp-analyser\QSP_Analyser\bin\Debug\QSP_Analyser.exe.manifest
+C:\Temp\qsp-analyser\QSP_Analyser\bin\Debug\QSP_Analyser.application
+C:\Temp\qsp-analyser\QSP_Analyser\bin\Debug\QSP_Analyser.exe
+C:\Temp\qsp-analyser\QSP_Analyser\bin\Debug\QSP_Analyser.pdb
+C:\Temp\qsp-analyser\QSP_Analyser\obj\Debug\QSP_Analyser.csprojResolveAssemblyReference.cache
+C:\Temp\qsp-analyser\QSP_Analyser\obj\Debug\Analyser.MainForm.resources
+C:\Temp\qsp-analyser\QSP_Analyser\obj\Debug\Analyser.Properties.Resources.resources
+C:\Temp\qsp-analyser\QSP_Analyser\obj\Debug\QSP_Analyser.csproj.GenerateResource.Cache
+C:\Temp\qsp-analyser\QSP_Analyser\obj\Debug\QSP_Analyser.TrustInfo.xml
+C:\Temp\qsp-analyser\QSP_Analyser\obj\Debug\QSP_Analyser.exe.manifest
+C:\Temp\qsp-analyser\QSP_Analyser\obj\Debug\QSP_Analyser.application
+C:\Temp\qsp-analyser\QSP_Analyser\obj\Debug\QSP_Analyser.exe
+C:\Temp\qsp-analyser\QSP_Analyser\obj\Debug\QSP_Analyser.pdb

BIN
QSP/qsp-analyser/QSP_Analyser/obj/Debug/QSP_Analyser.csproj.GenerateResource.Cache


BIN
QSP/qsp-analyser/QSP_Analyser/obj/Debug/QSP_Analyser.csprojResolveAssemblyReference.cache


BIN
QSP/qsp-analyser/QSP_Analyser/obj/Debug/QSP_Analyser.exe


+ 64 - 0
QSP/qsp-analyser/QSP_Analyser/obj/Debug/QSP_Analyser.exe.manifest

@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<asmv1:assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:co.v2="urn:schemas-microsoft-com:clickonce.v2">
+  <asmv1:assemblyIdentity name="QSP_Analyser.exe" version="1.0.0.0" publicKeyToken="0000000000000000" language="neutral" processorArchitecture="msil" type="win32" />
+  <application />
+  <entryPoint>
+    <assemblyIdentity name="QSP_Analyser" version="1.0.0.0" language="neutral" processorArchitecture="msil" />
+    <commandLine file="QSP_Analyser.exe" parameters="" />
+  </entryPoint>
+  <trustInfo>
+    <security>
+      <applicationRequestMinimum>
+        <PermissionSet class="System.Security.PermissionSet" version="1" ID="Custom" SameSite="site" Unrestricted="true" />
+        <defaultAssemblyRequest permissionSetReference="Custom" />
+      </applicationRequestMinimum>
+      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
+        <!-- UAC Manifest Options
+            If you want to change the Windows User Account Control level replace the 
+            requestedExecutionLevel node with one of the following.
+
+        <requestedExecutionLevel  level="asInvoker" uiAccess="false" />
+        <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
+        <requestedExecutionLevel  level="highestAvailable" uiAccess="false" />
+
+            If you want to utilize File and Registry Virtualization for backward 
+            compatibility then delete the requestedExecutionLevel node.
+        -->
+        <requestedExecutionLevel level="asInvoker" uiAccess="false" />
+      </requestedPrivileges>
+    </security>
+  </trustInfo>
+  <dependency>
+    <dependentOS>
+      <osVersionInfo>
+        <os majorVersion="4" minorVersion="10" buildNumber="0" servicePackMajor="0" />
+      </osVersionInfo>
+    </dependentOS>
+  </dependency>
+  <dependency>
+    <dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
+      <assemblyIdentity name="Microsoft.Windows.CommonLanguageRuntime" version="2.0.50727.0" />
+    </dependentAssembly>
+  </dependency>
+  <dependency>
+    <dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="QSP_Analyser.exe" size="77824">
+      <assemblyIdentity name="QSP_Analyser" version="1.0.0.0" language="neutral" processorArchitecture="msil" />
+      <hash>
+        <dsig:Transforms>
+          <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
+        </dsig:Transforms>
+        <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
+        <dsig:DigestValue>thJRT8L4ZkRToqtichfxQW989qE=</dsig:DigestValue>
+      </hash>
+    </dependentAssembly>
+  </dependency>
+  <file name="QSP_Analyser.exe.config" size="3585">
+    <hash>
+      <dsig:Transforms>
+        <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
+      </dsig:Transforms>
+      <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
+      <dsig:DigestValue>J/ey7PHXPXO8TAhsxy0HFdTa/Zk=</dsig:DigestValue>
+    </hash>
+  </file>
+</asmv1:assembly>

BIN
QSP/qsp-analyser/QSP_Analyser/obj/Debug/QSP_Analyser.pdb


BIN
QSP/qsp-analyser/QSP_Analyser/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll


BIN
QSP/qsp-analyser/QSP_Analyser/obj/Release/Analyser.MainForm.resources


BIN
QSP/qsp-analyser/QSP_Analyser/obj/Release/Analyser.Properties.Resources.resources


+ 1 - 0
QSP/qsp-analyser/QSP_Analyser/obj/Release/CoreCompileInputs.cache

@@ -0,0 +1 @@
+18a2a3392e504c81a7d3f4ebb56ca57be4e67b4f

BIN
QSP/qsp-analyser/QSP_Analyser/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache


+ 11 - 0
QSP/qsp-analyser/QSP_Analyser/obj/Release/QSP_Analyser.TrustInfo.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?><trustInfo xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"><security><applicationRequestMinimum><PermissionSet class="System.Security.PermissionSet" version="1" ID="Custom" SameSite="site" Unrestricted="true" /><defaultAssemblyRequest permissionSetReference="Custom" /></applicationRequestMinimum><requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"><!-- UAC Manifest Options
+            If you want to change the Windows User Account Control level replace the 
+            requestedExecutionLevel node with one of the following.
+
+        <requestedExecutionLevel  level="asInvoker" uiAccess="false" />
+        <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
+        <requestedExecutionLevel  level="highestAvailable" uiAccess="false" />
+
+            If you want to utilize File and Registry Virtualization for backward 
+            compatibility then delete the requestedExecutionLevel node.
+        --><requestedExecutionLevel level="asInvoker" uiAccess="false" /></requestedPrivileges></security></trustInfo>

+ 18 - 0
QSP/qsp-analyser/QSP_Analyser/obj/Release/QSP_Analyser.application

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<asmv1:assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xrml="urn:mpeg:mpeg21:2003:01-REL-R-NS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" xmlns:co.v2="urn:schemas-microsoft-com:clickonce.v2">
+  <assemblyIdentity name="QSP_Analyser.application" version="1.0.0.0" publicKeyToken="0000000000000000" language="neutral" processorArchitecture="msil" xmlns="urn:schemas-microsoft-com:asm.v1" />
+  <description asmv2:publisher="QSP_Analyser" asmv2:product="QSP_Analyser" xmlns="urn:schemas-microsoft-com:asm.v1" />
+  <deployment install="true" mapFileExtensions="true" />
+  <dependency>
+    <dependentAssembly dependencyType="install" codebase="QSP_Analyser.exe.manifest" size="3499">
+      <assemblyIdentity name="QSP_Analyser.exe" version="1.0.0.0" publicKeyToken="0000000000000000" language="neutral" processorArchitecture="msil" type="win32" />
+      <hash>
+        <dsig:Transforms>
+          <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
+        </dsig:Transforms>
+        <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
+        <dsig:DigestValue>lAPGr7Cf7vpNIJp5b1q55nXG27E=</dsig:DigestValue>
+      </hash>
+    </dependentAssembly>
+  </dependency>
+</asmv1:assembly>

+ 13 - 0
QSP/qsp-analyser/QSP_Analyser/obj/Release/QSP_Analyser.csproj.FileListAbsolute.txt

@@ -0,0 +1,13 @@
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\bin\Release\QSP_Analyser.exe.config
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\bin\Release\QSP_Analyser.exe.manifest
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\bin\Release\QSP_Analyser.application
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\bin\Release\QSP_Analyser.exe
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\bin\Release\QSP_Analyser.pdb
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\obj\Release\Analyser.MainForm.resources
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\obj\Release\Analyser.Properties.Resources.resources
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\obj\Release\QSP_Analyser.csproj.GenerateResource.Cache
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\obj\Release\QSP_Analyser.TrustInfo.xml
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\obj\Release\QSP_Analyser.exe.manifest
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\obj\Release\QSP_Analyser.application
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\obj\Release\QSP_Analyser.exe
+C:\Temp\qsp-analyser\trunk\QSP_Analyser\obj\Release\QSP_Analyser.pdb

BIN
QSP/qsp-analyser/QSP_Analyser/obj/Release/QSP_Analyser.csproj.GenerateResource.Cache


BIN
QSP/qsp-analyser/QSP_Analyser/obj/Release/QSP_Analyser.exe


+ 64 - 0
QSP/qsp-analyser/QSP_Analyser/obj/Release/QSP_Analyser.exe.manifest

@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<asmv1:assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:co.v2="urn:schemas-microsoft-com:clickonce.v2">
+  <asmv1:assemblyIdentity name="QSP_Analyser.exe" version="1.0.0.0" publicKeyToken="0000000000000000" language="neutral" processorArchitecture="msil" type="win32" />
+  <application />
+  <entryPoint>
+    <assemblyIdentity name="QSP_Analyser" version="1.0.0.0" language="neutral" processorArchitecture="msil" />
+    <commandLine file="QSP_Analyser.exe" parameters="" />
+  </entryPoint>
+  <trustInfo>
+    <security>
+      <applicationRequestMinimum>
+        <PermissionSet class="System.Security.PermissionSet" version="1" ID="Custom" SameSite="site" Unrestricted="true" />
+        <defaultAssemblyRequest permissionSetReference="Custom" />
+      </applicationRequestMinimum>
+      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
+        <!-- UAC Manifest Options
+            If you want to change the Windows User Account Control level replace the 
+            requestedExecutionLevel node with one of the following.
+
+        <requestedExecutionLevel  level="asInvoker" uiAccess="false" />
+        <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
+        <requestedExecutionLevel  level="highestAvailable" uiAccess="false" />
+
+            If you want to utilize File and Registry Virtualization for backward 
+            compatibility then delete the requestedExecutionLevel node.
+        -->
+        <requestedExecutionLevel level="asInvoker" uiAccess="false" />
+      </requestedPrivileges>
+    </security>
+  </trustInfo>
+  <dependency>
+    <dependentOS>
+      <osVersionInfo>
+        <os majorVersion="4" minorVersion="10" buildNumber="0" servicePackMajor="0" />
+      </osVersionInfo>
+    </dependentOS>
+  </dependency>
+  <dependency>
+    <dependentAssembly dependencyType="preRequisite" allowDelayedBinding="true">
+      <assemblyIdentity name="Microsoft.Windows.CommonLanguageRuntime" version="2.0.50727.0" />
+    </dependentAssembly>
+  </dependency>
+  <dependency>
+    <dependentAssembly dependencyType="install" allowDelayedBinding="true" codebase="QSP_Analyser.exe" size="70656">
+      <assemblyIdentity name="QSP_Analyser" version="1.0.0.0" language="neutral" processorArchitecture="msil" />
+      <hash>
+        <dsig:Transforms>
+          <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
+        </dsig:Transforms>
+        <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
+        <dsig:DigestValue>moLI6Ib1XlcPSbHLeYuvwQLN79I=</dsig:DigestValue>
+      </hash>
+    </dependentAssembly>
+  </dependency>
+  <file name="QSP_Analyser.exe.config" size="3585">
+    <hash>
+      <dsig:Transforms>
+        <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
+      </dsig:Transforms>
+      <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
+      <dsig:DigestValue>J/ey7PHXPXO8TAhsxy0HFdTa/Zk=</dsig:DigestValue>
+    </hash>
+  </file>
+</asmv1:assembly>

BIN
QSP/qsp-analyser/QSP_Analyser/obj/Release/QSP_Analyser.pdb


BIN
QSP/qsp-analyser/QSP_Analyser/obj/Release/TempPE/Properties.Resources.Designer.cs.dll