1. C# / Говнокод #17195

    +135

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    public CookieContainer GetCookies(string url, string login, string password)
    {
        try
        {
            var cookies = new CookieContainer();
            string postData = string.Format(@"subaction=dologin&username={0}&password={1}&selected_language=Russian&x=62&y=37", Uri.EscapeDataString(login), Uri.EscapeDataString(password));
            HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url + "admin.php");
            httpWebRequest.AllowAutoRedirect = true;
            httpWebRequest.CookieContainer = cookies;
            httpWebRequest.Method = "POST";
            httpWebRequest.ContentType = "application/x-www-form-urlencoded";
            httpWebRequest.UserAgent = "Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.10.289 Version/12.01";
            httpWebRequest.ServicePoint.Expect100Continue = false;
            byte[] ByteQuery = System.Text.Encoding.UTF8.GetBytes(postData);
            httpWebRequest.ContentLength = ByteQuery.Length;
            Stream QueryStream = httpWebRequest.GetRequestStream();
            QueryStream.Write(ByteQuery, 0, ByteQuery.Length);
            QueryStream.Close();
            HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
            StreamReader sr = new StreamReader(httpWebResponse.GetResponseStream(), Encoding.GetEncoding(1251));
            string loginPage = sr.ReadToEnd();
            sr.Close();
            if (loginPage.IndexOf(@"div class=""error""") == -1)
            {
                httpWebResponse.Cookies = httpWebRequest.CookieContainer.GetCookies(httpWebRequest.RequestUri);
                httpWebResponse.Close();
                return cookies;
            }
            else
            {
                return null;
            }
            
        }
        catch (Exception)
        {
            if (n < 3)
            {
                Thread.Sleep(400);
                n++;
                return GetCookies(url, login, password);
            }
            else
            {
                n = 0;
                return null;
            }
        }
    }

    Костыльно-ориентированное велосипедирование. Выдержка из паттерна "тулза для работы с вебом", метод авторизации на какой-то из CMS.

    pushistayapodmyshka, 27 Ноября 2014

    Комментарии (25)
  2. C# / Говнокод #17186

    +134

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    75. 75
    76. 76
    77. 77
    78. 78
    79. 79
    80. 80
    81. 81
    82. 82
    83. 83
    84. 84
    85. 85
    86. 86
    87. 87
    88. 88
    89. 89
    90. 90
    91. 91
    92. 92
    93. 93
    94. 94
    95. 95
    96. 96
    97. 97
    98. 98
    public void OnKillEvent_ServerOnly(PhotonPlayer player)
        {
        case MatchTypeInfo.TDM:
    
                    if (player != null)
                    {
                        var hash = player.customProperties;
    
                        if (hash != null)
                        {
                            var team = (int) hash["team"];
    
                            var realScore = match.GetTeamScores();
    
                            var teamAScor = team == 0 ? realScore.x + TeamDeathScores : realScore.x;
                            var teamBScor = team == 1 ? realScore.y + TeamDeathScores : realScore.y;
    
                            //DebugModule("Kill Processed On Server completed: " + team + "// " + teamAScor + "/" + teamBScor);
    
                            match.ChangeTeamScores((int)teamAScor, (int)teamBScor);
                        }
                        else
                        {
                            Debug.LogError("OnKillEvent_ServerOnly ERROR Team hash");
                        }
                    }
    
                    break;
    }  {
    //через 500 строк кода
       private void LocalUpdate()
        { 
        if (Application.isEditor)
            {
                if (Input.GetKeyDown(KeyCode.Y))
                {
                    switch (MatchType)
                    {
    
                        case MatchTypeInfo.TDM:
                            ChangeTeamScores((int)(_teamScores.x - 1), (int)(_teamScores.y - 1), true);
                            break;   }
    
                    SendTeamScoresToUI();
                }
            }
    
       switch (MatchType)
            {
                case MatchTypeInfo.TDM:
                   // DebugModule("Load TDM type game");
                    break;
    }
    }
    //ещё 500 строк
     public void ChangeTeamScores(int a, int b, bool force = false)
        {
    
            if (PhotonNetwork.isMasterClient)
            {
                // check server rules
                var rules = GetGameRules();
                if (rules != null)
                {
                    if (!rules.CheckPlayerCountRules() && !force)
                    {
                        Debug.LogError("Game is not started, beacuse server has no players: " + rules.MinimumPlayerToPlay + "/" +
                                       PhotonNetwork.room.playerCount);
                        return;
                    }
                }
                else
                {
                    Debug.LogError("Rule error");
                    return;
                }
    
                _teamScores.x = Mathf.Clamp(a, 0, float.MaxValue);
                _teamScores.y = Mathf.Clamp(b, 0, float.MaxValue);
    
                var matchIsCompleted = false;
    
                switch (MatchType)
                {
                    case MatchTypeInfo.TDM:
                        matchIsCompleted = _teamScores.x <= 0 || _teamScores.y <= 0;
                        break;
                }
                   if (matchIsCompleted)
                {
                    Server_CallEndRound();
                }
                else
                {
                    // Call Event??
                  }
    }
    }

    Чтобы я ещё раз полез помогать инди-разработчикам, мать их за ногу.

    noshitleft, 26 Ноября 2014

    Комментарии (3)
  3. C# / Говнокод #17184

    +134

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    protected static DataTable[] ExecuteDataTablesReader(string ProcedureName, SqlParameter[] Params = null) {
    
                SqlConnection cnn = new SqlConnection(ConnectionString);
                SqlCommand cmd = new SqlCommand(ProcedureName, cnn);
                cmd.CommandType = System.Data.CommandType.StoredProcedure;
                if (Params != null && Params.Count() > 0) {
                    cmd.Parameters.AddRange(Params);
                }
                cnn.Open();
                
                IDataReader rd = cmd.ExecuteReader();
                List<DataTable> tables = new List<DataTable>();
                do {
                    DataTable dt = new DataTable();
                    dt.Load(rd);
                    tables.Add(dt);
                } while (rd.NextResult());
    
                return tables.ToArray();
    
            }

    может я чего не понимаю, но какого хера rd.NextResult() кидает мне exception, что ридер закрыт?

    Lokich, 26 Ноября 2014

    Комментарии (13)
  4. C# / Говнокод #17183

    +135

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    public void Login(ClientHandlers<int> actions)
            {
                var request = GetGetRequest("/user/xml/{0}", _login);
    
                var act = new Action<IRestResponse<GetUserInfoResult>>(response =>
                    {
                        if (CheckUserInfo(response))
                        {
                            throw new Exception("Невозможно получить информацию о пользователе\r\nНеобработанное исключение");
                        }
    
                        UserInfo = response.Data.UserInfo;
                        actions.Completed(UserInfo.idUser);
                    });
                _client.ExecuteAsync(request, act);
            }
    
            private bool CheckUserInfo(IRestResponse<GetUserInfoResult> response)
            {
                if (response != null && response.Data != null && response.Data.UserInfo != null && response.Data.UserInfo.idUser != 0)
                {
                    return true;
                }
    
                var message = "Невозможно получить информацию о пользователе";
                if (response == null)
                {
                    message = string.Format("{0}\r\n{1}", 
                                            message, 
                                            "Response is null");
                    throw new Exception(message);
                }
    
                message = string.Format("{0}\r\nResponse data is null\r\nContext: {1}", 
                                        message, 
                                        response.Content);
    
                if (response.Data == null)
                {
                    throw new Exception(message);
                }
    
                message = string.Format("{0}\r\nIs exception: {1}\r\nMessage: {2}", 
                                        message, 
                                        response.Data.IsException, 
                                        response.Data.Message);
    
                if (response.Data.UserInfo == null)
                {
                    throw new Exception(message);
                }
    
                message = string.Format("{0}\r\nSiteName: {1}\r\nUserName: {2}\r\nUserRole: {3}", 
                                        message, 
                                        response.Data.UserInfo.SiteName, 
                                        response.Data.UserInfo.UserName, 
                                        response.Data.UserInfo.UserRole);
                if (response.Data.UserInfo.idUser == 0)
                {
                    throw new Exception(message);
                }
    
                return false;
            }

    Внимательность, внимательность и еще раз внимательность...

    HellMaster_HaiL, 26 Ноября 2014

    Комментарии (3)
  5. C# / Говнокод #17166

    +137

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    8. 8
    9. 9
    void _device_ChangeStsConnect(bool Conn)								
    {
    	switch (Conn)
    	{
    		case true: Start(); break;
    		case false: Stop(); break;
    		default: break;
    	}
    }

    "Классический" switch булевой переменной.

    Qetu107, 25 Ноября 2014

    Комментарии (16)
  6. C# / Говнокод #17161

    +135

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    75. 75
    76. 76
    77. 77
    78. 78
    79. 79
    80. 80
    81. 81
    82. 82
    83. 83
    84. 84
    85. 85
    public void ValidateValue( ref object value ) {
                bool b;
                if ( value == null ) return;
                var typeName = BaseType.Name;
                var valueType = value.GetType();
                if ( valueType.Name == "String" ) {
                    if ( BaseType == valueType ) return;
                    if ( BaseType == Constants.Types.Boolean ) {
                        if ( string.Compare( "yes", (string) value, StringComparison.OrdinalIgnoreCase ) == 0 ) value = true;
                        else if ( string.Compare( "no", (string) value, StringComparison.OrdinalIgnoreCase ) == 0 ) value = false;
    #if !CF
                        else if ( Boolean.TryParse( value.ToString(), out b ) ) value = b;
    #else
              else if (TryParseUtility.TryParse(value.ToString(), out b)) value = b;
    #endif
                        else throw new ArgumentException( String.Format( Resources.ValueNotCorrectType, value ) );
                        return;
                    }
                }
    
    #if !CF
                if ( typeName == "Boolean"
                     && Boolean.TryParse( value.ToString(), out b ) ) {
                    value = b;
                    return;
                }
    
                UInt64 uintVal;
                if ( typeName.StartsWith( "UInt64" )
                     && UInt64.TryParse( value.ToString(), out uintVal ) ) {
                    value = uintVal;
                    return;
                }
    
                UInt32 uintVal32;
                if ( typeName.StartsWith( "UInt32" )
                     && UInt32.TryParse( value.ToString(), out uintVal32 ) ) {
                    value = uintVal32;
                    return;
                }
    
                long intVal;
                if ( typeName.StartsWith( "long" )
                     && long.TryParse( value.ToString(), out intVal ) ) {
                    value = intVal;
                    return;
                }
    
                int intVal32;
                if ( typeName.StartsWith( "Int32" )
                     && Int32.TryParse( value.ToString(), out intVal32 ) ) {
                    value = intVal32;
                    return;
                }
    #else
          if (typeName == "Boolean" && TryParseUtility.TryParse(value.ToString(), out b)) { value = b; return; }
    
          UInt64 uintVal;
          if (typeName.StartsWith("UInt64") && TryParseUtility.TryParse(value.ToString(), out uintVal)) { value = uintVal; return; }
    
          UInt32 uintVal32;
          if (typeName.StartsWith("UInt32") && TryParseUtility.TryParse(value.ToString(), out uintVal32)) { value = uintVal32; return; }
    
          long intVal;
          if (typeName.StartsWith("long") && TryParseUtility.TryParse(value.ToString(), out intVal)) { value = intVal; return; }
    
          Int32 intVal32;
          if (typeName.StartsWith("Int32") && TryParseUtility.TryParse(value.ToString(), out intVal32)) { value = intVal32; return; }
    #endif
    
                object objValue;
    #if RT
          Type baseType = BaseType.GetTypeInfo().BaseType;
    #else
                var baseType = BaseType.BaseType;
    #endif
                if ( baseType != null
                     && baseType.Name == "Enum"
                     && ParseEnum( value.ToString(), out objValue ) ) {
                    value = objValue;
                    return;
                }
    
                throw new ArgumentException( String.Format( Resources.ValueNotCorrectType, value ) );
            }

    MySql.Data 6.9.5, MySqlConnectionStringBuilder.cs

    kasthack, 24 Ноября 2014

    Комментарии (1)
  7. C# / Говнокод #17144

    +131

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;
    namespace CA1
    {
        class Program
        {
            static void Main()
            {
                int buffer;
                int Cout = 0;
                string line;
                System.IO.StreamReader file = new System.IO.StreamReader("file.txt");
                while ((line = file.ReadLine()) != null)
                {
                    buffer = Convert.ToInt32(line);
                    if(buffer > 0)
                    {
                        if(buffer / 2 > 5 && buffer / 2 < 49.5)
                        {
                            Cout++;
                        }
                    }
    
                    if (buffer < 0)
                    {
                        if (buffer / 2 < - 5 && buffer / 2 > - 49.5)
                        {
                            Cout++;
                        }
                    }
                }
                Console.WriteLine(Cout);
                Console.ReadLine();
            }
        }
    }

    Вычисление количества цифр в числе

    LightningAtom, 20 Ноября 2014

    Комментарии (138)
  8. C# / Говнокод #17142

    +135

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    public void SelectStep(int stepNumber)
    {
        //1.HTTPCore
        //2.find cat
        //3find p.cat
        //4.find products
        //5.parse products info
        //6.save
        //7.complete
        if (stepNumber != 1) ((Label)(this.panel.Controls.Cast<Control>()
            .First(c => c.TabIndex == stepNumber - 1))).ForeColor = Color.Black;
        ((Label)(this.panel.Controls.Cast<Control>()
            .First(c => c.TabIndex == stepNumber))).ForeColor = Color.Red;
        if (stepNumber == 6)
        {
            labelStatusSecondLine.ForeColor = Color.Black;
            labelStatusFirstLine.Text = "Готово."; buttonStart.Enabled = buttonRefreshCats.Enabled = true; timer.Stop();
        }
        if (stepNumber == 7)
        {
            labelStatusSecondLine.Text = "Обновление категорий...";
        }
    }

    Досталось в наследство. Слегка переписано мной (ранее у всех лейблов были имена вроде "label1" – к лейблам аффтар обращался по распарсенным оттуда цифрам).

    pushistayapodmyshka, 20 Ноября 2014

    Комментарии (17)
  9. C# / Говнокод #17105

    +136

    1. 1
    2. 2
    3. 3
    public override string GetMobileBody() {
    	return System.Text.Encoding.UTF8.GetString(new Terrasoft.Common.CompressionUtilities().UnZip(new byte[] { 31,139,8, /*... over 9000 bytes ...*/,36,59,0,0 }));
    }

    По долгу службы пришлось столкнуться с одной небезызвестной CRM отечественного производства.
    Безумно интересен сакральный смысл такого кода.

    lorond, 13 Ноября 2014

    Комментарии (29)
  10. C# / Говнокод #17089

    +134

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    75. 75
    76. 76
    77. 77
    78. 78
    79. 79
    80. 80
    81. 81
    82. 82
    83. 83
    84. 84
    85. 85
    86. 86
    87. 87
    88. 88
    89. 89
    90. 90
    91. 91
    92. 92
    93. 93
    94. 94
    95. 95
    96. 96
    class ParametersArray
    {
            ...
            /// <summary>
            /// Копирующей конструктор (создает копию коллекции)
            /// </summary>
            /// <param name="prs">Коллекция на основе, которой будет создаваться копия</param>
            public ParametersArray(ParametersArray prs)
            {
                paParameters = new ArrayList();
                for (int i = 0; i < prs.Count; i++)
                {
                    Parameter p = new Parameter(prs[i]);
                    paParameters.Add(p);
                }
            }
            ...
            #region Внутренние состояния
    
            /// <summary>
            /// Внутреннее поле - массив параметров
            /// </summary>
            private ArrayList paParameters;
    
            /// <summary>
            /// Внутреннее поле – идентификатор операции, к которой относятся параметры
            /// </summary>
            private string paOperationId = "";
    
            #endregion
            /// <summary>
            /// Удаляет параметр из коллекции
            /// </summary>
            /// <param name="parameterId">Идентификатор параметра</param>
            public void Delete(string parameterId)
            {
                ArrayList list = new ArrayList();
    
                foreach (Parameter prt in paParameters)
                {
                    if (prt.Id.Trim() != parameterId.Trim())
                    {
                        list.Add(prt);
                    }
                }
                paParameters = list;
            }
        }
    }
    
    ...
    
      /// <summary>
      /// Класс для поиска и обработки шаблонов в параметрах операций
      /// </summary>
      public class Parser
      {
        ...
        #region Конструкторы
    
        /// <summary>
        /// Конструктор инициализирующей класс
        /// </summary>
        /// <param name="requestUserId">ID пользователя, который используется для обработки шаблона ##USER()</param>
        public Parser(string requestUserId)
        {
          pParameters = null;
          pUserId = requestUserId;
        }
    
        #endregion
    
        #region Внешние методы
    
        /// <summary>
        /// Метод перебирает все параметры операции, ищет там шаблоны и заменяет их значениями
        /// </summary>
        /// <param name="opr">Операция</param>
        /// <returns>Операция с обработанными шаблонами</returns>
        public Operation Parse(Operation opr)
        {
          pParameters = new ParametersArray(opr.Parameters);
    
          for (int i = 0; i < pParameters.Count; i++)
            if (FindTemplate(pParameters[i]))
            {
              ReplaceTemplate(pParameters[i]);
    
              //Удаляет параметр с ошибкой
              if (pParameters[i].Value == "parse err")
                pParameters.Delete(pParameters[i].Id);
            }
    
          opr.Parameters = new ParametersArray(pParameters);
          return opr;
        }

    Внимание привлекает код в строках 81-95

    В строке 81-82 мы создаём временную копию параметров операции opr во внутреннем поле класса Parser. Прекрасно. Ещё раз - в публичном в методе инициализируем внутреннее поле (Классный side effect - поле используется в других методах).

    В строке 91 удаляет элемент из внутренней коллекции, пересоздавая коллекцию целиком, то есть требования к памяти временно удваиваются на выходе из метода Delete (до очистки памяти). В методе Delete. Да. Супер.
    потом инициализируем вновь созданной коллекцией публичное поле Parameters во входящем параметре opr метода Delete.

    P.S.: Диагноз - хроническая форма неизлечимой Java. Во первых, автор этих строк искренне думает, что в природе ничего, кроме коллекции ArrayList, не существует. Во вторых, для удаления элемента коллекции мы пересоздаём всю коллекцию целиком, то есть видимо искренне полагая, что коллекция ArrayList - immutable, как и все поля класса Parser (типа ParametersArray) равно как и поле класса ParametersArray (типа ArrayList). Занавес.

    Говнокодище.

    hack2root, 10 Ноября 2014

    Комментарии (7)